ActivityManagerService.java revision a4e102ee580282dc7abeb22f4a025813e53b9431
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    // Holds the current foreground user's id
1111    int mCurrentUserId = 0;
1112    // Holds the target user's id during a user switch
1113    int mTargetUserId = UserHandle.USER_NULL;
1114    // If there are multiple profiles for the current user, their ids are here
1115    // Currently only the primary user can have managed profiles
1116    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1117
1118    /**
1119     * Mapping from each known user ID to the profile group ID it is associated with.
1120     */
1121    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1122
1123    private UserManagerService mUserManager;
1124
1125    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1126        final ProcessRecord mApp;
1127        final int mPid;
1128        final IApplicationThread mAppThread;
1129
1130        AppDeathRecipient(ProcessRecord app, int pid,
1131                IApplicationThread thread) {
1132            if (localLOGV) Slog.v(
1133                TAG, "New death recipient " + this
1134                + " for thread " + thread.asBinder());
1135            mApp = app;
1136            mPid = pid;
1137            mAppThread = thread;
1138        }
1139
1140        @Override
1141        public void binderDied() {
1142            if (localLOGV) Slog.v(
1143                TAG, "Death received in " + this
1144                + " for thread " + mAppThread.asBinder());
1145            synchronized(ActivityManagerService.this) {
1146                appDiedLocked(mApp, mPid, mAppThread);
1147            }
1148        }
1149    }
1150
1151    static final int SHOW_ERROR_MSG = 1;
1152    static final int SHOW_NOT_RESPONDING_MSG = 2;
1153    static final int SHOW_FACTORY_ERROR_MSG = 3;
1154    static final int UPDATE_CONFIGURATION_MSG = 4;
1155    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1156    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1157    static final int SERVICE_TIMEOUT_MSG = 12;
1158    static final int UPDATE_TIME_ZONE = 13;
1159    static final int SHOW_UID_ERROR_MSG = 14;
1160    static final int IM_FEELING_LUCKY_MSG = 15;
1161    static final int PROC_START_TIMEOUT_MSG = 20;
1162    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1163    static final int KILL_APPLICATION_MSG = 22;
1164    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1165    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1166    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1167    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1168    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1169    static final int CLEAR_DNS_CACHE_MSG = 28;
1170    static final int UPDATE_HTTP_PROXY_MSG = 29;
1171    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1172    static final int DISPATCH_PROCESSES_CHANGED = 31;
1173    static final int DISPATCH_PROCESS_DIED = 32;
1174    static final int REPORT_MEM_USAGE_MSG = 33;
1175    static final int REPORT_USER_SWITCH_MSG = 34;
1176    static final int CONTINUE_USER_SWITCH_MSG = 35;
1177    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1178    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1179    static final int PERSIST_URI_GRANTS_MSG = 38;
1180    static final int REQUEST_ALL_PSS_MSG = 39;
1181    static final int START_PROFILES_MSG = 40;
1182    static final int UPDATE_TIME = 41;
1183    static final int SYSTEM_USER_START_MSG = 42;
1184    static final int SYSTEM_USER_CURRENT_MSG = 43;
1185    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1186    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1187    static final int START_USER_SWITCH_MSG = 46;
1188
1189    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1190    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1191    static final int FIRST_COMPAT_MODE_MSG = 300;
1192    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1193
1194    AlertDialog mUidAlert;
1195    CompatModeDialog mCompatModeDialog;
1196    long mLastMemUsageReportTime = 0;
1197
1198    private LockToAppRequestDialog mLockToAppRequest;
1199
1200    /**
1201     * Flag whether the current user is a "monkey", i.e. whether
1202     * the UI is driven by a UI automation tool.
1203     */
1204    private boolean mUserIsMonkey;
1205
1206    /** Flag whether the device has a Recents UI */
1207    boolean mHasRecents;
1208
1209    /** The dimensions of the thumbnails in the Recents UI. */
1210    int mThumbnailWidth;
1211    int mThumbnailHeight;
1212
1213    final ServiceThread mHandlerThread;
1214    final MainHandler mHandler;
1215
1216    final class MainHandler extends Handler {
1217        public MainHandler(Looper looper) {
1218            super(looper, null, true);
1219        }
1220
1221        @Override
1222        public void handleMessage(Message msg) {
1223            switch (msg.what) {
1224            case SHOW_ERROR_MSG: {
1225                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1226                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1227                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1228                synchronized (ActivityManagerService.this) {
1229                    ProcessRecord proc = (ProcessRecord)data.get("app");
1230                    AppErrorResult res = (AppErrorResult) data.get("result");
1231                    if (proc != null && proc.crashDialog != null) {
1232                        Slog.e(TAG, "App already has crash dialog: " + proc);
1233                        if (res != null) {
1234                            res.set(0);
1235                        }
1236                        return;
1237                    }
1238                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1239                            >= Process.FIRST_APPLICATION_UID
1240                            && proc.pid != MY_PID);
1241                    for (int userId : mCurrentProfileIds) {
1242                        isBackground &= (proc.userId != userId);
1243                    }
1244                    if (isBackground && !showBackground) {
1245                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1246                        if (res != null) {
1247                            res.set(0);
1248                        }
1249                        return;
1250                    }
1251                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1252                        Dialog d = new AppErrorDialog(mContext,
1253                                ActivityManagerService.this, res, proc);
1254                        d.show();
1255                        proc.crashDialog = d;
1256                    } else {
1257                        // The device is asleep, so just pretend that the user
1258                        // saw a crash dialog and hit "force quit".
1259                        if (res != null) {
1260                            res.set(0);
1261                        }
1262                    }
1263                }
1264
1265                ensureBootCompleted();
1266            } break;
1267            case SHOW_NOT_RESPONDING_MSG: {
1268                synchronized (ActivityManagerService.this) {
1269                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1270                    ProcessRecord proc = (ProcessRecord)data.get("app");
1271                    if (proc != null && proc.anrDialog != null) {
1272                        Slog.e(TAG, "App already has anr dialog: " + proc);
1273                        return;
1274                    }
1275
1276                    Intent intent = new Intent("android.intent.action.ANR");
1277                    if (!mProcessesReady) {
1278                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1279                                | Intent.FLAG_RECEIVER_FOREGROUND);
1280                    }
1281                    broadcastIntentLocked(null, null, intent,
1282                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1283                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1284
1285                    if (mShowDialogs) {
1286                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1287                                mContext, proc, (ActivityRecord)data.get("activity"),
1288                                msg.arg1 != 0);
1289                        d.show();
1290                        proc.anrDialog = d;
1291                    } else {
1292                        // Just kill the app if there is no dialog to be shown.
1293                        killAppAtUsersRequest(proc, null);
1294                    }
1295                }
1296
1297                ensureBootCompleted();
1298            } break;
1299            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1300                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1301                synchronized (ActivityManagerService.this) {
1302                    ProcessRecord proc = (ProcessRecord) data.get("app");
1303                    if (proc == null) {
1304                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1305                        break;
1306                    }
1307                    if (proc.crashDialog != null) {
1308                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1309                        return;
1310                    }
1311                    AppErrorResult res = (AppErrorResult) data.get("result");
1312                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1313                        Dialog d = new StrictModeViolationDialog(mContext,
1314                                ActivityManagerService.this, res, proc);
1315                        d.show();
1316                        proc.crashDialog = d;
1317                    } else {
1318                        // The device is asleep, so just pretend that the user
1319                        // saw a crash dialog and hit "force quit".
1320                        res.set(0);
1321                    }
1322                }
1323                ensureBootCompleted();
1324            } break;
1325            case SHOW_FACTORY_ERROR_MSG: {
1326                Dialog d = new FactoryErrorDialog(
1327                    mContext, msg.getData().getCharSequence("msg"));
1328                d.show();
1329                ensureBootCompleted();
1330            } break;
1331            case UPDATE_CONFIGURATION_MSG: {
1332                final ContentResolver resolver = mContext.getContentResolver();
1333                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1334            } break;
1335            case GC_BACKGROUND_PROCESSES_MSG: {
1336                synchronized (ActivityManagerService.this) {
1337                    performAppGcsIfAppropriateLocked();
1338                }
1339            } break;
1340            case WAIT_FOR_DEBUGGER_MSG: {
1341                synchronized (ActivityManagerService.this) {
1342                    ProcessRecord app = (ProcessRecord)msg.obj;
1343                    if (msg.arg1 != 0) {
1344                        if (!app.waitedForDebugger) {
1345                            Dialog d = new AppWaitingForDebuggerDialog(
1346                                    ActivityManagerService.this,
1347                                    mContext, app);
1348                            app.waitDialog = d;
1349                            app.waitedForDebugger = true;
1350                            d.show();
1351                        }
1352                    } else {
1353                        if (app.waitDialog != null) {
1354                            app.waitDialog.dismiss();
1355                            app.waitDialog = null;
1356                        }
1357                    }
1358                }
1359            } break;
1360            case SERVICE_TIMEOUT_MSG: {
1361                if (mDidDexOpt) {
1362                    mDidDexOpt = false;
1363                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1364                    nmsg.obj = msg.obj;
1365                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1366                    return;
1367                }
1368                mServices.serviceTimeout((ProcessRecord)msg.obj);
1369            } break;
1370            case UPDATE_TIME_ZONE: {
1371                synchronized (ActivityManagerService.this) {
1372                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1373                        ProcessRecord r = mLruProcesses.get(i);
1374                        if (r.thread != null) {
1375                            try {
1376                                r.thread.updateTimeZone();
1377                            } catch (RemoteException ex) {
1378                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1379                            }
1380                        }
1381                    }
1382                }
1383            } break;
1384            case CLEAR_DNS_CACHE_MSG: {
1385                synchronized (ActivityManagerService.this) {
1386                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1387                        ProcessRecord r = mLruProcesses.get(i);
1388                        if (r.thread != null) {
1389                            try {
1390                                r.thread.clearDnsCache();
1391                            } catch (RemoteException ex) {
1392                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1393                            }
1394                        }
1395                    }
1396                }
1397            } break;
1398            case UPDATE_HTTP_PROXY_MSG: {
1399                ProxyInfo proxy = (ProxyInfo)msg.obj;
1400                String host = "";
1401                String port = "";
1402                String exclList = "";
1403                Uri pacFileUrl = Uri.EMPTY;
1404                if (proxy != null) {
1405                    host = proxy.getHost();
1406                    port = Integer.toString(proxy.getPort());
1407                    exclList = proxy.getExclusionListAsString();
1408                    pacFileUrl = proxy.getPacFileUrl();
1409                }
1410                synchronized (ActivityManagerService.this) {
1411                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1412                        ProcessRecord r = mLruProcesses.get(i);
1413                        if (r.thread != null) {
1414                            try {
1415                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1416                            } catch (RemoteException ex) {
1417                                Slog.w(TAG, "Failed to update http proxy for: " +
1418                                        r.info.processName);
1419                            }
1420                        }
1421                    }
1422                }
1423            } break;
1424            case SHOW_UID_ERROR_MSG: {
1425                String title = "System UIDs Inconsistent";
1426                String text = "UIDs on the system are inconsistent, you need to wipe your"
1427                        + " data partition or your device will be unstable.";
1428                Log.e(TAG, title + ": " + text);
1429                if (mShowDialogs) {
1430                    // XXX This is a temporary dialog, no need to localize.
1431                    AlertDialog d = new BaseErrorDialog(mContext);
1432                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1433                    d.setCancelable(false);
1434                    d.setTitle(title);
1435                    d.setMessage(text);
1436                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1437                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1438                    mUidAlert = d;
1439                    d.show();
1440                }
1441            } break;
1442            case IM_FEELING_LUCKY_MSG: {
1443                if (mUidAlert != null) {
1444                    mUidAlert.dismiss();
1445                    mUidAlert = null;
1446                }
1447            } break;
1448            case PROC_START_TIMEOUT_MSG: {
1449                if (mDidDexOpt) {
1450                    mDidDexOpt = false;
1451                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1452                    nmsg.obj = msg.obj;
1453                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1454                    return;
1455                }
1456                ProcessRecord app = (ProcessRecord)msg.obj;
1457                synchronized (ActivityManagerService.this) {
1458                    processStartTimedOutLocked(app);
1459                }
1460            } break;
1461            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1462                synchronized (ActivityManagerService.this) {
1463                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1464                }
1465            } break;
1466            case KILL_APPLICATION_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    int appid = msg.arg1;
1469                    boolean restart = (msg.arg2 == 1);
1470                    Bundle bundle = (Bundle)msg.obj;
1471                    String pkg = bundle.getString("pkg");
1472                    String reason = bundle.getString("reason");
1473                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1474                            false, UserHandle.USER_ALL, reason);
1475                }
1476            } break;
1477            case FINALIZE_PENDING_INTENT_MSG: {
1478                ((PendingIntentRecord)msg.obj).completeFinalize();
1479            } break;
1480            case POST_HEAVY_NOTIFICATION_MSG: {
1481                INotificationManager inm = NotificationManager.getService();
1482                if (inm == null) {
1483                    return;
1484                }
1485
1486                ActivityRecord root = (ActivityRecord)msg.obj;
1487                ProcessRecord process = root.app;
1488                if (process == null) {
1489                    return;
1490                }
1491
1492                try {
1493                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1494                    String text = mContext.getString(R.string.heavy_weight_notification,
1495                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1496                    Notification notification = new Notification();
1497                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1498                    notification.when = 0;
1499                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1500                    notification.tickerText = text;
1501                    notification.defaults = 0; // please be quiet
1502                    notification.sound = null;
1503                    notification.vibrate = null;
1504                    notification.color = mContext.getResources().getColor(
1505                            com.android.internal.R.color.system_notification_accent_color);
1506                    notification.setLatestEventInfo(context, text,
1507                            mContext.getText(R.string.heavy_weight_notification_detail),
1508                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1509                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1510                                    new UserHandle(root.userId)));
1511
1512                    try {
1513                        int[] outId = new int[1];
1514                        inm.enqueueNotificationWithTag("android", "android", null,
1515                                R.string.heavy_weight_notification,
1516                                notification, outId, root.userId);
1517                    } catch (RuntimeException e) {
1518                        Slog.w(ActivityManagerService.TAG,
1519                                "Error showing notification for heavy-weight app", e);
1520                    } catch (RemoteException e) {
1521                    }
1522                } catch (NameNotFoundException e) {
1523                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1524                }
1525            } break;
1526            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1527                INotificationManager inm = NotificationManager.getService();
1528                if (inm == null) {
1529                    return;
1530                }
1531                try {
1532                    inm.cancelNotificationWithTag("android", null,
1533                            R.string.heavy_weight_notification,  msg.arg1);
1534                } catch (RuntimeException e) {
1535                    Slog.w(ActivityManagerService.TAG,
1536                            "Error canceling notification for service", e);
1537                } catch (RemoteException e) {
1538                }
1539            } break;
1540            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1541                synchronized (ActivityManagerService.this) {
1542                    checkExcessivePowerUsageLocked(true);
1543                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1544                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1545                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1546                }
1547            } break;
1548            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1549                synchronized (ActivityManagerService.this) {
1550                    ActivityRecord ar = (ActivityRecord)msg.obj;
1551                    if (mCompatModeDialog != null) {
1552                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1553                                ar.info.applicationInfo.packageName)) {
1554                            return;
1555                        }
1556                        mCompatModeDialog.dismiss();
1557                        mCompatModeDialog = null;
1558                    }
1559                    if (ar != null && false) {
1560                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1561                                ar.packageName)) {
1562                            int mode = mCompatModePackages.computeCompatModeLocked(
1563                                    ar.info.applicationInfo);
1564                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1565                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1566                                mCompatModeDialog = new CompatModeDialog(
1567                                        ActivityManagerService.this, mContext,
1568                                        ar.info.applicationInfo);
1569                                mCompatModeDialog.show();
1570                            }
1571                        }
1572                    }
1573                }
1574                break;
1575            }
1576            case DISPATCH_PROCESSES_CHANGED: {
1577                dispatchProcessesChanged();
1578                break;
1579            }
1580            case DISPATCH_PROCESS_DIED: {
1581                final int pid = msg.arg1;
1582                final int uid = msg.arg2;
1583                dispatchProcessDied(pid, uid);
1584                break;
1585            }
1586            case REPORT_MEM_USAGE_MSG: {
1587                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1588                Thread thread = new Thread() {
1589                    @Override public void run() {
1590                        final SparseArray<ProcessMemInfo> infoMap
1591                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1592                        for (int i=0, N=memInfos.size(); i<N; i++) {
1593                            ProcessMemInfo mi = memInfos.get(i);
1594                            infoMap.put(mi.pid, mi);
1595                        }
1596                        updateCpuStatsNow();
1597                        synchronized (mProcessCpuThread) {
1598                            final int N = mProcessCpuTracker.countStats();
1599                            for (int i=0; i<N; i++) {
1600                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1601                                if (st.vsize > 0) {
1602                                    long pss = Debug.getPss(st.pid, null);
1603                                    if (pss > 0) {
1604                                        if (infoMap.indexOfKey(st.pid) < 0) {
1605                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1606                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1607                                            mi.pss = pss;
1608                                            memInfos.add(mi);
1609                                        }
1610                                    }
1611                                }
1612                            }
1613                        }
1614
1615                        long totalPss = 0;
1616                        for (int i=0, N=memInfos.size(); i<N; i++) {
1617                            ProcessMemInfo mi = memInfos.get(i);
1618                            if (mi.pss == 0) {
1619                                mi.pss = Debug.getPss(mi.pid, null);
1620                            }
1621                            totalPss += mi.pss;
1622                        }
1623                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1624                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1625                                if (lhs.oomAdj != rhs.oomAdj) {
1626                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1627                                }
1628                                if (lhs.pss != rhs.pss) {
1629                                    return lhs.pss < rhs.pss ? 1 : -1;
1630                                }
1631                                return 0;
1632                            }
1633                        });
1634
1635                        StringBuilder tag = new StringBuilder(128);
1636                        StringBuilder stack = new StringBuilder(128);
1637                        tag.append("Low on memory -- ");
1638                        appendMemBucket(tag, totalPss, "total", false);
1639                        appendMemBucket(stack, totalPss, "total", true);
1640
1641                        StringBuilder logBuilder = new StringBuilder(1024);
1642                        logBuilder.append("Low on memory:\n");
1643
1644                        boolean firstLine = true;
1645                        int lastOomAdj = Integer.MIN_VALUE;
1646                        for (int i=0, N=memInfos.size(); i<N; i++) {
1647                            ProcessMemInfo mi = memInfos.get(i);
1648
1649                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1650                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1651                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1652                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1653                                if (lastOomAdj != mi.oomAdj) {
1654                                    lastOomAdj = mi.oomAdj;
1655                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1656                                        tag.append(" / ");
1657                                    }
1658                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1659                                        if (firstLine) {
1660                                            stack.append(":");
1661                                            firstLine = false;
1662                                        }
1663                                        stack.append("\n\t at ");
1664                                    } else {
1665                                        stack.append("$");
1666                                    }
1667                                } else {
1668                                    tag.append(" ");
1669                                    stack.append("$");
1670                                }
1671                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1672                                    appendMemBucket(tag, mi.pss, mi.name, false);
1673                                }
1674                                appendMemBucket(stack, mi.pss, mi.name, true);
1675                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1676                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1677                                    stack.append("(");
1678                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1679                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1680                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1681                                            stack.append(":");
1682                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1683                                        }
1684                                    }
1685                                    stack.append(")");
1686                                }
1687                            }
1688
1689                            logBuilder.append("  ");
1690                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1691                            logBuilder.append(' ');
1692                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1693                            logBuilder.append(' ');
1694                            ProcessList.appendRamKb(logBuilder, mi.pss);
1695                            logBuilder.append(" kB: ");
1696                            logBuilder.append(mi.name);
1697                            logBuilder.append(" (");
1698                            logBuilder.append(mi.pid);
1699                            logBuilder.append(") ");
1700                            logBuilder.append(mi.adjType);
1701                            logBuilder.append('\n');
1702                            if (mi.adjReason != null) {
1703                                logBuilder.append("                      ");
1704                                logBuilder.append(mi.adjReason);
1705                                logBuilder.append('\n');
1706                            }
1707                        }
1708
1709                        logBuilder.append("           ");
1710                        ProcessList.appendRamKb(logBuilder, totalPss);
1711                        logBuilder.append(" kB: TOTAL\n");
1712
1713                        long[] infos = new long[Debug.MEMINFO_COUNT];
1714                        Debug.getMemInfo(infos);
1715                        logBuilder.append("  MemInfo: ");
1716                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1717                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1718                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1719                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1720                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1721                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1722                            logBuilder.append("  ZRAM: ");
1723                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1724                            logBuilder.append(" kB RAM, ");
1725                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1726                            logBuilder.append(" kB swap total, ");
1727                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1728                            logBuilder.append(" kB swap free\n");
1729                        }
1730                        Slog.i(TAG, logBuilder.toString());
1731
1732                        StringBuilder dropBuilder = new StringBuilder(1024);
1733                        /*
1734                        StringWriter oomSw = new StringWriter();
1735                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1736                        StringWriter catSw = new StringWriter();
1737                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1738                        String[] emptyArgs = new String[] { };
1739                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1740                        oomPw.flush();
1741                        String oomString = oomSw.toString();
1742                        */
1743                        dropBuilder.append(stack);
1744                        dropBuilder.append('\n');
1745                        dropBuilder.append('\n');
1746                        dropBuilder.append(logBuilder);
1747                        dropBuilder.append('\n');
1748                        /*
1749                        dropBuilder.append(oomString);
1750                        dropBuilder.append('\n');
1751                        */
1752                        StringWriter catSw = new StringWriter();
1753                        synchronized (ActivityManagerService.this) {
1754                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1755                            String[] emptyArgs = new String[] { };
1756                            catPw.println();
1757                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1758                            catPw.println();
1759                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1760                                    false, false, null);
1761                            catPw.println();
1762                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1763                            catPw.flush();
1764                        }
1765                        dropBuilder.append(catSw.toString());
1766                        addErrorToDropBox("lowmem", null, "system_server", null,
1767                                null, tag.toString(), dropBuilder.toString(), null, null);
1768                        //Slog.i(TAG, "Sent to dropbox:");
1769                        //Slog.i(TAG, dropBuilder.toString());
1770                        synchronized (ActivityManagerService.this) {
1771                            long now = SystemClock.uptimeMillis();
1772                            if (mLastMemUsageReportTime < now) {
1773                                mLastMemUsageReportTime = now;
1774                            }
1775                        }
1776                    }
1777                };
1778                thread.start();
1779                break;
1780            }
1781            case START_USER_SWITCH_MSG: {
1782                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1783                break;
1784            }
1785            case REPORT_USER_SWITCH_MSG: {
1786                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1787                break;
1788            }
1789            case CONTINUE_USER_SWITCH_MSG: {
1790                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1791                break;
1792            }
1793            case USER_SWITCH_TIMEOUT_MSG: {
1794                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1795                break;
1796            }
1797            case IMMERSIVE_MODE_LOCK_MSG: {
1798                final boolean nextState = (msg.arg1 != 0);
1799                if (mUpdateLock.isHeld() != nextState) {
1800                    if (DEBUG_IMMERSIVE) {
1801                        final ActivityRecord r = (ActivityRecord) msg.obj;
1802                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1803                    }
1804                    if (nextState) {
1805                        mUpdateLock.acquire();
1806                    } else {
1807                        mUpdateLock.release();
1808                    }
1809                }
1810                break;
1811            }
1812            case PERSIST_URI_GRANTS_MSG: {
1813                writeGrantedUriPermissions();
1814                break;
1815            }
1816            case REQUEST_ALL_PSS_MSG: {
1817                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1818                break;
1819            }
1820            case START_PROFILES_MSG: {
1821                synchronized (ActivityManagerService.this) {
1822                    startProfilesLocked();
1823                }
1824                break;
1825            }
1826            case UPDATE_TIME: {
1827                synchronized (ActivityManagerService.this) {
1828                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1829                        ProcessRecord r = mLruProcesses.get(i);
1830                        if (r.thread != null) {
1831                            try {
1832                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1833                            } catch (RemoteException ex) {
1834                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1835                            }
1836                        }
1837                    }
1838                }
1839                break;
1840            }
1841            case SYSTEM_USER_START_MSG: {
1842                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1843                        Integer.toString(msg.arg1), msg.arg1);
1844                mSystemServiceManager.startUser(msg.arg1);
1845                break;
1846            }
1847            case SYSTEM_USER_CURRENT_MSG: {
1848                mBatteryStatsService.noteEvent(
1849                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1850                        Integer.toString(msg.arg2), msg.arg2);
1851                mBatteryStatsService.noteEvent(
1852                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1853                        Integer.toString(msg.arg1), msg.arg1);
1854                mSystemServiceManager.switchUser(msg.arg1);
1855                mLockToAppRequest.clearPrompt();
1856                break;
1857            }
1858            case ENTER_ANIMATION_COMPLETE_MSG: {
1859                synchronized (ActivityManagerService.this) {
1860                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1861                    if (r != null && r.app != null && r.app.thread != null) {
1862                        try {
1863                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1864                        } catch (RemoteException e) {
1865                        }
1866                    }
1867                }
1868                break;
1869            }
1870            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1871                enableScreenAfterBoot();
1872                break;
1873            }
1874            }
1875        }
1876    };
1877
1878    static final int COLLECT_PSS_BG_MSG = 1;
1879
1880    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1881        @Override
1882        public void handleMessage(Message msg) {
1883            switch (msg.what) {
1884            case COLLECT_PSS_BG_MSG: {
1885                long start = SystemClock.uptimeMillis();
1886                MemInfoReader memInfo = null;
1887                synchronized (ActivityManagerService.this) {
1888                    if (mFullPssPending) {
1889                        mFullPssPending = false;
1890                        memInfo = new MemInfoReader();
1891                    }
1892                }
1893                if (memInfo != null) {
1894                    updateCpuStatsNow();
1895                    long nativeTotalPss = 0;
1896                    synchronized (mProcessCpuThread) {
1897                        final int N = mProcessCpuTracker.countStats();
1898                        for (int j=0; j<N; j++) {
1899                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1900                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1901                                // This is definitely an application process; skip it.
1902                                continue;
1903                            }
1904                            synchronized (mPidsSelfLocked) {
1905                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1906                                    // This is one of our own processes; skip it.
1907                                    continue;
1908                                }
1909                            }
1910                            nativeTotalPss += Debug.getPss(st.pid, null);
1911                        }
1912                    }
1913                    memInfo.readMemInfo();
1914                    synchronized (this) {
1915                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1916                                + (SystemClock.uptimeMillis()-start) + "ms");
1917                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1918                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1919                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1920                                        +memInfo.getSlabSizeKb(),
1921                                nativeTotalPss);
1922                    }
1923                }
1924
1925                int i=0, num=0;
1926                long[] tmp = new long[1];
1927                do {
1928                    ProcessRecord proc;
1929                    int procState;
1930                    int pid;
1931                    synchronized (ActivityManagerService.this) {
1932                        if (i >= mPendingPssProcesses.size()) {
1933                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1934                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1935                            mPendingPssProcesses.clear();
1936                            return;
1937                        }
1938                        proc = mPendingPssProcesses.get(i);
1939                        procState = proc.pssProcState;
1940                        if (proc.thread != null && procState == proc.setProcState) {
1941                            pid = proc.pid;
1942                        } else {
1943                            proc = null;
1944                            pid = 0;
1945                        }
1946                        i++;
1947                    }
1948                    if (proc != null) {
1949                        long pss = Debug.getPss(pid, tmp);
1950                        synchronized (ActivityManagerService.this) {
1951                            if (proc.thread != null && proc.setProcState == procState
1952                                    && proc.pid == pid) {
1953                                num++;
1954                                proc.lastPssTime = SystemClock.uptimeMillis();
1955                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1956                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1957                                        + ": " + pss + " lastPss=" + proc.lastPss
1958                                        + " state=" + ProcessList.makeProcStateString(procState));
1959                                if (proc.initialIdlePss == 0) {
1960                                    proc.initialIdlePss = pss;
1961                                }
1962                                proc.lastPss = pss;
1963                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1964                                    proc.lastCachedPss = pss;
1965                                }
1966                            }
1967                        }
1968                    }
1969                } while (true);
1970            }
1971            }
1972        }
1973    };
1974
1975    /**
1976     * Monitor for package changes and update our internal state.
1977     */
1978    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1979        @Override
1980        public void onPackageRemoved(String packageName, int uid) {
1981            // Remove all tasks with activities in the specified package from the list of recent tasks
1982            synchronized (ActivityManagerService.this) {
1983                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1984                    TaskRecord tr = mRecentTasks.get(i);
1985                    ComponentName cn = tr.intent.getComponent();
1986                    if (cn != null && cn.getPackageName().equals(packageName)) {
1987                        // If the package name matches, remove the task and kill the process
1988                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1989                    }
1990                }
1991            }
1992        }
1993
1994        @Override
1995        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1996            onPackageModified(packageName);
1997            return true;
1998        }
1999
2000        @Override
2001        public void onPackageModified(String packageName) {
2002            final PackageManager pm = mContext.getPackageManager();
2003            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2004                    new ArrayList<Pair<Intent, Integer>>();
2005            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2006            // Copy the list of recent tasks so that we don't hold onto the lock on
2007            // ActivityManagerService for long periods while checking if components exist.
2008            synchronized (ActivityManagerService.this) {
2009                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2010                    TaskRecord tr = mRecentTasks.get(i);
2011                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2012                }
2013            }
2014            // Check the recent tasks and filter out all tasks with components that no longer exist.
2015            Intent tmpI = new Intent();
2016            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2017                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2018                ComponentName cn = p.first.getComponent();
2019                if (cn != null && cn.getPackageName().equals(packageName)) {
2020                    try {
2021                        // Add the task to the list to remove if the component no longer exists
2022                        tmpI.setComponent(cn);
2023                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2024                            tasksToRemove.add(p.second);
2025                        }
2026                    } catch (Exception e) {}
2027                }
2028            }
2029            // Prune all the tasks with removed components from the list of recent tasks
2030            synchronized (ActivityManagerService.this) {
2031                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2032                    // Remove the task but don't kill the process (since other components in that
2033                    // package may still be running and in the background)
2034                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2035                }
2036            }
2037        }
2038
2039        @Override
2040        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2041            // Force stop the specified packages
2042            if (packages != null) {
2043                for (String pkg : packages) {
2044                    synchronized (ActivityManagerService.this) {
2045                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2046                                "finished booting")) {
2047                            return true;
2048                        }
2049                    }
2050                }
2051            }
2052            return false;
2053        }
2054    };
2055
2056    public void setSystemProcess() {
2057        try {
2058            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2059            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2060            ServiceManager.addService("meminfo", new MemBinder(this));
2061            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2062            ServiceManager.addService("dbinfo", new DbBinder(this));
2063            if (MONITOR_CPU_USAGE) {
2064                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2065            }
2066            ServiceManager.addService("permission", new PermissionController(this));
2067
2068            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2069                    "android", STOCK_PM_FLAGS);
2070            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2071
2072            synchronized (this) {
2073                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2074                app.persistent = true;
2075                app.pid = MY_PID;
2076                app.maxAdj = ProcessList.SYSTEM_ADJ;
2077                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2078                mProcessNames.put(app.processName, app.uid, app);
2079                synchronized (mPidsSelfLocked) {
2080                    mPidsSelfLocked.put(app.pid, app);
2081                }
2082                updateLruProcessLocked(app, false, null);
2083                updateOomAdjLocked();
2084            }
2085        } catch (PackageManager.NameNotFoundException e) {
2086            throw new RuntimeException(
2087                    "Unable to find android system package", e);
2088        }
2089    }
2090
2091    public void setWindowManager(WindowManagerService wm) {
2092        mWindowManager = wm;
2093        mStackSupervisor.setWindowManager(wm);
2094    }
2095
2096    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2097        mUsageStatsService = usageStatsManager;
2098    }
2099
2100    public void startObservingNativeCrashes() {
2101        final NativeCrashListener ncl = new NativeCrashListener(this);
2102        ncl.start();
2103    }
2104
2105    public IAppOpsService getAppOpsService() {
2106        return mAppOpsService;
2107    }
2108
2109    static class MemBinder extends Binder {
2110        ActivityManagerService mActivityManagerService;
2111        MemBinder(ActivityManagerService activityManagerService) {
2112            mActivityManagerService = activityManagerService;
2113        }
2114
2115        @Override
2116        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2117            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2118                    != PackageManager.PERMISSION_GRANTED) {
2119                pw.println("Permission Denial: can't dump meminfo from from pid="
2120                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2121                        + " without permission " + android.Manifest.permission.DUMP);
2122                return;
2123            }
2124
2125            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2126        }
2127    }
2128
2129    static class GraphicsBinder extends Binder {
2130        ActivityManagerService mActivityManagerService;
2131        GraphicsBinder(ActivityManagerService activityManagerService) {
2132            mActivityManagerService = activityManagerService;
2133        }
2134
2135        @Override
2136        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2137            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2138                    != PackageManager.PERMISSION_GRANTED) {
2139                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2140                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2141                        + " without permission " + android.Manifest.permission.DUMP);
2142                return;
2143            }
2144
2145            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2146        }
2147    }
2148
2149    static class DbBinder extends Binder {
2150        ActivityManagerService mActivityManagerService;
2151        DbBinder(ActivityManagerService activityManagerService) {
2152            mActivityManagerService = activityManagerService;
2153        }
2154
2155        @Override
2156        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2157            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2158                    != PackageManager.PERMISSION_GRANTED) {
2159                pw.println("Permission Denial: can't dump dbinfo from from pid="
2160                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2161                        + " without permission " + android.Manifest.permission.DUMP);
2162                return;
2163            }
2164
2165            mActivityManagerService.dumpDbInfo(fd, pw, args);
2166        }
2167    }
2168
2169    static class CpuBinder extends Binder {
2170        ActivityManagerService mActivityManagerService;
2171        CpuBinder(ActivityManagerService activityManagerService) {
2172            mActivityManagerService = activityManagerService;
2173        }
2174
2175        @Override
2176        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2177            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2178                    != PackageManager.PERMISSION_GRANTED) {
2179                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2180                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2181                        + " without permission " + android.Manifest.permission.DUMP);
2182                return;
2183            }
2184
2185            synchronized (mActivityManagerService.mProcessCpuThread) {
2186                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2187                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2188                        SystemClock.uptimeMillis()));
2189            }
2190        }
2191    }
2192
2193    public static final class Lifecycle extends SystemService {
2194        private final ActivityManagerService mService;
2195
2196        public Lifecycle(Context context) {
2197            super(context);
2198            mService = new ActivityManagerService(context);
2199        }
2200
2201        @Override
2202        public void onStart() {
2203            mService.start();
2204        }
2205
2206        public ActivityManagerService getService() {
2207            return mService;
2208        }
2209    }
2210
2211    // Note: This method is invoked on the main thread but may need to attach various
2212    // handlers to other threads.  So take care to be explicit about the looper.
2213    public ActivityManagerService(Context systemContext) {
2214        mContext = systemContext;
2215        mFactoryTest = FactoryTest.getMode();
2216        mSystemThread = ActivityThread.currentActivityThread();
2217
2218        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2219
2220        mHandlerThread = new ServiceThread(TAG,
2221                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2222        mHandlerThread.start();
2223        mHandler = new MainHandler(mHandlerThread.getLooper());
2224
2225        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2226                "foreground", BROADCAST_FG_TIMEOUT, false);
2227        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2228                "background", BROADCAST_BG_TIMEOUT, true);
2229        mBroadcastQueues[0] = mFgBroadcastQueue;
2230        mBroadcastQueues[1] = mBgBroadcastQueue;
2231
2232        mServices = new ActiveServices(this);
2233        mProviderMap = new ProviderMap(this);
2234
2235        // TODO: Move creation of battery stats service outside of activity manager service.
2236        File dataDir = Environment.getDataDirectory();
2237        File systemDir = new File(dataDir, "system");
2238        systemDir.mkdirs();
2239        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2240        mBatteryStatsService.getActiveStatistics().readLocked();
2241        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2242        mOnBattery = DEBUG_POWER ? true
2243                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2244        mBatteryStatsService.getActiveStatistics().setCallback(this);
2245
2246        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2247
2248        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2249
2250        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2251
2252        // User 0 is the first and only user that runs at boot.
2253        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2254        mUserLru.add(Integer.valueOf(0));
2255        updateStartedUserArrayLocked();
2256
2257        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2258            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2259
2260        mConfiguration.setToDefaults();
2261        mConfiguration.setLocale(Locale.getDefault());
2262
2263        mConfigurationSeq = mConfiguration.seq = 1;
2264        mProcessCpuTracker.init();
2265
2266        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2267        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2268        mStackSupervisor = new ActivityStackSupervisor(this);
2269        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2270
2271        mProcessCpuThread = new Thread("CpuTracker") {
2272            @Override
2273            public void run() {
2274                while (true) {
2275                    try {
2276                        try {
2277                            synchronized(this) {
2278                                final long now = SystemClock.uptimeMillis();
2279                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2280                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2281                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2282                                //        + ", write delay=" + nextWriteDelay);
2283                                if (nextWriteDelay < nextCpuDelay) {
2284                                    nextCpuDelay = nextWriteDelay;
2285                                }
2286                                if (nextCpuDelay > 0) {
2287                                    mProcessCpuMutexFree.set(true);
2288                                    this.wait(nextCpuDelay);
2289                                }
2290                            }
2291                        } catch (InterruptedException e) {
2292                        }
2293                        updateCpuStatsNow();
2294                    } catch (Exception e) {
2295                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2296                    }
2297                }
2298            }
2299        };
2300
2301        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2302
2303        Watchdog.getInstance().addMonitor(this);
2304        Watchdog.getInstance().addThread(mHandler);
2305    }
2306
2307    public void setSystemServiceManager(SystemServiceManager mgr) {
2308        mSystemServiceManager = mgr;
2309    }
2310
2311    private void start() {
2312        Process.removeAllProcessGroups();
2313        mProcessCpuThread.start();
2314
2315        mBatteryStatsService.publish(mContext);
2316        mAppOpsService.publish(mContext);
2317        Slog.d("AppOps", "AppOpsService published");
2318        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2319    }
2320
2321    public void initPowerManagement() {
2322        mStackSupervisor.initPowerManagement();
2323        mBatteryStatsService.initPowerManagement();
2324    }
2325
2326    @Override
2327    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2328            throws RemoteException {
2329        if (code == SYSPROPS_TRANSACTION) {
2330            // We need to tell all apps about the system property change.
2331            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2332            synchronized(this) {
2333                final int NP = mProcessNames.getMap().size();
2334                for (int ip=0; ip<NP; ip++) {
2335                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2336                    final int NA = apps.size();
2337                    for (int ia=0; ia<NA; ia++) {
2338                        ProcessRecord app = apps.valueAt(ia);
2339                        if (app.thread != null) {
2340                            procs.add(app.thread.asBinder());
2341                        }
2342                    }
2343                }
2344            }
2345
2346            int N = procs.size();
2347            for (int i=0; i<N; i++) {
2348                Parcel data2 = Parcel.obtain();
2349                try {
2350                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2351                } catch (RemoteException e) {
2352                }
2353                data2.recycle();
2354            }
2355        }
2356        try {
2357            return super.onTransact(code, data, reply, flags);
2358        } catch (RuntimeException e) {
2359            // The activity manager only throws security exceptions, so let's
2360            // log all others.
2361            if (!(e instanceof SecurityException)) {
2362                Slog.wtf(TAG, "Activity Manager Crash", e);
2363            }
2364            throw e;
2365        }
2366    }
2367
2368    void updateCpuStats() {
2369        final long now = SystemClock.uptimeMillis();
2370        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2371            return;
2372        }
2373        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2374            synchronized (mProcessCpuThread) {
2375                mProcessCpuThread.notify();
2376            }
2377        }
2378    }
2379
2380    void updateCpuStatsNow() {
2381        synchronized (mProcessCpuThread) {
2382            mProcessCpuMutexFree.set(false);
2383            final long now = SystemClock.uptimeMillis();
2384            boolean haveNewCpuStats = false;
2385
2386            if (MONITOR_CPU_USAGE &&
2387                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2388                mLastCpuTime.set(now);
2389                haveNewCpuStats = true;
2390                mProcessCpuTracker.update();
2391                //Slog.i(TAG, mProcessCpu.printCurrentState());
2392                //Slog.i(TAG, "Total CPU usage: "
2393                //        + mProcessCpu.getTotalCpuPercent() + "%");
2394
2395                // Slog the cpu usage if the property is set.
2396                if ("true".equals(SystemProperties.get("events.cpu"))) {
2397                    int user = mProcessCpuTracker.getLastUserTime();
2398                    int system = mProcessCpuTracker.getLastSystemTime();
2399                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2400                    int irq = mProcessCpuTracker.getLastIrqTime();
2401                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2402                    int idle = mProcessCpuTracker.getLastIdleTime();
2403
2404                    int total = user + system + iowait + irq + softIrq + idle;
2405                    if (total == 0) total = 1;
2406
2407                    EventLog.writeEvent(EventLogTags.CPU,
2408                            ((user+system+iowait+irq+softIrq) * 100) / total,
2409                            (user * 100) / total,
2410                            (system * 100) / total,
2411                            (iowait * 100) / total,
2412                            (irq * 100) / total,
2413                            (softIrq * 100) / total);
2414                }
2415            }
2416
2417            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2418            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2419            synchronized(bstats) {
2420                synchronized(mPidsSelfLocked) {
2421                    if (haveNewCpuStats) {
2422                        if (mOnBattery) {
2423                            int perc = bstats.startAddingCpuLocked();
2424                            int totalUTime = 0;
2425                            int totalSTime = 0;
2426                            final int N = mProcessCpuTracker.countStats();
2427                            for (int i=0; i<N; i++) {
2428                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2429                                if (!st.working) {
2430                                    continue;
2431                                }
2432                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2433                                int otherUTime = (st.rel_utime*perc)/100;
2434                                int otherSTime = (st.rel_stime*perc)/100;
2435                                totalUTime += otherUTime;
2436                                totalSTime += otherSTime;
2437                                if (pr != null) {
2438                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2439                                    if (ps == null || !ps.isActive()) {
2440                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2441                                                pr.info.uid, pr.processName);
2442                                    }
2443                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2444                                            st.rel_stime-otherSTime);
2445                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2446                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2447                                } else {
2448                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2449                                    if (ps == null || !ps.isActive()) {
2450                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2451                                                bstats.mapUid(st.uid), st.name);
2452                                    }
2453                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2454                                            st.rel_stime-otherSTime);
2455                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2456                                }
2457                            }
2458                            bstats.finishAddingCpuLocked(perc, totalUTime,
2459                                    totalSTime, cpuSpeedTimes);
2460                        }
2461                    }
2462                }
2463
2464                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2465                    mLastWriteTime = now;
2466                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2467                }
2468            }
2469        }
2470    }
2471
2472    @Override
2473    public void batteryNeedsCpuUpdate() {
2474        updateCpuStatsNow();
2475    }
2476
2477    @Override
2478    public void batteryPowerChanged(boolean onBattery) {
2479        // When plugging in, update the CPU stats first before changing
2480        // the plug state.
2481        updateCpuStatsNow();
2482        synchronized (this) {
2483            synchronized(mPidsSelfLocked) {
2484                mOnBattery = DEBUG_POWER ? true : onBattery;
2485            }
2486        }
2487    }
2488
2489    /**
2490     * Initialize the application bind args. These are passed to each
2491     * process when the bindApplication() IPC is sent to the process. They're
2492     * lazily setup to make sure the services are running when they're asked for.
2493     */
2494    private HashMap<String, IBinder> getCommonServicesLocked() {
2495        if (mAppBindArgs == null) {
2496            mAppBindArgs = new HashMap<String, IBinder>();
2497
2498            // Setup the application init args
2499            mAppBindArgs.put("package", ServiceManager.getService("package"));
2500            mAppBindArgs.put("window", ServiceManager.getService("window"));
2501            mAppBindArgs.put(Context.ALARM_SERVICE,
2502                    ServiceManager.getService(Context.ALARM_SERVICE));
2503        }
2504        return mAppBindArgs;
2505    }
2506
2507    final void setFocusedActivityLocked(ActivityRecord r) {
2508        if (mFocusedActivity != r) {
2509            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2510            mFocusedActivity = r;
2511            if (r.task != null && r.task.voiceInteractor != null) {
2512                startRunningVoiceLocked();
2513            } else {
2514                finishRunningVoiceLocked();
2515            }
2516            mStackSupervisor.setFocusedStack(r);
2517            if (r != null) {
2518                mWindowManager.setFocusedApp(r.appToken, true);
2519            }
2520            applyUpdateLockStateLocked(r);
2521        }
2522    }
2523
2524    final void clearFocusedActivity(ActivityRecord r) {
2525        if (mFocusedActivity == r) {
2526            mFocusedActivity = null;
2527        }
2528    }
2529
2530    @Override
2531    public void setFocusedStack(int stackId) {
2532        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2533        synchronized (ActivityManagerService.this) {
2534            ActivityStack stack = mStackSupervisor.getStack(stackId);
2535            if (stack != null) {
2536                ActivityRecord r = stack.topRunningActivityLocked(null);
2537                if (r != null) {
2538                    setFocusedActivityLocked(r);
2539                }
2540            }
2541        }
2542    }
2543
2544    @Override
2545    public void notifyActivityDrawn(IBinder token) {
2546        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2547        synchronized (this) {
2548            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2549            if (r != null) {
2550                r.task.stack.notifyActivityDrawnLocked(r);
2551            }
2552        }
2553    }
2554
2555    final void applyUpdateLockStateLocked(ActivityRecord r) {
2556        // Modifications to the UpdateLock state are done on our handler, outside
2557        // the activity manager's locks.  The new state is determined based on the
2558        // state *now* of the relevant activity record.  The object is passed to
2559        // the handler solely for logging detail, not to be consulted/modified.
2560        final boolean nextState = r != null && r.immersive;
2561        mHandler.sendMessage(
2562                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2563    }
2564
2565    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2566        Message msg = Message.obtain();
2567        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2568        msg.obj = r.task.askedCompatMode ? null : r;
2569        mHandler.sendMessage(msg);
2570    }
2571
2572    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2573            String what, Object obj, ProcessRecord srcApp) {
2574        app.lastActivityTime = now;
2575
2576        if (app.activities.size() > 0) {
2577            // Don't want to touch dependent processes that are hosting activities.
2578            return index;
2579        }
2580
2581        int lrui = mLruProcesses.lastIndexOf(app);
2582        if (lrui < 0) {
2583            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2584                    + what + " " + obj + " from " + srcApp);
2585            return index;
2586        }
2587
2588        if (lrui >= index) {
2589            // Don't want to cause this to move dependent processes *back* in the
2590            // list as if they were less frequently used.
2591            return index;
2592        }
2593
2594        if (lrui >= mLruProcessActivityStart) {
2595            // Don't want to touch dependent processes that are hosting activities.
2596            return index;
2597        }
2598
2599        mLruProcesses.remove(lrui);
2600        if (index > 0) {
2601            index--;
2602        }
2603        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2604                + " in LRU list: " + app);
2605        mLruProcesses.add(index, app);
2606        return index;
2607    }
2608
2609    final void removeLruProcessLocked(ProcessRecord app) {
2610        int lrui = mLruProcesses.lastIndexOf(app);
2611        if (lrui >= 0) {
2612            if (lrui <= mLruProcessActivityStart) {
2613                mLruProcessActivityStart--;
2614            }
2615            if (lrui <= mLruProcessServiceStart) {
2616                mLruProcessServiceStart--;
2617            }
2618            mLruProcesses.remove(lrui);
2619        }
2620    }
2621
2622    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2623            ProcessRecord client) {
2624        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2625                || app.treatLikeActivity;
2626        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2627        if (!activityChange && hasActivity) {
2628            // The process has activities, so we are only allowing activity-based adjustments
2629            // to move it.  It should be kept in the front of the list with other
2630            // processes that have activities, and we don't want those to change their
2631            // order except due to activity operations.
2632            return;
2633        }
2634
2635        mLruSeq++;
2636        final long now = SystemClock.uptimeMillis();
2637        app.lastActivityTime = now;
2638
2639        // First a quick reject: if the app is already at the position we will
2640        // put it, then there is nothing to do.
2641        if (hasActivity) {
2642            final int N = mLruProcesses.size();
2643            if (N > 0 && mLruProcesses.get(N-1) == app) {
2644                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2645                return;
2646            }
2647        } else {
2648            if (mLruProcessServiceStart > 0
2649                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2650                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2651                return;
2652            }
2653        }
2654
2655        int lrui = mLruProcesses.lastIndexOf(app);
2656
2657        if (app.persistent && lrui >= 0) {
2658            // We don't care about the position of persistent processes, as long as
2659            // they are in the list.
2660            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2661            return;
2662        }
2663
2664        /* In progress: compute new position first, so we can avoid doing work
2665           if the process is not actually going to move.  Not yet working.
2666        int addIndex;
2667        int nextIndex;
2668        boolean inActivity = false, inService = false;
2669        if (hasActivity) {
2670            // Process has activities, put it at the very tipsy-top.
2671            addIndex = mLruProcesses.size();
2672            nextIndex = mLruProcessServiceStart;
2673            inActivity = true;
2674        } else if (hasService) {
2675            // Process has services, put it at the top of the service list.
2676            addIndex = mLruProcessActivityStart;
2677            nextIndex = mLruProcessServiceStart;
2678            inActivity = true;
2679            inService = true;
2680        } else  {
2681            // Process not otherwise of interest, it goes to the top of the non-service area.
2682            addIndex = mLruProcessServiceStart;
2683            if (client != null) {
2684                int clientIndex = mLruProcesses.lastIndexOf(client);
2685                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2686                        + app);
2687                if (clientIndex >= 0 && addIndex > clientIndex) {
2688                    addIndex = clientIndex;
2689                }
2690            }
2691            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2692        }
2693
2694        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2695                + mLruProcessActivityStart + "): " + app);
2696        */
2697
2698        if (lrui >= 0) {
2699            if (lrui < mLruProcessActivityStart) {
2700                mLruProcessActivityStart--;
2701            }
2702            if (lrui < mLruProcessServiceStart) {
2703                mLruProcessServiceStart--;
2704            }
2705            /*
2706            if (addIndex > lrui) {
2707                addIndex--;
2708            }
2709            if (nextIndex > lrui) {
2710                nextIndex--;
2711            }
2712            */
2713            mLruProcesses.remove(lrui);
2714        }
2715
2716        /*
2717        mLruProcesses.add(addIndex, app);
2718        if (inActivity) {
2719            mLruProcessActivityStart++;
2720        }
2721        if (inService) {
2722            mLruProcessActivityStart++;
2723        }
2724        */
2725
2726        int nextIndex;
2727        if (hasActivity) {
2728            final int N = mLruProcesses.size();
2729            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2730                // Process doesn't have activities, but has clients with
2731                // activities...  move it up, but one below the top (the top
2732                // should always have a real activity).
2733                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2734                mLruProcesses.add(N-1, app);
2735                // To keep it from spamming the LRU list (by making a bunch of clients),
2736                // we will push down any other entries owned by the app.
2737                final int uid = app.info.uid;
2738                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2739                    ProcessRecord subProc = mLruProcesses.get(i);
2740                    if (subProc.info.uid == uid) {
2741                        // We want to push this one down the list.  If the process after
2742                        // it is for the same uid, however, don't do so, because we don't
2743                        // want them internally to be re-ordered.
2744                        if (mLruProcesses.get(i-1).info.uid != uid) {
2745                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2746                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2747                            ProcessRecord tmp = mLruProcesses.get(i);
2748                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2749                            mLruProcesses.set(i-1, tmp);
2750                            i--;
2751                        }
2752                    } else {
2753                        // A gap, we can stop here.
2754                        break;
2755                    }
2756                }
2757            } else {
2758                // Process has activities, put it at the very tipsy-top.
2759                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2760                mLruProcesses.add(app);
2761            }
2762            nextIndex = mLruProcessServiceStart;
2763        } else if (hasService) {
2764            // Process has services, put it at the top of the service list.
2765            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2766            mLruProcesses.add(mLruProcessActivityStart, app);
2767            nextIndex = mLruProcessServiceStart;
2768            mLruProcessActivityStart++;
2769        } else  {
2770            // Process not otherwise of interest, it goes to the top of the non-service area.
2771            int index = mLruProcessServiceStart;
2772            if (client != null) {
2773                // If there is a client, don't allow the process to be moved up higher
2774                // in the list than that client.
2775                int clientIndex = mLruProcesses.lastIndexOf(client);
2776                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2777                        + " when updating " + app);
2778                if (clientIndex <= lrui) {
2779                    // Don't allow the client index restriction to push it down farther in the
2780                    // list than it already is.
2781                    clientIndex = lrui;
2782                }
2783                if (clientIndex >= 0 && index > clientIndex) {
2784                    index = clientIndex;
2785                }
2786            }
2787            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2788            mLruProcesses.add(index, app);
2789            nextIndex = index-1;
2790            mLruProcessActivityStart++;
2791            mLruProcessServiceStart++;
2792        }
2793
2794        // If the app is currently using a content provider or service,
2795        // bump those processes as well.
2796        for (int j=app.connections.size()-1; j>=0; j--) {
2797            ConnectionRecord cr = app.connections.valueAt(j);
2798            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2799                    && cr.binding.service.app != null
2800                    && cr.binding.service.app.lruSeq != mLruSeq
2801                    && !cr.binding.service.app.persistent) {
2802                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2803                        "service connection", cr, app);
2804            }
2805        }
2806        for (int j=app.conProviders.size()-1; j>=0; j--) {
2807            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2808            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2809                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2810                        "provider reference", cpr, app);
2811            }
2812        }
2813    }
2814
2815    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2816        if (uid == Process.SYSTEM_UID) {
2817            // The system gets to run in any process.  If there are multiple
2818            // processes with the same uid, just pick the first (this
2819            // should never happen).
2820            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2821            if (procs == null) return null;
2822            final int N = procs.size();
2823            for (int i = 0; i < N; i++) {
2824                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2825            }
2826        }
2827        ProcessRecord proc = mProcessNames.get(processName, uid);
2828        if (false && proc != null && !keepIfLarge
2829                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2830                && proc.lastCachedPss >= 4000) {
2831            // Turn this condition on to cause killing to happen regularly, for testing.
2832            if (proc.baseProcessTracker != null) {
2833                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2834            }
2835            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2836        } else if (proc != null && !keepIfLarge
2837                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2838                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2839            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2840            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2841                if (proc.baseProcessTracker != null) {
2842                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2843                }
2844                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2845            }
2846        }
2847        return proc;
2848    }
2849
2850    void ensurePackageDexOpt(String packageName) {
2851        IPackageManager pm = AppGlobals.getPackageManager();
2852        try {
2853            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2854                mDidDexOpt = true;
2855            }
2856        } catch (RemoteException e) {
2857        }
2858    }
2859
2860    boolean isNextTransitionForward() {
2861        int transit = mWindowManager.getPendingAppTransition();
2862        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2863                || transit == AppTransition.TRANSIT_TASK_OPEN
2864                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2865    }
2866
2867    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2868            String processName, String abiOverride, int uid, Runnable crashHandler) {
2869        synchronized(this) {
2870            ApplicationInfo info = new ApplicationInfo();
2871            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2872            // For isolated processes, the former contains the parent's uid and the latter the
2873            // actual uid of the isolated process.
2874            // In the special case introduced by this method (which is, starting an isolated
2875            // process directly from the SystemServer without an actual parent app process) the
2876            // closest thing to a parent's uid is SYSTEM_UID.
2877            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2878            // the |isolated| logic in the ProcessRecord constructor.
2879            info.uid = Process.SYSTEM_UID;
2880            info.processName = processName;
2881            info.className = entryPoint;
2882            info.packageName = "android";
2883            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2884                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2885                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2886                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2887                    crashHandler);
2888            return proc != null ? proc.pid : 0;
2889        }
2890    }
2891
2892    final ProcessRecord startProcessLocked(String processName,
2893            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2894            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2895            boolean isolated, boolean keepIfLarge) {
2896        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2897                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2898                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2899                null /* crashHandler */);
2900    }
2901
2902    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2903            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2904            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2905            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2906        long startTime = SystemClock.elapsedRealtime();
2907        ProcessRecord app;
2908        if (!isolated) {
2909            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2910            checkTime(startTime, "startProcess: after getProcessRecord");
2911        } else {
2912            // If this is an isolated process, it can't re-use an existing process.
2913            app = null;
2914        }
2915        // We don't have to do anything more if:
2916        // (1) There is an existing application record; and
2917        // (2) The caller doesn't think it is dead, OR there is no thread
2918        //     object attached to it so we know it couldn't have crashed; and
2919        // (3) There is a pid assigned to it, so it is either starting or
2920        //     already running.
2921        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2922                + " app=" + app + " knownToBeDead=" + knownToBeDead
2923                + " thread=" + (app != null ? app.thread : null)
2924                + " pid=" + (app != null ? app.pid : -1));
2925        if (app != null && app.pid > 0) {
2926            if (!knownToBeDead || app.thread == null) {
2927                // We already have the app running, or are waiting for it to
2928                // come up (we have a pid but not yet its thread), so keep it.
2929                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2930                // If this is a new package in the process, add the package to the list
2931                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2932                checkTime(startTime, "startProcess: done, added package to proc");
2933                return app;
2934            }
2935
2936            // An application record is attached to a previous process,
2937            // clean it up now.
2938            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2939            checkTime(startTime, "startProcess: bad proc running, killing");
2940            Process.killProcessGroup(app.info.uid, app.pid);
2941            handleAppDiedLocked(app, true, true);
2942            checkTime(startTime, "startProcess: done killing old proc");
2943        }
2944
2945        String hostingNameStr = hostingName != null
2946                ? hostingName.flattenToShortString() : null;
2947
2948        if (!isolated) {
2949            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2950                // If we are in the background, then check to see if this process
2951                // is bad.  If so, we will just silently fail.
2952                if (mBadProcesses.get(info.processName, info.uid) != null) {
2953                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2954                            + "/" + info.processName);
2955                    return null;
2956                }
2957            } else {
2958                // When the user is explicitly starting a process, then clear its
2959                // crash count so that we won't make it bad until they see at
2960                // least one crash dialog again, and make the process good again
2961                // if it had been bad.
2962                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2963                        + "/" + info.processName);
2964                mProcessCrashTimes.remove(info.processName, info.uid);
2965                if (mBadProcesses.get(info.processName, info.uid) != null) {
2966                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2967                            UserHandle.getUserId(info.uid), info.uid,
2968                            info.processName);
2969                    mBadProcesses.remove(info.processName, info.uid);
2970                    if (app != null) {
2971                        app.bad = false;
2972                    }
2973                }
2974            }
2975        }
2976
2977        if (app == null) {
2978            checkTime(startTime, "startProcess: creating new process record");
2979            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2980            app.crashHandler = crashHandler;
2981            if (app == null) {
2982                Slog.w(TAG, "Failed making new process record for "
2983                        + processName + "/" + info.uid + " isolated=" + isolated);
2984                return null;
2985            }
2986            mProcessNames.put(processName, app.uid, app);
2987            if (isolated) {
2988                mIsolatedProcesses.put(app.uid, app);
2989            }
2990            checkTime(startTime, "startProcess: done creating new process record");
2991        } else {
2992            // If this is a new package in the process, add the package to the list
2993            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2994            checkTime(startTime, "startProcess: added package to existing proc");
2995        }
2996
2997        // If the system is not ready yet, then hold off on starting this
2998        // process until it is.
2999        if (!mProcessesReady
3000                && !isAllowedWhileBooting(info)
3001                && !allowWhileBooting) {
3002            if (!mProcessesOnHold.contains(app)) {
3003                mProcessesOnHold.add(app);
3004            }
3005            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3006            checkTime(startTime, "startProcess: returning with proc on hold");
3007            return app;
3008        }
3009
3010        checkTime(startTime, "startProcess: stepping in to startProcess");
3011        startProcessLocked(
3012                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3013        checkTime(startTime, "startProcess: done starting proc!");
3014        return (app.pid != 0) ? app : null;
3015    }
3016
3017    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3018        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3019    }
3020
3021    private final void startProcessLocked(ProcessRecord app,
3022            String hostingType, String hostingNameStr) {
3023        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3024                null /* entryPoint */, null /* entryPointArgs */);
3025    }
3026
3027    private final void startProcessLocked(ProcessRecord app, String hostingType,
3028            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3029        long startTime = SystemClock.elapsedRealtime();
3030        if (app.pid > 0 && app.pid != MY_PID) {
3031            checkTime(startTime, "startProcess: removing from pids map");
3032            synchronized (mPidsSelfLocked) {
3033                mPidsSelfLocked.remove(app.pid);
3034                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3035            }
3036            checkTime(startTime, "startProcess: done removing from pids map");
3037            app.setPid(0);
3038        }
3039
3040        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3041                "startProcessLocked removing on hold: " + app);
3042        mProcessesOnHold.remove(app);
3043
3044        checkTime(startTime, "startProcess: starting to update cpu stats");
3045        updateCpuStats();
3046        checkTime(startTime, "startProcess: done updating cpu stats");
3047
3048        try {
3049            int uid = app.uid;
3050
3051            int[] gids = null;
3052            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3053            if (!app.isolated) {
3054                int[] permGids = null;
3055                try {
3056                    checkTime(startTime, "startProcess: getting gids from package manager");
3057                    final PackageManager pm = mContext.getPackageManager();
3058                    permGids = pm.getPackageGids(app.info.packageName);
3059
3060                    if (Environment.isExternalStorageEmulated()) {
3061                        checkTime(startTime, "startProcess: checking external storage perm");
3062                        if (pm.checkPermission(
3063                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3064                                app.info.packageName) == PERMISSION_GRANTED) {
3065                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3066                        } else {
3067                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3068                        }
3069                    }
3070                } catch (PackageManager.NameNotFoundException e) {
3071                    Slog.w(TAG, "Unable to retrieve gids", e);
3072                }
3073
3074                /*
3075                 * Add shared application and profile GIDs so applications can share some
3076                 * resources like shared libraries and access user-wide resources
3077                 */
3078                if (permGids == null) {
3079                    gids = new int[2];
3080                } else {
3081                    gids = new int[permGids.length + 2];
3082                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3083                }
3084                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3085                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3086            }
3087            checkTime(startTime, "startProcess: building args");
3088            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3089                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3090                        && mTopComponent != null
3091                        && app.processName.equals(mTopComponent.getPackageName())) {
3092                    uid = 0;
3093                }
3094                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3095                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3096                    uid = 0;
3097                }
3098            }
3099            int debugFlags = 0;
3100            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3101                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3102                // Also turn on CheckJNI for debuggable apps. It's quite
3103                // awkward to turn on otherwise.
3104                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3105            }
3106            // Run the app in safe mode if its manifest requests so or the
3107            // system is booted in safe mode.
3108            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3109                mSafeMode == true) {
3110                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3111            }
3112            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3113                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3114            }
3115            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3116                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3117            }
3118            if ("1".equals(SystemProperties.get("debug.assert"))) {
3119                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3120            }
3121
3122            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3123            if (requiredAbi == null) {
3124                requiredAbi = Build.SUPPORTED_ABIS[0];
3125            }
3126
3127            // Start the process.  It will either succeed and return a result containing
3128            // the PID of the new process, or else throw a RuntimeException.
3129            boolean isActivityProcess = (entryPoint == null);
3130            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3131            checkTime(startTime, "startProcess: asking zygote to start proc");
3132            Process.ProcessStartResult startResult = Process.start(entryPoint,
3133                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3134                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3135            checkTime(startTime, "startProcess: returned from zygote!");
3136
3137            if (app.isolated) {
3138                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3139            }
3140            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3141            checkTime(startTime, "startProcess: done updating battery stats");
3142
3143            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3144                    UserHandle.getUserId(uid), startResult.pid, uid,
3145                    app.processName, hostingType,
3146                    hostingNameStr != null ? hostingNameStr : "");
3147
3148            if (app.persistent) {
3149                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3150            }
3151
3152            checkTime(startTime, "startProcess: building log message");
3153            StringBuilder buf = mStringBuilder;
3154            buf.setLength(0);
3155            buf.append("Start proc ");
3156            buf.append(app.processName);
3157            if (!isActivityProcess) {
3158                buf.append(" [");
3159                buf.append(entryPoint);
3160                buf.append("]");
3161            }
3162            buf.append(" for ");
3163            buf.append(hostingType);
3164            if (hostingNameStr != null) {
3165                buf.append(" ");
3166                buf.append(hostingNameStr);
3167            }
3168            buf.append(": pid=");
3169            buf.append(startResult.pid);
3170            buf.append(" uid=");
3171            buf.append(uid);
3172            buf.append(" gids={");
3173            if (gids != null) {
3174                for (int gi=0; gi<gids.length; gi++) {
3175                    if (gi != 0) buf.append(", ");
3176                    buf.append(gids[gi]);
3177
3178                }
3179            }
3180            buf.append("}");
3181            if (requiredAbi != null) {
3182                buf.append(" abi=");
3183                buf.append(requiredAbi);
3184            }
3185            Slog.i(TAG, buf.toString());
3186            app.setPid(startResult.pid);
3187            app.usingWrapper = startResult.usingWrapper;
3188            app.removed = false;
3189            app.killedByAm = false;
3190            checkTime(startTime, "startProcess: starting to update pids map");
3191            synchronized (mPidsSelfLocked) {
3192                this.mPidsSelfLocked.put(startResult.pid, app);
3193                if (isActivityProcess) {
3194                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3195                    msg.obj = app;
3196                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3197                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3198                }
3199            }
3200            checkTime(startTime, "startProcess: done updating pids map");
3201        } catch (RuntimeException e) {
3202            // XXX do better error recovery.
3203            app.setPid(0);
3204            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3205            if (app.isolated) {
3206                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3207            }
3208            Slog.e(TAG, "Failure starting process " + app.processName, e);
3209        }
3210    }
3211
3212    void updateUsageStats(ActivityRecord component, boolean resumed) {
3213        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3214        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3215        if (resumed) {
3216            if (mUsageStatsService != null) {
3217                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3218                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3219            }
3220            synchronized (stats) {
3221                stats.noteActivityResumedLocked(component.app.uid);
3222            }
3223        } else {
3224            if (mUsageStatsService != null) {
3225                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3226                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3227            }
3228            synchronized (stats) {
3229                stats.noteActivityPausedLocked(component.app.uid);
3230            }
3231        }
3232    }
3233
3234    Intent getHomeIntent() {
3235        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3236        intent.setComponent(mTopComponent);
3237        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3238            intent.addCategory(Intent.CATEGORY_HOME);
3239        }
3240        return intent;
3241    }
3242
3243    boolean startHomeActivityLocked(int userId) {
3244        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3245                && mTopAction == null) {
3246            // We are running in factory test mode, but unable to find
3247            // the factory test app, so just sit around displaying the
3248            // error message and don't try to start anything.
3249            return false;
3250        }
3251        Intent intent = getHomeIntent();
3252        ActivityInfo aInfo =
3253            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3254        if (aInfo != null) {
3255            intent.setComponent(new ComponentName(
3256                    aInfo.applicationInfo.packageName, aInfo.name));
3257            // Don't do this if the home app is currently being
3258            // instrumented.
3259            aInfo = new ActivityInfo(aInfo);
3260            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3261            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3262                    aInfo.applicationInfo.uid, true);
3263            if (app == null || app.instrumentationClass == null) {
3264                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3265                mStackSupervisor.startHomeActivity(intent, aInfo);
3266            }
3267        }
3268
3269        return true;
3270    }
3271
3272    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3273        ActivityInfo ai = null;
3274        ComponentName comp = intent.getComponent();
3275        try {
3276            if (comp != null) {
3277                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3278            } else {
3279                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3280                        intent,
3281                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3282                            flags, userId);
3283
3284                if (info != null) {
3285                    ai = info.activityInfo;
3286                }
3287            }
3288        } catch (RemoteException e) {
3289            // ignore
3290        }
3291
3292        return ai;
3293    }
3294
3295    /**
3296     * Starts the "new version setup screen" if appropriate.
3297     */
3298    void startSetupActivityLocked() {
3299        // Only do this once per boot.
3300        if (mCheckedForSetup) {
3301            return;
3302        }
3303
3304        // We will show this screen if the current one is a different
3305        // version than the last one shown, and we are not running in
3306        // low-level factory test mode.
3307        final ContentResolver resolver = mContext.getContentResolver();
3308        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3309                Settings.Global.getInt(resolver,
3310                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3311            mCheckedForSetup = true;
3312
3313            // See if we should be showing the platform update setup UI.
3314            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3315            List<ResolveInfo> ris = mContext.getPackageManager()
3316                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3317
3318            // We don't allow third party apps to replace this.
3319            ResolveInfo ri = null;
3320            for (int i=0; ris != null && i<ris.size(); i++) {
3321                if ((ris.get(i).activityInfo.applicationInfo.flags
3322                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3323                    ri = ris.get(i);
3324                    break;
3325                }
3326            }
3327
3328            if (ri != null) {
3329                String vers = ri.activityInfo.metaData != null
3330                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3331                        : null;
3332                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3333                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3334                            Intent.METADATA_SETUP_VERSION);
3335                }
3336                String lastVers = Settings.Secure.getString(
3337                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3338                if (vers != null && !vers.equals(lastVers)) {
3339                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3340                    intent.setComponent(new ComponentName(
3341                            ri.activityInfo.packageName, ri.activityInfo.name));
3342                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3343                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3344                            null);
3345                }
3346            }
3347        }
3348    }
3349
3350    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3351        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3352    }
3353
3354    void enforceNotIsolatedCaller(String caller) {
3355        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3356            throw new SecurityException("Isolated process not allowed to call " + caller);
3357        }
3358    }
3359
3360    @Override
3361    public int getFrontActivityScreenCompatMode() {
3362        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3363        synchronized (this) {
3364            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3365        }
3366    }
3367
3368    @Override
3369    public void setFrontActivityScreenCompatMode(int mode) {
3370        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3371                "setFrontActivityScreenCompatMode");
3372        synchronized (this) {
3373            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3374        }
3375    }
3376
3377    @Override
3378    public int getPackageScreenCompatMode(String packageName) {
3379        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3380        synchronized (this) {
3381            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3382        }
3383    }
3384
3385    @Override
3386    public void setPackageScreenCompatMode(String packageName, int mode) {
3387        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3388                "setPackageScreenCompatMode");
3389        synchronized (this) {
3390            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3391        }
3392    }
3393
3394    @Override
3395    public boolean getPackageAskScreenCompat(String packageName) {
3396        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3397        synchronized (this) {
3398            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3399        }
3400    }
3401
3402    @Override
3403    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3404        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3405                "setPackageAskScreenCompat");
3406        synchronized (this) {
3407            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3408        }
3409    }
3410
3411    private void dispatchProcessesChanged() {
3412        int N;
3413        synchronized (this) {
3414            N = mPendingProcessChanges.size();
3415            if (mActiveProcessChanges.length < N) {
3416                mActiveProcessChanges = new ProcessChangeItem[N];
3417            }
3418            mPendingProcessChanges.toArray(mActiveProcessChanges);
3419            mAvailProcessChanges.addAll(mPendingProcessChanges);
3420            mPendingProcessChanges.clear();
3421            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3422        }
3423
3424        int i = mProcessObservers.beginBroadcast();
3425        while (i > 0) {
3426            i--;
3427            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3428            if (observer != null) {
3429                try {
3430                    for (int j=0; j<N; j++) {
3431                        ProcessChangeItem item = mActiveProcessChanges[j];
3432                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3433                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3434                                    + item.pid + " uid=" + item.uid + ": "
3435                                    + item.foregroundActivities);
3436                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3437                                    item.foregroundActivities);
3438                        }
3439                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3440                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3441                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3442                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3443                        }
3444                    }
3445                } catch (RemoteException e) {
3446                }
3447            }
3448        }
3449        mProcessObservers.finishBroadcast();
3450    }
3451
3452    private void dispatchProcessDied(int pid, int uid) {
3453        int i = mProcessObservers.beginBroadcast();
3454        while (i > 0) {
3455            i--;
3456            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3457            if (observer != null) {
3458                try {
3459                    observer.onProcessDied(pid, uid);
3460                } catch (RemoteException e) {
3461                }
3462            }
3463        }
3464        mProcessObservers.finishBroadcast();
3465    }
3466
3467    @Override
3468    public final int startActivity(IApplicationThread caller, String callingPackage,
3469            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3470            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3471        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3472            resultWho, requestCode, startFlags, profilerInfo, options,
3473            UserHandle.getCallingUserId());
3474    }
3475
3476    @Override
3477    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3478            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3479            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3480        enforceNotIsolatedCaller("startActivity");
3481        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3482                false, ALLOW_FULL_ONLY, "startActivity", null);
3483        // TODO: Switch to user app stacks here.
3484        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3485                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3486                profilerInfo, null, null, options, userId, null, null);
3487    }
3488
3489    @Override
3490    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3491            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3492            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3493
3494        // This is very dangerous -- it allows you to perform a start activity (including
3495        // permission grants) as any app that may launch one of your own activities.  So
3496        // we will only allow this to be done from activities that are part of the core framework,
3497        // and then only when they are running as the system.
3498        final ActivityRecord sourceRecord;
3499        final int targetUid;
3500        final String targetPackage;
3501        synchronized (this) {
3502            if (resultTo == null) {
3503                throw new SecurityException("Must be called from an activity");
3504            }
3505            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3506            if (sourceRecord == null) {
3507                throw new SecurityException("Called with bad activity token: " + resultTo);
3508            }
3509            if (!sourceRecord.info.packageName.equals("android")) {
3510                throw new SecurityException(
3511                        "Must be called from an activity that is declared in the android package");
3512            }
3513            if (sourceRecord.app == null) {
3514                throw new SecurityException("Called without a process attached to activity");
3515            }
3516            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3517                // This is still okay, as long as this activity is running under the
3518                // uid of the original calling activity.
3519                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3520                    throw new SecurityException(
3521                            "Calling activity in uid " + sourceRecord.app.uid
3522                                    + " must be system uid or original calling uid "
3523                                    + sourceRecord.launchedFromUid);
3524                }
3525            }
3526            targetUid = sourceRecord.launchedFromUid;
3527            targetPackage = sourceRecord.launchedFromPackage;
3528        }
3529
3530        // TODO: Switch to user app stacks here.
3531        try {
3532            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3533                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3534                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3535            return ret;
3536        } catch (SecurityException e) {
3537            // XXX need to figure out how to propagate to original app.
3538            // A SecurityException here is generally actually a fault of the original
3539            // calling activity (such as a fairly granting permissions), so propagate it
3540            // back to them.
3541            /*
3542            StringBuilder msg = new StringBuilder();
3543            msg.append("While launching");
3544            msg.append(intent.toString());
3545            msg.append(": ");
3546            msg.append(e.getMessage());
3547            */
3548            throw e;
3549        }
3550    }
3551
3552    @Override
3553    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3554            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3555            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3556        enforceNotIsolatedCaller("startActivityAndWait");
3557        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3558                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3559        WaitResult res = new WaitResult();
3560        // TODO: Switch to user app stacks here.
3561        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3562                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3563                options, userId, null, null);
3564        return res;
3565    }
3566
3567    @Override
3568    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3569            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3570            int startFlags, Configuration config, Bundle options, int userId) {
3571        enforceNotIsolatedCaller("startActivityWithConfig");
3572        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3573                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3574        // TODO: Switch to user app stacks here.
3575        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3576                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3577                null, null, config, options, userId, null, null);
3578        return ret;
3579    }
3580
3581    @Override
3582    public int startActivityIntentSender(IApplicationThread caller,
3583            IntentSender intent, Intent fillInIntent, String resolvedType,
3584            IBinder resultTo, String resultWho, int requestCode,
3585            int flagsMask, int flagsValues, Bundle options) {
3586        enforceNotIsolatedCaller("startActivityIntentSender");
3587        // Refuse possible leaked file descriptors
3588        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3589            throw new IllegalArgumentException("File descriptors passed in Intent");
3590        }
3591
3592        IIntentSender sender = intent.getTarget();
3593        if (!(sender instanceof PendingIntentRecord)) {
3594            throw new IllegalArgumentException("Bad PendingIntent object");
3595        }
3596
3597        PendingIntentRecord pir = (PendingIntentRecord)sender;
3598
3599        synchronized (this) {
3600            // If this is coming from the currently resumed activity, it is
3601            // effectively saying that app switches are allowed at this point.
3602            final ActivityStack stack = getFocusedStack();
3603            if (stack.mResumedActivity != null &&
3604                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3605                mAppSwitchesAllowedTime = 0;
3606            }
3607        }
3608        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3609                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3610        return ret;
3611    }
3612
3613    @Override
3614    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3615            Intent intent, String resolvedType, IVoiceInteractionSession session,
3616            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3617            Bundle options, int userId) {
3618        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3619                != PackageManager.PERMISSION_GRANTED) {
3620            String msg = "Permission Denial: startVoiceActivity() from pid="
3621                    + Binder.getCallingPid()
3622                    + ", uid=" + Binder.getCallingUid()
3623                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3624            Slog.w(TAG, msg);
3625            throw new SecurityException(msg);
3626        }
3627        if (session == null || interactor == null) {
3628            throw new NullPointerException("null session or interactor");
3629        }
3630        userId = handleIncomingUser(callingPid, callingUid, userId,
3631                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3632        // TODO: Switch to user app stacks here.
3633        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3634                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3635                null, options, userId, null, null);
3636    }
3637
3638    @Override
3639    public boolean startNextMatchingActivity(IBinder callingActivity,
3640            Intent intent, Bundle options) {
3641        // Refuse possible leaked file descriptors
3642        if (intent != null && intent.hasFileDescriptors() == true) {
3643            throw new IllegalArgumentException("File descriptors passed in Intent");
3644        }
3645
3646        synchronized (this) {
3647            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3648            if (r == null) {
3649                ActivityOptions.abort(options);
3650                return false;
3651            }
3652            if (r.app == null || r.app.thread == null) {
3653                // The caller is not running...  d'oh!
3654                ActivityOptions.abort(options);
3655                return false;
3656            }
3657            intent = new Intent(intent);
3658            // The caller is not allowed to change the data.
3659            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3660            // And we are resetting to find the next component...
3661            intent.setComponent(null);
3662
3663            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3664
3665            ActivityInfo aInfo = null;
3666            try {
3667                List<ResolveInfo> resolves =
3668                    AppGlobals.getPackageManager().queryIntentActivities(
3669                            intent, r.resolvedType,
3670                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3671                            UserHandle.getCallingUserId());
3672
3673                // Look for the original activity in the list...
3674                final int N = resolves != null ? resolves.size() : 0;
3675                for (int i=0; i<N; i++) {
3676                    ResolveInfo rInfo = resolves.get(i);
3677                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3678                            && rInfo.activityInfo.name.equals(r.info.name)) {
3679                        // We found the current one...  the next matching is
3680                        // after it.
3681                        i++;
3682                        if (i<N) {
3683                            aInfo = resolves.get(i).activityInfo;
3684                        }
3685                        if (debug) {
3686                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3687                                    + "/" + r.info.name);
3688                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3689                                    + "/" + aInfo.name);
3690                        }
3691                        break;
3692                    }
3693                }
3694            } catch (RemoteException e) {
3695            }
3696
3697            if (aInfo == null) {
3698                // Nobody who is next!
3699                ActivityOptions.abort(options);
3700                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3701                return false;
3702            }
3703
3704            intent.setComponent(new ComponentName(
3705                    aInfo.applicationInfo.packageName, aInfo.name));
3706            intent.setFlags(intent.getFlags()&~(
3707                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3708                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3709                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3710                    Intent.FLAG_ACTIVITY_NEW_TASK));
3711
3712            // Okay now we need to start the new activity, replacing the
3713            // currently running activity.  This is a little tricky because
3714            // we want to start the new one as if the current one is finished,
3715            // but not finish the current one first so that there is no flicker.
3716            // And thus...
3717            final boolean wasFinishing = r.finishing;
3718            r.finishing = true;
3719
3720            // Propagate reply information over to the new activity.
3721            final ActivityRecord resultTo = r.resultTo;
3722            final String resultWho = r.resultWho;
3723            final int requestCode = r.requestCode;
3724            r.resultTo = null;
3725            if (resultTo != null) {
3726                resultTo.removeResultsLocked(r, resultWho, requestCode);
3727            }
3728
3729            final long origId = Binder.clearCallingIdentity();
3730            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3731                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3732                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3733                    options, false, null, null, null);
3734            Binder.restoreCallingIdentity(origId);
3735
3736            r.finishing = wasFinishing;
3737            if (res != ActivityManager.START_SUCCESS) {
3738                return false;
3739            }
3740            return true;
3741        }
3742    }
3743
3744    @Override
3745    public final int startActivityFromRecents(int taskId, Bundle options) {
3746        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3747            String msg = "Permission Denial: startActivityFromRecents called without " +
3748                    START_TASKS_FROM_RECENTS;
3749            Slog.w(TAG, msg);
3750            throw new SecurityException(msg);
3751        }
3752        return startActivityFromRecentsInner(taskId, options);
3753    }
3754
3755    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3756        final TaskRecord task;
3757        final int callingUid;
3758        final String callingPackage;
3759        final Intent intent;
3760        final int userId;
3761        synchronized (this) {
3762            task = recentTaskForIdLocked(taskId);
3763            if (task == null) {
3764                throw new IllegalArgumentException("Task " + taskId + " not found.");
3765            }
3766            callingUid = task.mCallingUid;
3767            callingPackage = task.mCallingPackage;
3768            intent = task.intent;
3769            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3770            userId = task.userId;
3771        }
3772        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3773                options, userId, null, task);
3774    }
3775
3776    final int startActivityInPackage(int uid, String callingPackage,
3777            Intent intent, String resolvedType, IBinder resultTo,
3778            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3779            IActivityContainer container, TaskRecord inTask) {
3780
3781        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3782                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3783
3784        // TODO: Switch to user app stacks here.
3785        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3786                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3787                null, null, null, options, userId, container, inTask);
3788        return ret;
3789    }
3790
3791    @Override
3792    public final int startActivities(IApplicationThread caller, String callingPackage,
3793            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3794            int userId) {
3795        enforceNotIsolatedCaller("startActivities");
3796        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3797                false, ALLOW_FULL_ONLY, "startActivity", null);
3798        // TODO: Switch to user app stacks here.
3799        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3800                resolvedTypes, resultTo, options, userId);
3801        return ret;
3802    }
3803
3804    final int startActivitiesInPackage(int uid, String callingPackage,
3805            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3806            Bundle options, int userId) {
3807
3808        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3809                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3810        // TODO: Switch to user app stacks here.
3811        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3812                resultTo, options, userId);
3813        return ret;
3814    }
3815
3816    //explicitly remove thd old information in mRecentTasks when removing existing user.
3817    private void removeRecentTasksForUserLocked(int userId) {
3818        if(userId <= 0) {
3819            Slog.i(TAG, "Can't remove recent task on user " + userId);
3820            return;
3821        }
3822
3823        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3824            TaskRecord tr = mRecentTasks.get(i);
3825            if (tr.userId == userId) {
3826                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3827                        + " when finishing user" + userId);
3828                mRecentTasks.remove(i);
3829                tr.removedFromRecents(mTaskPersister);
3830            }
3831        }
3832
3833        // Remove tasks from persistent storage.
3834        mTaskPersister.wakeup(null, true);
3835    }
3836
3837    /**
3838     * Update the recent tasks lists: make sure tasks should still be here (their
3839     * applications / activities still exist), update their availability, fixup ordering
3840     * of affiliations.
3841     */
3842    void cleanupRecentTasksLocked(int userId) {
3843        if (mRecentTasks == null) {
3844            // Happens when called from the packagemanager broadcast before boot.
3845            return;
3846        }
3847
3848        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3849        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3850        final IPackageManager pm = AppGlobals.getPackageManager();
3851        final ActivityInfo dummyAct = new ActivityInfo();
3852        final ApplicationInfo dummyApp = new ApplicationInfo();
3853
3854        int N = mRecentTasks.size();
3855
3856        int[] users = userId == UserHandle.USER_ALL
3857                ? getUsersLocked() : new int[] { userId };
3858        for (int user : users) {
3859            for (int i = 0; i < N; i++) {
3860                TaskRecord task = mRecentTasks.get(i);
3861                if (task.userId != user) {
3862                    // Only look at tasks for the user ID of interest.
3863                    continue;
3864                }
3865                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3866                    // This situation is broken, and we should just get rid of it now.
3867                    mRecentTasks.remove(i);
3868                    task.removedFromRecents(mTaskPersister);
3869                    i--;
3870                    N--;
3871                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3872                    continue;
3873                }
3874                // Check whether this activity is currently available.
3875                if (task.realActivity != null) {
3876                    ActivityInfo ai = availActCache.get(task.realActivity);
3877                    if (ai == null) {
3878                        try {
3879                            ai = pm.getActivityInfo(task.realActivity,
3880                                    PackageManager.GET_UNINSTALLED_PACKAGES
3881                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3882                        } catch (RemoteException e) {
3883                            // Will never happen.
3884                            continue;
3885                        }
3886                        if (ai == null) {
3887                            ai = dummyAct;
3888                        }
3889                        availActCache.put(task.realActivity, ai);
3890                    }
3891                    if (ai == dummyAct) {
3892                        // This could be either because the activity no longer exists, or the
3893                        // app is temporarily gone.  For the former we want to remove the recents
3894                        // entry; for the latter we want to mark it as unavailable.
3895                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3896                        if (app == null) {
3897                            try {
3898                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3899                                        PackageManager.GET_UNINSTALLED_PACKAGES
3900                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3901                            } catch (RemoteException e) {
3902                                // Will never happen.
3903                                continue;
3904                            }
3905                            if (app == null) {
3906                                app = dummyApp;
3907                            }
3908                            availAppCache.put(task.realActivity.getPackageName(), app);
3909                        }
3910                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3911                            // Doesn't exist any more!  Good-bye.
3912                            mRecentTasks.remove(i);
3913                            task.removedFromRecents(mTaskPersister);
3914                            i--;
3915                            N--;
3916                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3917                            continue;
3918                        } else {
3919                            // Otherwise just not available for now.
3920                            if (task.isAvailable) {
3921                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3922                                        + task);
3923                            }
3924                            task.isAvailable = false;
3925                        }
3926                    } else {
3927                        if (!ai.enabled || !ai.applicationInfo.enabled
3928                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3929                            if (task.isAvailable) {
3930                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3931                                        + task + " (enabled=" + ai.enabled + "/"
3932                                        + ai.applicationInfo.enabled +  " flags="
3933                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3934                            }
3935                            task.isAvailable = false;
3936                        } else {
3937                            if (!task.isAvailable) {
3938                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3939                                        + task);
3940                            }
3941                            task.isAvailable = true;
3942                        }
3943                    }
3944                }
3945            }
3946        }
3947
3948        // Verify the affiliate chain for each task.
3949        for (int i = 0; i < N; ) {
3950            TaskRecord task = mRecentTasks.remove(i);
3951            if (mTmpRecents.contains(task)) {
3952                continue;
3953            }
3954            int affiliatedTaskId = task.mAffiliatedTaskId;
3955            while (true) {
3956                TaskRecord next = task.mNextAffiliate;
3957                if (next == null) {
3958                    break;
3959                }
3960                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3961                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3962                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3963                    task.setNextAffiliate(null);
3964                    if (next.mPrevAffiliate == task) {
3965                        next.setPrevAffiliate(null);
3966                    }
3967                    break;
3968                }
3969                if (next.mPrevAffiliate != task) {
3970                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3971                            next.mPrevAffiliate + " task=" + task);
3972                    next.setPrevAffiliate(null);
3973                    task.setNextAffiliate(null);
3974                    break;
3975                }
3976                if (!mRecentTasks.contains(next)) {
3977                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3978                    task.setNextAffiliate(null);
3979                    // We know that next.mPrevAffiliate is always task, from above, so clear
3980                    // its previous affiliate.
3981                    next.setPrevAffiliate(null);
3982                    break;
3983                }
3984                task = next;
3985            }
3986            // task is now the end of the list
3987            do {
3988                mRecentTasks.remove(task);
3989                mRecentTasks.add(i++, task);
3990                mTmpRecents.add(task);
3991                task.inRecents = true;
3992            } while ((task = task.mPrevAffiliate) != null);
3993        }
3994        mTmpRecents.clear();
3995        // mRecentTasks is now in sorted, affiliated order.
3996    }
3997
3998    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3999        int N = mRecentTasks.size();
4000        TaskRecord top = task;
4001        int topIndex = taskIndex;
4002        while (top.mNextAffiliate != null && topIndex > 0) {
4003            top = top.mNextAffiliate;
4004            topIndex--;
4005        }
4006        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4007                + topIndex + " from intial " + taskIndex);
4008        // Find the end of the chain, doing a sanity check along the way.
4009        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4010        int endIndex = topIndex;
4011        TaskRecord prev = top;
4012        while (endIndex < N) {
4013            TaskRecord cur = mRecentTasks.get(endIndex);
4014            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4015                    + endIndex + " " + cur);
4016            if (cur == top) {
4017                // Verify start of the chain.
4018                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4019                    Slog.wtf(TAG, "Bad chain @" + endIndex
4020                            + ": first task has next affiliate: " + prev);
4021                    sane = false;
4022                    break;
4023                }
4024            } else {
4025                // Verify middle of the chain's next points back to the one before.
4026                if (cur.mNextAffiliate != prev
4027                        || cur.mNextAffiliateTaskId != prev.taskId) {
4028                    Slog.wtf(TAG, "Bad chain @" + endIndex
4029                            + ": middle task " + cur + " @" + endIndex
4030                            + " has bad next affiliate "
4031                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4032                            + ", expected " + prev);
4033                    sane = false;
4034                    break;
4035                }
4036            }
4037            if (cur.mPrevAffiliateTaskId == -1) {
4038                // Chain ends here.
4039                if (cur.mPrevAffiliate != null) {
4040                    Slog.wtf(TAG, "Bad chain @" + endIndex
4041                            + ": last task " + cur + " has previous affiliate "
4042                            + cur.mPrevAffiliate);
4043                    sane = false;
4044                }
4045                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4046                break;
4047            } else {
4048                // Verify middle of the chain's prev points to a valid item.
4049                if (cur.mPrevAffiliate == null) {
4050                    Slog.wtf(TAG, "Bad chain @" + endIndex
4051                            + ": task " + cur + " has previous affiliate "
4052                            + cur.mPrevAffiliate + " but should be id "
4053                            + cur.mPrevAffiliate);
4054                    sane = false;
4055                    break;
4056                }
4057            }
4058            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4059                Slog.wtf(TAG, "Bad chain @" + endIndex
4060                        + ": task " + cur + " has affiliated id "
4061                        + cur.mAffiliatedTaskId + " but should be "
4062                        + task.mAffiliatedTaskId);
4063                sane = false;
4064                break;
4065            }
4066            prev = cur;
4067            endIndex++;
4068            if (endIndex >= N) {
4069                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4070                        + ": last task " + prev);
4071                sane = false;
4072                break;
4073            }
4074        }
4075        if (sane) {
4076            if (endIndex < taskIndex) {
4077                Slog.wtf(TAG, "Bad chain @" + endIndex
4078                        + ": did not extend to task " + task + " @" + taskIndex);
4079                sane = false;
4080            }
4081        }
4082        if (sane) {
4083            // All looks good, we can just move all of the affiliated tasks
4084            // to the top.
4085            for (int i=topIndex; i<=endIndex; i++) {
4086                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4087                        + " from " + i + " to " + (i-topIndex));
4088                TaskRecord cur = mRecentTasks.remove(i);
4089                mRecentTasks.add(i-topIndex, cur);
4090            }
4091            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4092                    + " to " + endIndex);
4093            return true;
4094        }
4095
4096        // Whoops, couldn't do it.
4097        return false;
4098    }
4099
4100    final void addRecentTaskLocked(TaskRecord task) {
4101        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4102                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4103
4104        int N = mRecentTasks.size();
4105        // Quick case: check if the top-most recent task is the same.
4106        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4107            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4108            return;
4109        }
4110        // Another quick case: check if this is part of a set of affiliated
4111        // tasks that are at the top.
4112        if (isAffiliated && N > 0 && task.inRecents
4113                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4114            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4115                    + " at top when adding " + task);
4116            return;
4117        }
4118        // Another quick case: never add voice sessions.
4119        if (task.voiceSession != null) {
4120            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4121            return;
4122        }
4123
4124        boolean needAffiliationFix = false;
4125
4126        // Slightly less quick case: the task is already in recents, so all we need
4127        // to do is move it.
4128        if (task.inRecents) {
4129            int taskIndex = mRecentTasks.indexOf(task);
4130            if (taskIndex >= 0) {
4131                if (!isAffiliated) {
4132                    // Simple case: this is not an affiliated task, so we just move it to the front.
4133                    mRecentTasks.remove(taskIndex);
4134                    mRecentTasks.add(0, task);
4135                    notifyTaskPersisterLocked(task, false);
4136                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4137                            + " from " + taskIndex);
4138                    return;
4139                } else {
4140                    // More complicated: need to keep all affiliated tasks together.
4141                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4142                        // All went well.
4143                        return;
4144                    }
4145
4146                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4147                    // everything and then go through our general path of adding a new task.
4148                    needAffiliationFix = true;
4149                }
4150            } else {
4151                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4152                needAffiliationFix = true;
4153            }
4154        }
4155
4156        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4157        trimRecentsForTask(task, true);
4158
4159        N = mRecentTasks.size();
4160        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4161            final TaskRecord tr = mRecentTasks.remove(N - 1);
4162            tr.removedFromRecents(mTaskPersister);
4163            N--;
4164        }
4165        task.inRecents = true;
4166        if (!isAffiliated || needAffiliationFix) {
4167            // If this is a simple non-affiliated task, or we had some failure trying to
4168            // handle it as part of an affilated task, then just place it at the top.
4169            mRecentTasks.add(0, task);
4170        } else if (isAffiliated) {
4171            // If this is a new affiliated task, then move all of the affiliated tasks
4172            // to the front and insert this new one.
4173            TaskRecord other = task.mNextAffiliate;
4174            if (other == null) {
4175                other = task.mPrevAffiliate;
4176            }
4177            if (other != null) {
4178                int otherIndex = mRecentTasks.indexOf(other);
4179                if (otherIndex >= 0) {
4180                    // Insert new task at appropriate location.
4181                    int taskIndex;
4182                    if (other == task.mNextAffiliate) {
4183                        // We found the index of our next affiliation, which is who is
4184                        // before us in the list, so add after that point.
4185                        taskIndex = otherIndex+1;
4186                    } else {
4187                        // We found the index of our previous affiliation, which is who is
4188                        // after us in the list, so add at their position.
4189                        taskIndex = otherIndex;
4190                    }
4191                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4192                            + taskIndex + ": " + task);
4193                    mRecentTasks.add(taskIndex, task);
4194
4195                    // Now move everything to the front.
4196                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4197                        // All went well.
4198                        return;
4199                    }
4200
4201                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4202                    // everything and then go through our general path of adding a new task.
4203                    needAffiliationFix = true;
4204                } else {
4205                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4206                            + other);
4207                    needAffiliationFix = true;
4208                }
4209            } else {
4210                if (DEBUG_RECENTS) Slog.d(TAG,
4211                        "addRecent: adding affiliated task without next/prev:" + task);
4212                needAffiliationFix = true;
4213            }
4214        }
4215        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4216
4217        if (needAffiliationFix) {
4218            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4219            cleanupRecentTasksLocked(task.userId);
4220        }
4221    }
4222
4223    /**
4224     * If needed, remove oldest existing entries in recents that are for the same kind
4225     * of task as the given one.
4226     */
4227    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4228        int N = mRecentTasks.size();
4229        final Intent intent = task.intent;
4230        final boolean document = intent != null && intent.isDocument();
4231
4232        int maxRecents = task.maxRecents - 1;
4233        for (int i=0; i<N; i++) {
4234            final TaskRecord tr = mRecentTasks.get(i);
4235            if (task != tr) {
4236                if (task.userId != tr.userId) {
4237                    continue;
4238                }
4239                if (i > MAX_RECENT_BITMAPS) {
4240                    tr.freeLastThumbnail();
4241                }
4242                final Intent trIntent = tr.intent;
4243                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4244                    (intent == null || !intent.filterEquals(trIntent))) {
4245                    continue;
4246                }
4247                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4248                if (document && trIsDocument) {
4249                    // These are the same document activity (not necessarily the same doc).
4250                    if (maxRecents > 0) {
4251                        --maxRecents;
4252                        continue;
4253                    }
4254                    // Hit the maximum number of documents for this task. Fall through
4255                    // and remove this document from recents.
4256                } else if (document || trIsDocument) {
4257                    // Only one of these is a document. Not the droid we're looking for.
4258                    continue;
4259                }
4260            }
4261
4262            if (!doTrim) {
4263                // If the caller is not actually asking for a trim, just tell them we reached
4264                // a point where the trim would happen.
4265                return i;
4266            }
4267
4268            // Either task and tr are the same or, their affinities match or their intents match
4269            // and neither of them is a document, or they are documents using the same activity
4270            // and their maxRecents has been reached.
4271            tr.disposeThumbnail();
4272            mRecentTasks.remove(i);
4273            if (task != tr) {
4274                tr.removedFromRecents(mTaskPersister);
4275            }
4276            i--;
4277            N--;
4278            if (task.intent == null) {
4279                // If the new recent task we are adding is not fully
4280                // specified, then replace it with the existing recent task.
4281                task = tr;
4282            }
4283            notifyTaskPersisterLocked(tr, false);
4284        }
4285
4286        return -1;
4287    }
4288
4289    @Override
4290    public void reportActivityFullyDrawn(IBinder token) {
4291        synchronized (this) {
4292            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4293            if (r == null) {
4294                return;
4295            }
4296            r.reportFullyDrawnLocked();
4297        }
4298    }
4299
4300    @Override
4301    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4302        synchronized (this) {
4303            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4304            if (r == null) {
4305                return;
4306            }
4307            final long origId = Binder.clearCallingIdentity();
4308            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4309            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4310                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4311            if (config != null) {
4312                r.frozenBeforeDestroy = true;
4313                if (!updateConfigurationLocked(config, r, false, false)) {
4314                    mStackSupervisor.resumeTopActivitiesLocked();
4315                }
4316            }
4317            Binder.restoreCallingIdentity(origId);
4318        }
4319    }
4320
4321    @Override
4322    public int getRequestedOrientation(IBinder token) {
4323        synchronized (this) {
4324            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4325            if (r == null) {
4326                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4327            }
4328            return mWindowManager.getAppOrientation(r.appToken);
4329        }
4330    }
4331
4332    /**
4333     * This is the internal entry point for handling Activity.finish().
4334     *
4335     * @param token The Binder token referencing the Activity we want to finish.
4336     * @param resultCode Result code, if any, from this Activity.
4337     * @param resultData Result data (Intent), if any, from this Activity.
4338     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4339     *            the root Activity in the task.
4340     *
4341     * @return Returns true if the activity successfully finished, or false if it is still running.
4342     */
4343    @Override
4344    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4345            boolean finishTask) {
4346        // Refuse possible leaked file descriptors
4347        if (resultData != null && resultData.hasFileDescriptors() == true) {
4348            throw new IllegalArgumentException("File descriptors passed in Intent");
4349        }
4350
4351        synchronized(this) {
4352            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4353            if (r == null) {
4354                return true;
4355            }
4356            // Keep track of the root activity of the task before we finish it
4357            TaskRecord tr = r.task;
4358            ActivityRecord rootR = tr.getRootActivity();
4359            // Do not allow task to finish in Lock Task mode.
4360            if (tr == mStackSupervisor.mLockTaskModeTask) {
4361                if (rootR == r) {
4362                    mStackSupervisor.showLockTaskToast();
4363                    return false;
4364                }
4365            }
4366            if (mController != null) {
4367                // Find the first activity that is not finishing.
4368                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4369                if (next != null) {
4370                    // ask watcher if this is allowed
4371                    boolean resumeOK = true;
4372                    try {
4373                        resumeOK = mController.activityResuming(next.packageName);
4374                    } catch (RemoteException e) {
4375                        mController = null;
4376                        Watchdog.getInstance().setActivityController(null);
4377                    }
4378
4379                    if (!resumeOK) {
4380                        return false;
4381                    }
4382                }
4383            }
4384            final long origId = Binder.clearCallingIdentity();
4385            try {
4386                boolean res;
4387                if (finishTask && r == rootR) {
4388                    // If requested, remove the task that is associated to this activity only if it
4389                    // was the root activity in the task.  The result code and data is ignored because
4390                    // we don't support returning them across task boundaries.
4391                    res = removeTaskByIdLocked(tr.taskId, 0);
4392                } else {
4393                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4394                            resultData, "app-request", true);
4395                }
4396                return res;
4397            } finally {
4398                Binder.restoreCallingIdentity(origId);
4399            }
4400        }
4401    }
4402
4403    @Override
4404    public final void finishHeavyWeightApp() {
4405        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4406                != PackageManager.PERMISSION_GRANTED) {
4407            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4408                    + Binder.getCallingPid()
4409                    + ", uid=" + Binder.getCallingUid()
4410                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4411            Slog.w(TAG, msg);
4412            throw new SecurityException(msg);
4413        }
4414
4415        synchronized(this) {
4416            if (mHeavyWeightProcess == null) {
4417                return;
4418            }
4419
4420            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4421                    mHeavyWeightProcess.activities);
4422            for (int i=0; i<activities.size(); i++) {
4423                ActivityRecord r = activities.get(i);
4424                if (!r.finishing) {
4425                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4426                            null, "finish-heavy", true);
4427                }
4428            }
4429
4430            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4431                    mHeavyWeightProcess.userId, 0));
4432            mHeavyWeightProcess = null;
4433        }
4434    }
4435
4436    @Override
4437    public void crashApplication(int uid, int initialPid, String packageName,
4438            String message) {
4439        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4440                != PackageManager.PERMISSION_GRANTED) {
4441            String msg = "Permission Denial: crashApplication() from pid="
4442                    + Binder.getCallingPid()
4443                    + ", uid=" + Binder.getCallingUid()
4444                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4445            Slog.w(TAG, msg);
4446            throw new SecurityException(msg);
4447        }
4448
4449        synchronized(this) {
4450            ProcessRecord proc = null;
4451
4452            // Figure out which process to kill.  We don't trust that initialPid
4453            // still has any relation to current pids, so must scan through the
4454            // list.
4455            synchronized (mPidsSelfLocked) {
4456                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4457                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4458                    if (p.uid != uid) {
4459                        continue;
4460                    }
4461                    if (p.pid == initialPid) {
4462                        proc = p;
4463                        break;
4464                    }
4465                    if (p.pkgList.containsKey(packageName)) {
4466                        proc = p;
4467                    }
4468                }
4469            }
4470
4471            if (proc == null) {
4472                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4473                        + " initialPid=" + initialPid
4474                        + " packageName=" + packageName);
4475                return;
4476            }
4477
4478            if (proc.thread != null) {
4479                if (proc.pid == Process.myPid()) {
4480                    Log.w(TAG, "crashApplication: trying to crash self!");
4481                    return;
4482                }
4483                long ident = Binder.clearCallingIdentity();
4484                try {
4485                    proc.thread.scheduleCrash(message);
4486                } catch (RemoteException e) {
4487                }
4488                Binder.restoreCallingIdentity(ident);
4489            }
4490        }
4491    }
4492
4493    @Override
4494    public final void finishSubActivity(IBinder token, String resultWho,
4495            int requestCode) {
4496        synchronized(this) {
4497            final long origId = Binder.clearCallingIdentity();
4498            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4499            if (r != null) {
4500                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4501            }
4502            Binder.restoreCallingIdentity(origId);
4503        }
4504    }
4505
4506    @Override
4507    public boolean finishActivityAffinity(IBinder token) {
4508        synchronized(this) {
4509            final long origId = Binder.clearCallingIdentity();
4510            try {
4511                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4512
4513                ActivityRecord rootR = r.task.getRootActivity();
4514                // Do not allow task to finish in Lock Task mode.
4515                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4516                    if (rootR == r) {
4517                        mStackSupervisor.showLockTaskToast();
4518                        return false;
4519                    }
4520                }
4521                boolean res = false;
4522                if (r != null) {
4523                    res = r.task.stack.finishActivityAffinityLocked(r);
4524                }
4525                return res;
4526            } finally {
4527                Binder.restoreCallingIdentity(origId);
4528            }
4529        }
4530    }
4531
4532    @Override
4533    public void finishVoiceTask(IVoiceInteractionSession session) {
4534        synchronized(this) {
4535            final long origId = Binder.clearCallingIdentity();
4536            try {
4537                mStackSupervisor.finishVoiceTask(session);
4538            } finally {
4539                Binder.restoreCallingIdentity(origId);
4540            }
4541        }
4542
4543    }
4544
4545    @Override
4546    public boolean releaseActivityInstance(IBinder token) {
4547        synchronized(this) {
4548            final long origId = Binder.clearCallingIdentity();
4549            try {
4550                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4551                if (r.task == null || r.task.stack == null) {
4552                    return false;
4553                }
4554                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4555            } finally {
4556                Binder.restoreCallingIdentity(origId);
4557            }
4558        }
4559    }
4560
4561    @Override
4562    public void releaseSomeActivities(IApplicationThread appInt) {
4563        synchronized(this) {
4564            final long origId = Binder.clearCallingIdentity();
4565            try {
4566                ProcessRecord app = getRecordForAppLocked(appInt);
4567                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4568            } finally {
4569                Binder.restoreCallingIdentity(origId);
4570            }
4571        }
4572    }
4573
4574    @Override
4575    public boolean willActivityBeVisible(IBinder token) {
4576        synchronized(this) {
4577            ActivityStack stack = ActivityRecord.getStackLocked(token);
4578            if (stack != null) {
4579                return stack.willActivityBeVisibleLocked(token);
4580            }
4581            return false;
4582        }
4583    }
4584
4585    @Override
4586    public void overridePendingTransition(IBinder token, String packageName,
4587            int enterAnim, int exitAnim) {
4588        synchronized(this) {
4589            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4590            if (self == null) {
4591                return;
4592            }
4593
4594            final long origId = Binder.clearCallingIdentity();
4595
4596            if (self.state == ActivityState.RESUMED
4597                    || self.state == ActivityState.PAUSING) {
4598                mWindowManager.overridePendingAppTransition(packageName,
4599                        enterAnim, exitAnim, null);
4600            }
4601
4602            Binder.restoreCallingIdentity(origId);
4603        }
4604    }
4605
4606    /**
4607     * Main function for removing an existing process from the activity manager
4608     * as a result of that process going away.  Clears out all connections
4609     * to the process.
4610     */
4611    private final void handleAppDiedLocked(ProcessRecord app,
4612            boolean restarting, boolean allowRestart) {
4613        int pid = app.pid;
4614        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4615        if (!restarting) {
4616            removeLruProcessLocked(app);
4617            if (pid > 0) {
4618                ProcessList.remove(pid);
4619            }
4620        }
4621
4622        if (mProfileProc == app) {
4623            clearProfilerLocked();
4624        }
4625
4626        // Remove this application's activities from active lists.
4627        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4628
4629        app.activities.clear();
4630
4631        if (app.instrumentationClass != null) {
4632            Slog.w(TAG, "Crash of app " + app.processName
4633                  + " running instrumentation " + app.instrumentationClass);
4634            Bundle info = new Bundle();
4635            info.putString("shortMsg", "Process crashed.");
4636            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4637        }
4638
4639        if (!restarting) {
4640            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4641                // If there was nothing to resume, and we are not already
4642                // restarting this process, but there is a visible activity that
4643                // is hosted by the process...  then make sure all visible
4644                // activities are running, taking care of restarting this
4645                // process.
4646                if (hasVisibleActivities) {
4647                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4648                }
4649            }
4650        }
4651    }
4652
4653    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4654        IBinder threadBinder = thread.asBinder();
4655        // Find the application record.
4656        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4657            ProcessRecord rec = mLruProcesses.get(i);
4658            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4659                return i;
4660            }
4661        }
4662        return -1;
4663    }
4664
4665    final ProcessRecord getRecordForAppLocked(
4666            IApplicationThread thread) {
4667        if (thread == null) {
4668            return null;
4669        }
4670
4671        int appIndex = getLRURecordIndexForAppLocked(thread);
4672        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4673    }
4674
4675    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4676        // If there are no longer any background processes running,
4677        // and the app that died was not running instrumentation,
4678        // then tell everyone we are now low on memory.
4679        boolean haveBg = false;
4680        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4681            ProcessRecord rec = mLruProcesses.get(i);
4682            if (rec.thread != null
4683                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4684                haveBg = true;
4685                break;
4686            }
4687        }
4688
4689        if (!haveBg) {
4690            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4691            if (doReport) {
4692                long now = SystemClock.uptimeMillis();
4693                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4694                    doReport = false;
4695                } else {
4696                    mLastMemUsageReportTime = now;
4697                }
4698            }
4699            final ArrayList<ProcessMemInfo> memInfos
4700                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4701            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4702            long now = SystemClock.uptimeMillis();
4703            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4704                ProcessRecord rec = mLruProcesses.get(i);
4705                if (rec == dyingProc || rec.thread == null) {
4706                    continue;
4707                }
4708                if (doReport) {
4709                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4710                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4711                }
4712                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4713                    // The low memory report is overriding any current
4714                    // state for a GC request.  Make sure to do
4715                    // heavy/important/visible/foreground processes first.
4716                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4717                        rec.lastRequestedGc = 0;
4718                    } else {
4719                        rec.lastRequestedGc = rec.lastLowMemory;
4720                    }
4721                    rec.reportLowMemory = true;
4722                    rec.lastLowMemory = now;
4723                    mProcessesToGc.remove(rec);
4724                    addProcessToGcListLocked(rec);
4725                }
4726            }
4727            if (doReport) {
4728                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4729                mHandler.sendMessage(msg);
4730            }
4731            scheduleAppGcsLocked();
4732        }
4733    }
4734
4735    final void appDiedLocked(ProcessRecord app) {
4736       appDiedLocked(app, app.pid, app.thread);
4737    }
4738
4739    final void appDiedLocked(ProcessRecord app, int pid,
4740            IApplicationThread thread) {
4741
4742        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4743        synchronized (stats) {
4744            stats.noteProcessDiedLocked(app.info.uid, pid);
4745        }
4746
4747        Process.killProcessGroup(app.info.uid, pid);
4748
4749        // Clean up already done if the process has been re-started.
4750        if (app.pid == pid && app.thread != null &&
4751                app.thread.asBinder() == thread.asBinder()) {
4752            boolean doLowMem = app.instrumentationClass == null;
4753            boolean doOomAdj = doLowMem;
4754            if (!app.killedByAm) {
4755                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4756                        + ") has died.");
4757                mAllowLowerMemLevel = true;
4758            } else {
4759                // Note that we always want to do oom adj to update our state with the
4760                // new number of procs.
4761                mAllowLowerMemLevel = false;
4762                doLowMem = false;
4763            }
4764            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4765            if (DEBUG_CLEANUP) Slog.v(
4766                TAG, "Dying app: " + app + ", pid: " + pid
4767                + ", thread: " + thread.asBinder());
4768            handleAppDiedLocked(app, false, true);
4769
4770            if (doOomAdj) {
4771                updateOomAdjLocked();
4772            }
4773            if (doLowMem) {
4774                doLowMemReportIfNeededLocked(app);
4775            }
4776        } else if (app.pid != pid) {
4777            // A new process has already been started.
4778            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4779                    + ") has died and restarted (pid " + app.pid + ").");
4780            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4781        } else if (DEBUG_PROCESSES) {
4782            Slog.d(TAG, "Received spurious death notification for thread "
4783                    + thread.asBinder());
4784        }
4785    }
4786
4787    /**
4788     * If a stack trace dump file is configured, dump process stack traces.
4789     * @param clearTraces causes the dump file to be erased prior to the new
4790     *    traces being written, if true; when false, the new traces will be
4791     *    appended to any existing file content.
4792     * @param firstPids of dalvik VM processes to dump stack traces for first
4793     * @param lastPids of dalvik VM processes to dump stack traces for last
4794     * @param nativeProcs optional list of native process names to dump stack crawls
4795     * @return file containing stack traces, or null if no dump file is configured
4796     */
4797    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4798            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4799        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4800        if (tracesPath == null || tracesPath.length() == 0) {
4801            return null;
4802        }
4803
4804        File tracesFile = new File(tracesPath);
4805        try {
4806            File tracesDir = tracesFile.getParentFile();
4807            if (!tracesDir.exists()) {
4808                tracesFile.mkdirs();
4809                if (!SELinux.restorecon(tracesDir)) {
4810                    return null;
4811                }
4812            }
4813            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4814
4815            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4816            tracesFile.createNewFile();
4817            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4818        } catch (IOException e) {
4819            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4820            return null;
4821        }
4822
4823        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4824        return tracesFile;
4825    }
4826
4827    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4828            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4829        // Use a FileObserver to detect when traces finish writing.
4830        // The order of traces is considered important to maintain for legibility.
4831        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4832            @Override
4833            public synchronized void onEvent(int event, String path) { notify(); }
4834        };
4835
4836        try {
4837            observer.startWatching();
4838
4839            // First collect all of the stacks of the most important pids.
4840            if (firstPids != null) {
4841                try {
4842                    int num = firstPids.size();
4843                    for (int i = 0; i < num; i++) {
4844                        synchronized (observer) {
4845                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4846                            observer.wait(200);  // Wait for write-close, give up after 200msec
4847                        }
4848                    }
4849                } catch (InterruptedException e) {
4850                    Log.wtf(TAG, e);
4851                }
4852            }
4853
4854            // Next collect the stacks of the native pids
4855            if (nativeProcs != null) {
4856                int[] pids = Process.getPidsForCommands(nativeProcs);
4857                if (pids != null) {
4858                    for (int pid : pids) {
4859                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4860                    }
4861                }
4862            }
4863
4864            // Lastly, measure CPU usage.
4865            if (processCpuTracker != null) {
4866                processCpuTracker.init();
4867                System.gc();
4868                processCpuTracker.update();
4869                try {
4870                    synchronized (processCpuTracker) {
4871                        processCpuTracker.wait(500); // measure over 1/2 second.
4872                    }
4873                } catch (InterruptedException e) {
4874                }
4875                processCpuTracker.update();
4876
4877                // We'll take the stack crawls of just the top apps using CPU.
4878                final int N = processCpuTracker.countWorkingStats();
4879                int numProcs = 0;
4880                for (int i=0; i<N && numProcs<5; i++) {
4881                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4882                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4883                        numProcs++;
4884                        try {
4885                            synchronized (observer) {
4886                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4887                                observer.wait(200);  // Wait for write-close, give up after 200msec
4888                            }
4889                        } catch (InterruptedException e) {
4890                            Log.wtf(TAG, e);
4891                        }
4892
4893                    }
4894                }
4895            }
4896        } finally {
4897            observer.stopWatching();
4898        }
4899    }
4900
4901    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4902        if (true || IS_USER_BUILD) {
4903            return;
4904        }
4905        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4906        if (tracesPath == null || tracesPath.length() == 0) {
4907            return;
4908        }
4909
4910        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4911        StrictMode.allowThreadDiskWrites();
4912        try {
4913            final File tracesFile = new File(tracesPath);
4914            final File tracesDir = tracesFile.getParentFile();
4915            final File tracesTmp = new File(tracesDir, "__tmp__");
4916            try {
4917                if (!tracesDir.exists()) {
4918                    tracesFile.mkdirs();
4919                    if (!SELinux.restorecon(tracesDir.getPath())) {
4920                        return;
4921                    }
4922                }
4923                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4924
4925                if (tracesFile.exists()) {
4926                    tracesTmp.delete();
4927                    tracesFile.renameTo(tracesTmp);
4928                }
4929                StringBuilder sb = new StringBuilder();
4930                Time tobj = new Time();
4931                tobj.set(System.currentTimeMillis());
4932                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4933                sb.append(": ");
4934                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4935                sb.append(" since ");
4936                sb.append(msg);
4937                FileOutputStream fos = new FileOutputStream(tracesFile);
4938                fos.write(sb.toString().getBytes());
4939                if (app == null) {
4940                    fos.write("\n*** No application process!".getBytes());
4941                }
4942                fos.close();
4943                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4944            } catch (IOException e) {
4945                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4946                return;
4947            }
4948
4949            if (app != null) {
4950                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4951                firstPids.add(app.pid);
4952                dumpStackTraces(tracesPath, firstPids, null, null, null);
4953            }
4954
4955            File lastTracesFile = null;
4956            File curTracesFile = null;
4957            for (int i=9; i>=0; i--) {
4958                String name = String.format(Locale.US, "slow%02d.txt", i);
4959                curTracesFile = new File(tracesDir, name);
4960                if (curTracesFile.exists()) {
4961                    if (lastTracesFile != null) {
4962                        curTracesFile.renameTo(lastTracesFile);
4963                    } else {
4964                        curTracesFile.delete();
4965                    }
4966                }
4967                lastTracesFile = curTracesFile;
4968            }
4969            tracesFile.renameTo(curTracesFile);
4970            if (tracesTmp.exists()) {
4971                tracesTmp.renameTo(tracesFile);
4972            }
4973        } finally {
4974            StrictMode.setThreadPolicy(oldPolicy);
4975        }
4976    }
4977
4978    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4979            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4980        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4981        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4982
4983        if (mController != null) {
4984            try {
4985                // 0 == continue, -1 = kill process immediately
4986                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4987                if (res < 0 && app.pid != MY_PID) {
4988                    app.kill("anr", true);
4989                }
4990            } catch (RemoteException e) {
4991                mController = null;
4992                Watchdog.getInstance().setActivityController(null);
4993            }
4994        }
4995
4996        long anrTime = SystemClock.uptimeMillis();
4997        if (MONITOR_CPU_USAGE) {
4998            updateCpuStatsNow();
4999        }
5000
5001        synchronized (this) {
5002            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5003            if (mShuttingDown) {
5004                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5005                return;
5006            } else if (app.notResponding) {
5007                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5008                return;
5009            } else if (app.crashing) {
5010                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5011                return;
5012            }
5013
5014            // In case we come through here for the same app before completing
5015            // this one, mark as anring now so we will bail out.
5016            app.notResponding = true;
5017
5018            // Log the ANR to the event log.
5019            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5020                    app.processName, app.info.flags, annotation);
5021
5022            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5023            firstPids.add(app.pid);
5024
5025            int parentPid = app.pid;
5026            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5027            if (parentPid != app.pid) firstPids.add(parentPid);
5028
5029            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5030
5031            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5032                ProcessRecord r = mLruProcesses.get(i);
5033                if (r != null && r.thread != null) {
5034                    int pid = r.pid;
5035                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5036                        if (r.persistent) {
5037                            firstPids.add(pid);
5038                        } else {
5039                            lastPids.put(pid, Boolean.TRUE);
5040                        }
5041                    }
5042                }
5043            }
5044        }
5045
5046        // Log the ANR to the main log.
5047        StringBuilder info = new StringBuilder();
5048        info.setLength(0);
5049        info.append("ANR in ").append(app.processName);
5050        if (activity != null && activity.shortComponentName != null) {
5051            info.append(" (").append(activity.shortComponentName).append(")");
5052        }
5053        info.append("\n");
5054        info.append("PID: ").append(app.pid).append("\n");
5055        if (annotation != null) {
5056            info.append("Reason: ").append(annotation).append("\n");
5057        }
5058        if (parent != null && parent != activity) {
5059            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5060        }
5061
5062        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5063
5064        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5065                NATIVE_STACKS_OF_INTEREST);
5066
5067        String cpuInfo = null;
5068        if (MONITOR_CPU_USAGE) {
5069            updateCpuStatsNow();
5070            synchronized (mProcessCpuThread) {
5071                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5072            }
5073            info.append(processCpuTracker.printCurrentLoad());
5074            info.append(cpuInfo);
5075        }
5076
5077        info.append(processCpuTracker.printCurrentState(anrTime));
5078
5079        Slog.e(TAG, info.toString());
5080        if (tracesFile == null) {
5081            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5082            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5083        }
5084
5085        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5086                cpuInfo, tracesFile, null);
5087
5088        if (mController != null) {
5089            try {
5090                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5091                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5092                if (res != 0) {
5093                    if (res < 0 && app.pid != MY_PID) {
5094                        app.kill("anr", true);
5095                    } else {
5096                        synchronized (this) {
5097                            mServices.scheduleServiceTimeoutLocked(app);
5098                        }
5099                    }
5100                    return;
5101                }
5102            } catch (RemoteException e) {
5103                mController = null;
5104                Watchdog.getInstance().setActivityController(null);
5105            }
5106        }
5107
5108        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5109        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5110                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5111
5112        synchronized (this) {
5113            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5114                app.kill("bg anr", true);
5115                return;
5116            }
5117
5118            // Set the app's notResponding state, and look up the errorReportReceiver
5119            makeAppNotRespondingLocked(app,
5120                    activity != null ? activity.shortComponentName : null,
5121                    annotation != null ? "ANR " + annotation : "ANR",
5122                    info.toString());
5123
5124            // Bring up the infamous App Not Responding dialog
5125            Message msg = Message.obtain();
5126            HashMap<String, Object> map = new HashMap<String, Object>();
5127            msg.what = SHOW_NOT_RESPONDING_MSG;
5128            msg.obj = map;
5129            msg.arg1 = aboveSystem ? 1 : 0;
5130            map.put("app", app);
5131            if (activity != null) {
5132                map.put("activity", activity);
5133            }
5134
5135            mHandler.sendMessage(msg);
5136        }
5137    }
5138
5139    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5140        if (!mLaunchWarningShown) {
5141            mLaunchWarningShown = true;
5142            mHandler.post(new Runnable() {
5143                @Override
5144                public void run() {
5145                    synchronized (ActivityManagerService.this) {
5146                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5147                        d.show();
5148                        mHandler.postDelayed(new Runnable() {
5149                            @Override
5150                            public void run() {
5151                                synchronized (ActivityManagerService.this) {
5152                                    d.dismiss();
5153                                    mLaunchWarningShown = false;
5154                                }
5155                            }
5156                        }, 4000);
5157                    }
5158                }
5159            });
5160        }
5161    }
5162
5163    @Override
5164    public boolean clearApplicationUserData(final String packageName,
5165            final IPackageDataObserver observer, int userId) {
5166        enforceNotIsolatedCaller("clearApplicationUserData");
5167        int uid = Binder.getCallingUid();
5168        int pid = Binder.getCallingPid();
5169        userId = handleIncomingUser(pid, uid,
5170                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5171        long callingId = Binder.clearCallingIdentity();
5172        try {
5173            IPackageManager pm = AppGlobals.getPackageManager();
5174            int pkgUid = -1;
5175            synchronized(this) {
5176                try {
5177                    pkgUid = pm.getPackageUid(packageName, userId);
5178                } catch (RemoteException e) {
5179                }
5180                if (pkgUid == -1) {
5181                    Slog.w(TAG, "Invalid packageName: " + packageName);
5182                    if (observer != null) {
5183                        try {
5184                            observer.onRemoveCompleted(packageName, false);
5185                        } catch (RemoteException e) {
5186                            Slog.i(TAG, "Observer no longer exists.");
5187                        }
5188                    }
5189                    return false;
5190                }
5191                if (uid == pkgUid || checkComponentPermission(
5192                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5193                        pid, uid, -1, true)
5194                        == PackageManager.PERMISSION_GRANTED) {
5195                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5196                } else {
5197                    throw new SecurityException("PID " + pid + " does not have permission "
5198                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5199                                    + " of package " + packageName);
5200                }
5201
5202                // Remove all tasks match the cleared application package and user
5203                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5204                    final TaskRecord tr = mRecentTasks.get(i);
5205                    final String taskPackageName =
5206                            tr.getBaseIntent().getComponent().getPackageName();
5207                    if (tr.userId != userId) continue;
5208                    if (!taskPackageName.equals(packageName)) continue;
5209                    removeTaskByIdLocked(tr.taskId, 0);
5210                }
5211            }
5212
5213            try {
5214                // Clear application user data
5215                pm.clearApplicationUserData(packageName, observer, userId);
5216
5217                synchronized(this) {
5218                    // Remove all permissions granted from/to this package
5219                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5220                }
5221
5222                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5223                        Uri.fromParts("package", packageName, null));
5224                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5225                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5226                        null, null, 0, null, null, null, false, false, userId);
5227            } catch (RemoteException e) {
5228            }
5229        } finally {
5230            Binder.restoreCallingIdentity(callingId);
5231        }
5232        return true;
5233    }
5234
5235    @Override
5236    public void killBackgroundProcesses(final String packageName, int userId) {
5237        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5238                != PackageManager.PERMISSION_GRANTED &&
5239                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5240                        != PackageManager.PERMISSION_GRANTED) {
5241            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5242                    + Binder.getCallingPid()
5243                    + ", uid=" + Binder.getCallingUid()
5244                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5245            Slog.w(TAG, msg);
5246            throw new SecurityException(msg);
5247        }
5248
5249        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5250                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5251        long callingId = Binder.clearCallingIdentity();
5252        try {
5253            IPackageManager pm = AppGlobals.getPackageManager();
5254            synchronized(this) {
5255                int appId = -1;
5256                try {
5257                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5258                } catch (RemoteException e) {
5259                }
5260                if (appId == -1) {
5261                    Slog.w(TAG, "Invalid packageName: " + packageName);
5262                    return;
5263                }
5264                killPackageProcessesLocked(packageName, appId, userId,
5265                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5266            }
5267        } finally {
5268            Binder.restoreCallingIdentity(callingId);
5269        }
5270    }
5271
5272    @Override
5273    public void killAllBackgroundProcesses() {
5274        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5275                != PackageManager.PERMISSION_GRANTED) {
5276            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5277                    + Binder.getCallingPid()
5278                    + ", uid=" + Binder.getCallingUid()
5279                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5280            Slog.w(TAG, msg);
5281            throw new SecurityException(msg);
5282        }
5283
5284        long callingId = Binder.clearCallingIdentity();
5285        try {
5286            synchronized(this) {
5287                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5288                final int NP = mProcessNames.getMap().size();
5289                for (int ip=0; ip<NP; ip++) {
5290                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5291                    final int NA = apps.size();
5292                    for (int ia=0; ia<NA; ia++) {
5293                        ProcessRecord app = apps.valueAt(ia);
5294                        if (app.persistent) {
5295                            // we don't kill persistent processes
5296                            continue;
5297                        }
5298                        if (app.removed) {
5299                            procs.add(app);
5300                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5301                            app.removed = true;
5302                            procs.add(app);
5303                        }
5304                    }
5305                }
5306
5307                int N = procs.size();
5308                for (int i=0; i<N; i++) {
5309                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5310                }
5311                mAllowLowerMemLevel = true;
5312                updateOomAdjLocked();
5313                doLowMemReportIfNeededLocked(null);
5314            }
5315        } finally {
5316            Binder.restoreCallingIdentity(callingId);
5317        }
5318    }
5319
5320    @Override
5321    public void forceStopPackage(final String packageName, int userId) {
5322        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5323                != PackageManager.PERMISSION_GRANTED) {
5324            String msg = "Permission Denial: forceStopPackage() from pid="
5325                    + Binder.getCallingPid()
5326                    + ", uid=" + Binder.getCallingUid()
5327                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5328            Slog.w(TAG, msg);
5329            throw new SecurityException(msg);
5330        }
5331        final int callingPid = Binder.getCallingPid();
5332        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5333                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5334        long callingId = Binder.clearCallingIdentity();
5335        try {
5336            IPackageManager pm = AppGlobals.getPackageManager();
5337            synchronized(this) {
5338                int[] users = userId == UserHandle.USER_ALL
5339                        ? getUsersLocked() : new int[] { userId };
5340                for (int user : users) {
5341                    int pkgUid = -1;
5342                    try {
5343                        pkgUid = pm.getPackageUid(packageName, user);
5344                    } catch (RemoteException e) {
5345                    }
5346                    if (pkgUid == -1) {
5347                        Slog.w(TAG, "Invalid packageName: " + packageName);
5348                        continue;
5349                    }
5350                    try {
5351                        pm.setPackageStoppedState(packageName, true, user);
5352                    } catch (RemoteException e) {
5353                    } catch (IllegalArgumentException e) {
5354                        Slog.w(TAG, "Failed trying to unstop package "
5355                                + packageName + ": " + e);
5356                    }
5357                    if (isUserRunningLocked(user, false)) {
5358                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5359                    }
5360                }
5361            }
5362        } finally {
5363            Binder.restoreCallingIdentity(callingId);
5364        }
5365    }
5366
5367    @Override
5368    public void addPackageDependency(String packageName) {
5369        synchronized (this) {
5370            int callingPid = Binder.getCallingPid();
5371            if (callingPid == Process.myPid()) {
5372                //  Yeah, um, no.
5373                Slog.w(TAG, "Can't addPackageDependency on system process");
5374                return;
5375            }
5376            ProcessRecord proc;
5377            synchronized (mPidsSelfLocked) {
5378                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5379            }
5380            if (proc != null) {
5381                if (proc.pkgDeps == null) {
5382                    proc.pkgDeps = new ArraySet<String>(1);
5383                }
5384                proc.pkgDeps.add(packageName);
5385            }
5386        }
5387    }
5388
5389    /*
5390     * The pkg name and app id have to be specified.
5391     */
5392    @Override
5393    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5394        if (pkg == null) {
5395            return;
5396        }
5397        // Make sure the uid is valid.
5398        if (appid < 0) {
5399            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5400            return;
5401        }
5402        int callerUid = Binder.getCallingUid();
5403        // Only the system server can kill an application
5404        if (callerUid == Process.SYSTEM_UID) {
5405            // Post an aysnc message to kill the application
5406            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5407            msg.arg1 = appid;
5408            msg.arg2 = 0;
5409            Bundle bundle = new Bundle();
5410            bundle.putString("pkg", pkg);
5411            bundle.putString("reason", reason);
5412            msg.obj = bundle;
5413            mHandler.sendMessage(msg);
5414        } else {
5415            throw new SecurityException(callerUid + " cannot kill pkg: " +
5416                    pkg);
5417        }
5418    }
5419
5420    @Override
5421    public void closeSystemDialogs(String reason) {
5422        enforceNotIsolatedCaller("closeSystemDialogs");
5423
5424        final int pid = Binder.getCallingPid();
5425        final int uid = Binder.getCallingUid();
5426        final long origId = Binder.clearCallingIdentity();
5427        try {
5428            synchronized (this) {
5429                // Only allow this from foreground processes, so that background
5430                // applications can't abuse it to prevent system UI from being shown.
5431                if (uid >= Process.FIRST_APPLICATION_UID) {
5432                    ProcessRecord proc;
5433                    synchronized (mPidsSelfLocked) {
5434                        proc = mPidsSelfLocked.get(pid);
5435                    }
5436                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5437                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5438                                + " from background process " + proc);
5439                        return;
5440                    }
5441                }
5442                closeSystemDialogsLocked(reason);
5443            }
5444        } finally {
5445            Binder.restoreCallingIdentity(origId);
5446        }
5447    }
5448
5449    void closeSystemDialogsLocked(String reason) {
5450        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5451        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5452                | Intent.FLAG_RECEIVER_FOREGROUND);
5453        if (reason != null) {
5454            intent.putExtra("reason", reason);
5455        }
5456        mWindowManager.closeSystemDialogs(reason);
5457
5458        mStackSupervisor.closeSystemDialogsLocked();
5459
5460        broadcastIntentLocked(null, null, intent, null,
5461                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5462                Process.SYSTEM_UID, UserHandle.USER_ALL);
5463    }
5464
5465    @Override
5466    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5467        enforceNotIsolatedCaller("getProcessMemoryInfo");
5468        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[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            infos[i] = new Debug.MemoryInfo();
5479            Debug.getMemoryInfo(pids[i], infos[i]);
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(infos[i].getTotalPss(),
5485                                infos[i].getTotalUss(), false, proc.pkgList);
5486                    }
5487                }
5488            }
5489        }
5490        return infos;
5491    }
5492
5493    @Override
5494    public long[] getProcessPss(int[] pids) {
5495        enforceNotIsolatedCaller("getProcessPss");
5496        long[] pss = new long[pids.length];
5497        for (int i=pids.length-1; i>=0; i--) {
5498            ProcessRecord proc;
5499            int oomAdj;
5500            synchronized (this) {
5501                synchronized (mPidsSelfLocked) {
5502                    proc = mPidsSelfLocked.get(pids[i]);
5503                    oomAdj = proc != null ? proc.setAdj : 0;
5504                }
5505            }
5506            long[] tmpUss = new long[1];
5507            pss[i] = Debug.getPss(pids[i], tmpUss);
5508            if (proc != null) {
5509                synchronized (this) {
5510                    if (proc.thread != null && proc.setAdj == oomAdj) {
5511                        // Record this for posterity if the process has been stable.
5512                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5513                    }
5514                }
5515            }
5516        }
5517        return pss;
5518    }
5519
5520    @Override
5521    public void killApplicationProcess(String processName, int uid) {
5522        if (processName == null) {
5523            return;
5524        }
5525
5526        int callerUid = Binder.getCallingUid();
5527        // Only the system server can kill an application
5528        if (callerUid == Process.SYSTEM_UID) {
5529            synchronized (this) {
5530                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5531                if (app != null && app.thread != null) {
5532                    try {
5533                        app.thread.scheduleSuicide();
5534                    } catch (RemoteException e) {
5535                        // If the other end already died, then our work here is done.
5536                    }
5537                } else {
5538                    Slog.w(TAG, "Process/uid not found attempting kill of "
5539                            + processName + " / " + uid);
5540                }
5541            }
5542        } else {
5543            throw new SecurityException(callerUid + " cannot kill app process: " +
5544                    processName);
5545        }
5546    }
5547
5548    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5549        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5550                false, true, false, false, UserHandle.getUserId(uid), reason);
5551        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5552                Uri.fromParts("package", packageName, null));
5553        if (!mProcessesReady) {
5554            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5555                    | Intent.FLAG_RECEIVER_FOREGROUND);
5556        }
5557        intent.putExtra(Intent.EXTRA_UID, uid);
5558        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5559        broadcastIntentLocked(null, null, intent,
5560                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5561                false, false,
5562                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5563    }
5564
5565    private void forceStopUserLocked(int userId, String reason) {
5566        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5567        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5568        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5569                | Intent.FLAG_RECEIVER_FOREGROUND);
5570        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5571        broadcastIntentLocked(null, null, intent,
5572                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5573                false, false,
5574                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5575    }
5576
5577    private final boolean killPackageProcessesLocked(String packageName, int appId,
5578            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5579            boolean doit, boolean evenPersistent, String reason) {
5580        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5581
5582        // Remove all processes this package may have touched: all with the
5583        // same UID (except for the system or root user), and all whose name
5584        // matches the package name.
5585        final int NP = mProcessNames.getMap().size();
5586        for (int ip=0; ip<NP; ip++) {
5587            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5588            final int NA = apps.size();
5589            for (int ia=0; ia<NA; ia++) {
5590                ProcessRecord app = apps.valueAt(ia);
5591                if (app.persistent && !evenPersistent) {
5592                    // we don't kill persistent processes
5593                    continue;
5594                }
5595                if (app.removed) {
5596                    if (doit) {
5597                        procs.add(app);
5598                    }
5599                    continue;
5600                }
5601
5602                // Skip process if it doesn't meet our oom adj requirement.
5603                if (app.setAdj < minOomAdj) {
5604                    continue;
5605                }
5606
5607                // If no package is specified, we call all processes under the
5608                // give user id.
5609                if (packageName == null) {
5610                    if (app.userId != userId) {
5611                        continue;
5612                    }
5613                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5614                        continue;
5615                    }
5616                // Package has been specified, we want to hit all processes
5617                // that match it.  We need to qualify this by the processes
5618                // that are running under the specified app and user ID.
5619                } else {
5620                    final boolean isDep = app.pkgDeps != null
5621                            && app.pkgDeps.contains(packageName);
5622                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5623                        continue;
5624                    }
5625                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5626                        continue;
5627                    }
5628                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5629                        continue;
5630                    }
5631                }
5632
5633                // Process has passed all conditions, kill it!
5634                if (!doit) {
5635                    return true;
5636                }
5637                app.removed = true;
5638                procs.add(app);
5639            }
5640        }
5641
5642        int N = procs.size();
5643        for (int i=0; i<N; i++) {
5644            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5645        }
5646        updateOomAdjLocked();
5647        return N > 0;
5648    }
5649
5650    private final boolean forceStopPackageLocked(String name, int appId,
5651            boolean callerWillRestart, boolean purgeCache, boolean doit,
5652            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5653        int i;
5654        int N;
5655
5656        if (userId == UserHandle.USER_ALL && name == null) {
5657            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5658        }
5659
5660        if (appId < 0 && name != null) {
5661            try {
5662                appId = UserHandle.getAppId(
5663                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5664            } catch (RemoteException e) {
5665            }
5666        }
5667
5668        if (doit) {
5669            if (name != null) {
5670                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5671                        + " user=" + userId + ": " + reason);
5672            } else {
5673                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5674            }
5675
5676            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5677            for (int ip=pmap.size()-1; ip>=0; ip--) {
5678                SparseArray<Long> ba = pmap.valueAt(ip);
5679                for (i=ba.size()-1; i>=0; i--) {
5680                    boolean remove = false;
5681                    final int entUid = ba.keyAt(i);
5682                    if (name != null) {
5683                        if (userId == UserHandle.USER_ALL) {
5684                            if (UserHandle.getAppId(entUid) == appId) {
5685                                remove = true;
5686                            }
5687                        } else {
5688                            if (entUid == UserHandle.getUid(userId, appId)) {
5689                                remove = true;
5690                            }
5691                        }
5692                    } else if (UserHandle.getUserId(entUid) == userId) {
5693                        remove = true;
5694                    }
5695                    if (remove) {
5696                        ba.removeAt(i);
5697                    }
5698                }
5699                if (ba.size() == 0) {
5700                    pmap.removeAt(ip);
5701                }
5702            }
5703        }
5704
5705        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5706                -100, callerWillRestart, true, doit, evenPersistent,
5707                name == null ? ("stop user " + userId) : ("stop " + name));
5708
5709        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5710            if (!doit) {
5711                return true;
5712            }
5713            didSomething = true;
5714        }
5715
5716        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5717            if (!doit) {
5718                return true;
5719            }
5720            didSomething = true;
5721        }
5722
5723        if (name == null) {
5724            // Remove all sticky broadcasts from this user.
5725            mStickyBroadcasts.remove(userId);
5726        }
5727
5728        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5729        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5730                userId, providers)) {
5731            if (!doit) {
5732                return true;
5733            }
5734            didSomething = true;
5735        }
5736        N = providers.size();
5737        for (i=0; i<N; i++) {
5738            removeDyingProviderLocked(null, providers.get(i), true);
5739        }
5740
5741        // Remove transient permissions granted from/to this package/user
5742        removeUriPermissionsForPackageLocked(name, userId, false);
5743
5744        if (name == null || uninstalling) {
5745            // Remove pending intents.  For now we only do this when force
5746            // stopping users, because we have some problems when doing this
5747            // for packages -- app widgets are not currently cleaned up for
5748            // such packages, so they can be left with bad pending intents.
5749            if (mIntentSenderRecords.size() > 0) {
5750                Iterator<WeakReference<PendingIntentRecord>> it
5751                        = mIntentSenderRecords.values().iterator();
5752                while (it.hasNext()) {
5753                    WeakReference<PendingIntentRecord> wpir = it.next();
5754                    if (wpir == null) {
5755                        it.remove();
5756                        continue;
5757                    }
5758                    PendingIntentRecord pir = wpir.get();
5759                    if (pir == null) {
5760                        it.remove();
5761                        continue;
5762                    }
5763                    if (name == null) {
5764                        // Stopping user, remove all objects for the user.
5765                        if (pir.key.userId != userId) {
5766                            // Not the same user, skip it.
5767                            continue;
5768                        }
5769                    } else {
5770                        if (UserHandle.getAppId(pir.uid) != appId) {
5771                            // Different app id, skip it.
5772                            continue;
5773                        }
5774                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5775                            // Different user, skip it.
5776                            continue;
5777                        }
5778                        if (!pir.key.packageName.equals(name)) {
5779                            // Different package, skip it.
5780                            continue;
5781                        }
5782                    }
5783                    if (!doit) {
5784                        return true;
5785                    }
5786                    didSomething = true;
5787                    it.remove();
5788                    pir.canceled = true;
5789                    if (pir.key.activity != null) {
5790                        pir.key.activity.pendingResults.remove(pir.ref);
5791                    }
5792                }
5793            }
5794        }
5795
5796        if (doit) {
5797            if (purgeCache && name != null) {
5798                AttributeCache ac = AttributeCache.instance();
5799                if (ac != null) {
5800                    ac.removePackage(name);
5801                }
5802            }
5803            if (mBooted) {
5804                mStackSupervisor.resumeTopActivitiesLocked();
5805                mStackSupervisor.scheduleIdleLocked();
5806            }
5807        }
5808
5809        return didSomething;
5810    }
5811
5812    private final boolean removeProcessLocked(ProcessRecord app,
5813            boolean callerWillRestart, boolean allowRestart, String reason) {
5814        final String name = app.processName;
5815        final int uid = app.uid;
5816        if (DEBUG_PROCESSES) Slog.d(
5817            TAG, "Force removing proc " + app.toShortString() + " (" + name
5818            + "/" + uid + ")");
5819
5820        mProcessNames.remove(name, uid);
5821        mIsolatedProcesses.remove(app.uid);
5822        if (mHeavyWeightProcess == app) {
5823            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5824                    mHeavyWeightProcess.userId, 0));
5825            mHeavyWeightProcess = null;
5826        }
5827        boolean needRestart = false;
5828        if (app.pid > 0 && app.pid != MY_PID) {
5829            int pid = app.pid;
5830            synchronized (mPidsSelfLocked) {
5831                mPidsSelfLocked.remove(pid);
5832                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5833            }
5834            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5835            if (app.isolated) {
5836                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5837            }
5838            app.kill(reason, true);
5839            handleAppDiedLocked(app, true, allowRestart);
5840            removeLruProcessLocked(app);
5841
5842            if (app.persistent && !app.isolated) {
5843                if (!callerWillRestart) {
5844                    addAppLocked(app.info, false, null /* ABI override */);
5845                } else {
5846                    needRestart = true;
5847                }
5848            }
5849        } else {
5850            mRemovedProcesses.add(app);
5851        }
5852
5853        return needRestart;
5854    }
5855
5856    private final void processStartTimedOutLocked(ProcessRecord app) {
5857        final int pid = app.pid;
5858        boolean gone = false;
5859        synchronized (mPidsSelfLocked) {
5860            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5861            if (knownApp != null && knownApp.thread == null) {
5862                mPidsSelfLocked.remove(pid);
5863                gone = true;
5864            }
5865        }
5866
5867        if (gone) {
5868            Slog.w(TAG, "Process " + app + " failed to attach");
5869            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5870                    pid, app.uid, app.processName);
5871            mProcessNames.remove(app.processName, app.uid);
5872            mIsolatedProcesses.remove(app.uid);
5873            if (mHeavyWeightProcess == app) {
5874                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5875                        mHeavyWeightProcess.userId, 0));
5876                mHeavyWeightProcess = null;
5877            }
5878            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5879            if (app.isolated) {
5880                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5881            }
5882            // Take care of any launching providers waiting for this process.
5883            checkAppInLaunchingProvidersLocked(app, true);
5884            // Take care of any services that are waiting for the process.
5885            mServices.processStartTimedOutLocked(app);
5886            app.kill("start timeout", true);
5887            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5888                Slog.w(TAG, "Unattached app died before backup, skipping");
5889                try {
5890                    IBackupManager bm = IBackupManager.Stub.asInterface(
5891                            ServiceManager.getService(Context.BACKUP_SERVICE));
5892                    bm.agentDisconnected(app.info.packageName);
5893                } catch (RemoteException e) {
5894                    // Can't happen; the backup manager is local
5895                }
5896            }
5897            if (isPendingBroadcastProcessLocked(pid)) {
5898                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5899                skipPendingBroadcastLocked(pid);
5900            }
5901        } else {
5902            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5903        }
5904    }
5905
5906    private final boolean attachApplicationLocked(IApplicationThread thread,
5907            int pid) {
5908
5909        // Find the application record that is being attached...  either via
5910        // the pid if we are running in multiple processes, or just pull the
5911        // next app record if we are emulating process with anonymous threads.
5912        ProcessRecord app;
5913        if (pid != MY_PID && pid >= 0) {
5914            synchronized (mPidsSelfLocked) {
5915                app = mPidsSelfLocked.get(pid);
5916            }
5917        } else {
5918            app = null;
5919        }
5920
5921        if (app == null) {
5922            Slog.w(TAG, "No pending application record for pid " + pid
5923                    + " (IApplicationThread " + thread + "); dropping process");
5924            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5925            if (pid > 0 && pid != MY_PID) {
5926                Process.killProcessQuiet(pid);
5927                //TODO: Process.killProcessGroup(app.info.uid, pid);
5928            } else {
5929                try {
5930                    thread.scheduleExit();
5931                } catch (Exception e) {
5932                    // Ignore exceptions.
5933                }
5934            }
5935            return false;
5936        }
5937
5938        // If this application record is still attached to a previous
5939        // process, clean it up now.
5940        if (app.thread != null) {
5941            handleAppDiedLocked(app, true, true);
5942        }
5943
5944        // Tell the process all about itself.
5945
5946        if (localLOGV) Slog.v(
5947                TAG, "Binding process pid " + pid + " to record " + app);
5948
5949        final String processName = app.processName;
5950        try {
5951            AppDeathRecipient adr = new AppDeathRecipient(
5952                    app, pid, thread);
5953            thread.asBinder().linkToDeath(adr, 0);
5954            app.deathRecipient = adr;
5955        } catch (RemoteException e) {
5956            app.resetPackageList(mProcessStats);
5957            startProcessLocked(app, "link fail", processName);
5958            return false;
5959        }
5960
5961        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5962
5963        app.makeActive(thread, mProcessStats);
5964        app.curAdj = app.setAdj = -100;
5965        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5966        app.forcingToForeground = null;
5967        updateProcessForegroundLocked(app, false, false);
5968        app.hasShownUi = false;
5969        app.debugging = false;
5970        app.cached = false;
5971
5972        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5973
5974        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5975        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5976
5977        if (!normalMode) {
5978            Slog.i(TAG, "Launching preboot mode app: " + app);
5979        }
5980
5981        if (localLOGV) Slog.v(
5982            TAG, "New app record " + app
5983            + " thread=" + thread.asBinder() + " pid=" + pid);
5984        try {
5985            int testMode = IApplicationThread.DEBUG_OFF;
5986            if (mDebugApp != null && mDebugApp.equals(processName)) {
5987                testMode = mWaitForDebugger
5988                    ? IApplicationThread.DEBUG_WAIT
5989                    : IApplicationThread.DEBUG_ON;
5990                app.debugging = true;
5991                if (mDebugTransient) {
5992                    mDebugApp = mOrigDebugApp;
5993                    mWaitForDebugger = mOrigWaitForDebugger;
5994                }
5995            }
5996            String profileFile = app.instrumentationProfileFile;
5997            ParcelFileDescriptor profileFd = null;
5998            int samplingInterval = 0;
5999            boolean profileAutoStop = false;
6000            if (mProfileApp != null && mProfileApp.equals(processName)) {
6001                mProfileProc = app;
6002                profileFile = mProfileFile;
6003                profileFd = mProfileFd;
6004                samplingInterval = mSamplingInterval;
6005                profileAutoStop = mAutoStopProfiler;
6006            }
6007            boolean enableOpenGlTrace = false;
6008            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6009                enableOpenGlTrace = true;
6010                mOpenGlTraceApp = null;
6011            }
6012
6013            // If the app is being launched for restore or full backup, set it up specially
6014            boolean isRestrictedBackupMode = false;
6015            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6016                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6017                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6018                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6019            }
6020
6021            ensurePackageDexOpt(app.instrumentationInfo != null
6022                    ? app.instrumentationInfo.packageName
6023                    : app.info.packageName);
6024            if (app.instrumentationClass != null) {
6025                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6026            }
6027            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6028                    + processName + " with config " + mConfiguration);
6029            ApplicationInfo appInfo = app.instrumentationInfo != null
6030                    ? app.instrumentationInfo : app.info;
6031            app.compat = compatibilityInfoForPackageLocked(appInfo);
6032            if (profileFd != null) {
6033                profileFd = profileFd.dup();
6034            }
6035            ProfilerInfo profilerInfo = profileFile == null ? null
6036                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6037            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6038                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6039                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6040                    isRestrictedBackupMode || !normalMode, app.persistent,
6041                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6042                    mCoreSettingsObserver.getCoreSettingsLocked());
6043            updateLruProcessLocked(app, false, null);
6044            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6045        } catch (Exception e) {
6046            // todo: Yikes!  What should we do?  For now we will try to
6047            // start another process, but that could easily get us in
6048            // an infinite loop of restarting processes...
6049            Slog.w(TAG, "Exception thrown during bind!", e);
6050
6051            app.resetPackageList(mProcessStats);
6052            app.unlinkDeathRecipient();
6053            startProcessLocked(app, "bind fail", processName);
6054            return false;
6055        }
6056
6057        // Remove this record from the list of starting applications.
6058        mPersistentStartingProcesses.remove(app);
6059        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6060                "Attach application locked removing on hold: " + app);
6061        mProcessesOnHold.remove(app);
6062
6063        boolean badApp = false;
6064        boolean didSomething = false;
6065
6066        // See if the top visible activity is waiting to run in this process...
6067        if (normalMode) {
6068            try {
6069                if (mStackSupervisor.attachApplicationLocked(app)) {
6070                    didSomething = true;
6071                }
6072            } catch (Exception e) {
6073                badApp = true;
6074            }
6075        }
6076
6077        // Find any services that should be running in this process...
6078        if (!badApp) {
6079            try {
6080                didSomething |= mServices.attachApplicationLocked(app, processName);
6081            } catch (Exception e) {
6082                badApp = true;
6083            }
6084        }
6085
6086        // Check if a next-broadcast receiver is in this process...
6087        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6088            try {
6089                didSomething |= sendPendingBroadcastsLocked(app);
6090            } catch (Exception e) {
6091                // If the app died trying to launch the receiver we declare it 'bad'
6092                badApp = true;
6093            }
6094        }
6095
6096        // Check whether the next backup agent is in this process...
6097        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6098            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6099            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6100            try {
6101                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6102                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6103                        mBackupTarget.backupMode);
6104            } catch (Exception e) {
6105                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6106                e.printStackTrace();
6107            }
6108        }
6109
6110        if (badApp) {
6111            // todo: Also need to kill application to deal with all
6112            // kinds of exceptions.
6113            handleAppDiedLocked(app, false, true);
6114            return false;
6115        }
6116
6117        if (!didSomething) {
6118            updateOomAdjLocked();
6119        }
6120
6121        return true;
6122    }
6123
6124    @Override
6125    public final void attachApplication(IApplicationThread thread) {
6126        synchronized (this) {
6127            int callingPid = Binder.getCallingPid();
6128            final long origId = Binder.clearCallingIdentity();
6129            attachApplicationLocked(thread, callingPid);
6130            Binder.restoreCallingIdentity(origId);
6131        }
6132    }
6133
6134    @Override
6135    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6136        final long origId = Binder.clearCallingIdentity();
6137        synchronized (this) {
6138            ActivityStack stack = ActivityRecord.getStackLocked(token);
6139            if (stack != null) {
6140                ActivityRecord r =
6141                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6142                if (stopProfiling) {
6143                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6144                        try {
6145                            mProfileFd.close();
6146                        } catch (IOException e) {
6147                        }
6148                        clearProfilerLocked();
6149                    }
6150                }
6151            }
6152        }
6153        Binder.restoreCallingIdentity(origId);
6154    }
6155
6156    void postEnableScreenAfterBootLocked() {
6157        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6158    }
6159
6160    void enableScreenAfterBoot() {
6161        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6162                SystemClock.uptimeMillis());
6163        mWindowManager.enableScreenAfterBoot();
6164
6165        synchronized (this) {
6166            updateEventDispatchingLocked();
6167        }
6168    }
6169
6170    @Override
6171    public void showBootMessage(final CharSequence msg, final boolean always) {
6172        enforceNotIsolatedCaller("showBootMessage");
6173        mWindowManager.showBootMessage(msg, always);
6174    }
6175
6176    @Override
6177    public void keyguardWaitingForActivityDrawn() {
6178        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6179        final long token = Binder.clearCallingIdentity();
6180        try {
6181            synchronized (this) {
6182                if (DEBUG_LOCKSCREEN) logLockScreen("");
6183                mWindowManager.keyguardWaitingForActivityDrawn();
6184            }
6185        } finally {
6186            Binder.restoreCallingIdentity(token);
6187        }
6188    }
6189
6190    final void finishBooting() {
6191        // Register receivers to handle package update events
6192        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6193
6194        // Let system services know.
6195        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6196
6197        synchronized (this) {
6198            // Ensure that any processes we had put on hold are now started
6199            // up.
6200            final int NP = mProcessesOnHold.size();
6201            if (NP > 0) {
6202                ArrayList<ProcessRecord> procs =
6203                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6204                for (int ip=0; ip<NP; ip++) {
6205                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6206                            + procs.get(ip));
6207                    startProcessLocked(procs.get(ip), "on-hold", null);
6208                }
6209            }
6210
6211            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6212                // Start looking for apps that are abusing wake locks.
6213                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6214                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6215                // Tell anyone interested that we are done booting!
6216                SystemProperties.set("sys.boot_completed", "1");
6217                SystemProperties.set("dev.bootcomplete", "1");
6218                for (int i=0; i<mStartedUsers.size(); i++) {
6219                    UserStartedState uss = mStartedUsers.valueAt(i);
6220                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6221                        uss.mState = UserStartedState.STATE_RUNNING;
6222                        final int userId = mStartedUsers.keyAt(i);
6223                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6224                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6225                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6226                        broadcastIntentLocked(null, null, intent, null,
6227                                new IIntentReceiver.Stub() {
6228                                    @Override
6229                                    public void performReceive(Intent intent, int resultCode,
6230                                            String data, Bundle extras, boolean ordered,
6231                                            boolean sticky, int sendingUser) {
6232                                        synchronized (ActivityManagerService.this) {
6233                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6234                                                    true, false);
6235                                        }
6236                                    }
6237                                },
6238                                0, null, null,
6239                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6240                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6241                                userId);
6242                    }
6243                }
6244                scheduleStartProfilesLocked();
6245            }
6246        }
6247    }
6248
6249    final void ensureBootCompleted() {
6250        boolean booting;
6251        boolean enableScreen;
6252        synchronized (this) {
6253            booting = mBooting;
6254            mBooting = false;
6255            enableScreen = !mBooted;
6256            mBooted = true;
6257        }
6258
6259        if (booting) {
6260            finishBooting();
6261        }
6262
6263        if (enableScreen) {
6264            enableScreenAfterBoot();
6265        }
6266    }
6267
6268    @Override
6269    public final void activityResumed(IBinder token) {
6270        final long origId = Binder.clearCallingIdentity();
6271        synchronized(this) {
6272            ActivityStack stack = ActivityRecord.getStackLocked(token);
6273            if (stack != null) {
6274                ActivityRecord.activityResumedLocked(token);
6275            }
6276        }
6277        Binder.restoreCallingIdentity(origId);
6278    }
6279
6280    @Override
6281    public final void activityPaused(IBinder token) {
6282        final long origId = Binder.clearCallingIdentity();
6283        synchronized(this) {
6284            ActivityStack stack = ActivityRecord.getStackLocked(token);
6285            if (stack != null) {
6286                stack.activityPausedLocked(token, false);
6287            }
6288        }
6289        Binder.restoreCallingIdentity(origId);
6290    }
6291
6292    @Override
6293    public final void activityStopped(IBinder token, Bundle icicle,
6294            PersistableBundle persistentState, CharSequence description) {
6295        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6296
6297        // Refuse possible leaked file descriptors
6298        if (icicle != null && icicle.hasFileDescriptors()) {
6299            throw new IllegalArgumentException("File descriptors passed in Bundle");
6300        }
6301
6302        final long origId = Binder.clearCallingIdentity();
6303
6304        synchronized (this) {
6305            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6306            if (r != null) {
6307                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6308            }
6309        }
6310
6311        trimApplications();
6312
6313        Binder.restoreCallingIdentity(origId);
6314    }
6315
6316    @Override
6317    public final void activityDestroyed(IBinder token) {
6318        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6319        synchronized (this) {
6320            ActivityStack stack = ActivityRecord.getStackLocked(token);
6321            if (stack != null) {
6322                stack.activityDestroyedLocked(token);
6323            }
6324        }
6325    }
6326
6327    @Override
6328    public final void backgroundResourcesReleased(IBinder token) {
6329        final long origId = Binder.clearCallingIdentity();
6330        try {
6331            synchronized (this) {
6332                ActivityStack stack = ActivityRecord.getStackLocked(token);
6333                if (stack != null) {
6334                    stack.backgroundResourcesReleased(token);
6335                }
6336            }
6337        } finally {
6338            Binder.restoreCallingIdentity(origId);
6339        }
6340    }
6341
6342    @Override
6343    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6344        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6345    }
6346
6347    @Override
6348    public final void notifyEnterAnimationComplete(IBinder token) {
6349        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6350    }
6351
6352    @Override
6353    public String getCallingPackage(IBinder token) {
6354        synchronized (this) {
6355            ActivityRecord r = getCallingRecordLocked(token);
6356            return r != null ? r.info.packageName : null;
6357        }
6358    }
6359
6360    @Override
6361    public ComponentName getCallingActivity(IBinder token) {
6362        synchronized (this) {
6363            ActivityRecord r = getCallingRecordLocked(token);
6364            return r != null ? r.intent.getComponent() : null;
6365        }
6366    }
6367
6368    private ActivityRecord getCallingRecordLocked(IBinder token) {
6369        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6370        if (r == null) {
6371            return null;
6372        }
6373        return r.resultTo;
6374    }
6375
6376    @Override
6377    public ComponentName getActivityClassForToken(IBinder token) {
6378        synchronized(this) {
6379            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6380            if (r == null) {
6381                return null;
6382            }
6383            return r.intent.getComponent();
6384        }
6385    }
6386
6387    @Override
6388    public String getPackageForToken(IBinder token) {
6389        synchronized(this) {
6390            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6391            if (r == null) {
6392                return null;
6393            }
6394            return r.packageName;
6395        }
6396    }
6397
6398    @Override
6399    public IIntentSender getIntentSender(int type,
6400            String packageName, IBinder token, String resultWho,
6401            int requestCode, Intent[] intents, String[] resolvedTypes,
6402            int flags, Bundle options, int userId) {
6403        enforceNotIsolatedCaller("getIntentSender");
6404        // Refuse possible leaked file descriptors
6405        if (intents != null) {
6406            if (intents.length < 1) {
6407                throw new IllegalArgumentException("Intents array length must be >= 1");
6408            }
6409            for (int i=0; i<intents.length; i++) {
6410                Intent intent = intents[i];
6411                if (intent != null) {
6412                    if (intent.hasFileDescriptors()) {
6413                        throw new IllegalArgumentException("File descriptors passed in Intent");
6414                    }
6415                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6416                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6417                        throw new IllegalArgumentException(
6418                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6419                    }
6420                    intents[i] = new Intent(intent);
6421                }
6422            }
6423            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6424                throw new IllegalArgumentException(
6425                        "Intent array length does not match resolvedTypes length");
6426            }
6427        }
6428        if (options != null) {
6429            if (options.hasFileDescriptors()) {
6430                throw new IllegalArgumentException("File descriptors passed in options");
6431            }
6432        }
6433
6434        synchronized(this) {
6435            int callingUid = Binder.getCallingUid();
6436            int origUserId = userId;
6437            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6438                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6439                    ALLOW_NON_FULL, "getIntentSender", null);
6440            if (origUserId == UserHandle.USER_CURRENT) {
6441                // We don't want to evaluate this until the pending intent is
6442                // actually executed.  However, we do want to always do the
6443                // security checking for it above.
6444                userId = UserHandle.USER_CURRENT;
6445            }
6446            try {
6447                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6448                    int uid = AppGlobals.getPackageManager()
6449                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6450                    if (!UserHandle.isSameApp(callingUid, uid)) {
6451                        String msg = "Permission Denial: getIntentSender() from pid="
6452                            + Binder.getCallingPid()
6453                            + ", uid=" + Binder.getCallingUid()
6454                            + ", (need uid=" + uid + ")"
6455                            + " is not allowed to send as package " + packageName;
6456                        Slog.w(TAG, msg);
6457                        throw new SecurityException(msg);
6458                    }
6459                }
6460
6461                return getIntentSenderLocked(type, packageName, callingUid, userId,
6462                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6463
6464            } catch (RemoteException e) {
6465                throw new SecurityException(e);
6466            }
6467        }
6468    }
6469
6470    IIntentSender getIntentSenderLocked(int type, String packageName,
6471            int callingUid, int userId, IBinder token, String resultWho,
6472            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6473            Bundle options) {
6474        if (DEBUG_MU)
6475            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6476        ActivityRecord activity = null;
6477        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6478            activity = ActivityRecord.isInStackLocked(token);
6479            if (activity == null) {
6480                return null;
6481            }
6482            if (activity.finishing) {
6483                return null;
6484            }
6485        }
6486
6487        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6488        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6489        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6490        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6491                |PendingIntent.FLAG_UPDATE_CURRENT);
6492
6493        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6494                type, packageName, activity, resultWho,
6495                requestCode, intents, resolvedTypes, flags, options, userId);
6496        WeakReference<PendingIntentRecord> ref;
6497        ref = mIntentSenderRecords.get(key);
6498        PendingIntentRecord rec = ref != null ? ref.get() : null;
6499        if (rec != null) {
6500            if (!cancelCurrent) {
6501                if (updateCurrent) {
6502                    if (rec.key.requestIntent != null) {
6503                        rec.key.requestIntent.replaceExtras(intents != null ?
6504                                intents[intents.length - 1] : null);
6505                    }
6506                    if (intents != null) {
6507                        intents[intents.length-1] = rec.key.requestIntent;
6508                        rec.key.allIntents = intents;
6509                        rec.key.allResolvedTypes = resolvedTypes;
6510                    } else {
6511                        rec.key.allIntents = null;
6512                        rec.key.allResolvedTypes = null;
6513                    }
6514                }
6515                return rec;
6516            }
6517            rec.canceled = true;
6518            mIntentSenderRecords.remove(key);
6519        }
6520        if (noCreate) {
6521            return rec;
6522        }
6523        rec = new PendingIntentRecord(this, key, callingUid);
6524        mIntentSenderRecords.put(key, rec.ref);
6525        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6526            if (activity.pendingResults == null) {
6527                activity.pendingResults
6528                        = new HashSet<WeakReference<PendingIntentRecord>>();
6529            }
6530            activity.pendingResults.add(rec.ref);
6531        }
6532        return rec;
6533    }
6534
6535    @Override
6536    public void cancelIntentSender(IIntentSender sender) {
6537        if (!(sender instanceof PendingIntentRecord)) {
6538            return;
6539        }
6540        synchronized(this) {
6541            PendingIntentRecord rec = (PendingIntentRecord)sender;
6542            try {
6543                int uid = AppGlobals.getPackageManager()
6544                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6545                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6546                    String msg = "Permission Denial: cancelIntentSender() from pid="
6547                        + Binder.getCallingPid()
6548                        + ", uid=" + Binder.getCallingUid()
6549                        + " is not allowed to cancel packges "
6550                        + rec.key.packageName;
6551                    Slog.w(TAG, msg);
6552                    throw new SecurityException(msg);
6553                }
6554            } catch (RemoteException e) {
6555                throw new SecurityException(e);
6556            }
6557            cancelIntentSenderLocked(rec, true);
6558        }
6559    }
6560
6561    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6562        rec.canceled = true;
6563        mIntentSenderRecords.remove(rec.key);
6564        if (cleanActivity && rec.key.activity != null) {
6565            rec.key.activity.pendingResults.remove(rec.ref);
6566        }
6567    }
6568
6569    @Override
6570    public String getPackageForIntentSender(IIntentSender pendingResult) {
6571        if (!(pendingResult instanceof PendingIntentRecord)) {
6572            return null;
6573        }
6574        try {
6575            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6576            return res.key.packageName;
6577        } catch (ClassCastException e) {
6578        }
6579        return null;
6580    }
6581
6582    @Override
6583    public int getUidForIntentSender(IIntentSender sender) {
6584        if (sender instanceof PendingIntentRecord) {
6585            try {
6586                PendingIntentRecord res = (PendingIntentRecord)sender;
6587                return res.uid;
6588            } catch (ClassCastException e) {
6589            }
6590        }
6591        return -1;
6592    }
6593
6594    @Override
6595    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6596        if (!(pendingResult instanceof PendingIntentRecord)) {
6597            return false;
6598        }
6599        try {
6600            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6601            if (res.key.allIntents == null) {
6602                return false;
6603            }
6604            for (int i=0; i<res.key.allIntents.length; i++) {
6605                Intent intent = res.key.allIntents[i];
6606                if (intent.getPackage() != null && intent.getComponent() != null) {
6607                    return false;
6608                }
6609            }
6610            return true;
6611        } catch (ClassCastException e) {
6612        }
6613        return false;
6614    }
6615
6616    @Override
6617    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6618        if (!(pendingResult instanceof PendingIntentRecord)) {
6619            return false;
6620        }
6621        try {
6622            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6623            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6624                return true;
6625            }
6626            return false;
6627        } catch (ClassCastException e) {
6628        }
6629        return false;
6630    }
6631
6632    @Override
6633    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6634        if (!(pendingResult instanceof PendingIntentRecord)) {
6635            return null;
6636        }
6637        try {
6638            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6639            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6640        } catch (ClassCastException e) {
6641        }
6642        return null;
6643    }
6644
6645    @Override
6646    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6647        if (!(pendingResult instanceof PendingIntentRecord)) {
6648            return null;
6649        }
6650        try {
6651            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6652            Intent intent = res.key.requestIntent;
6653            if (intent != null) {
6654                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6655                        || res.lastTagPrefix.equals(prefix))) {
6656                    return res.lastTag;
6657                }
6658                res.lastTagPrefix = prefix;
6659                StringBuilder sb = new StringBuilder(128);
6660                if (prefix != null) {
6661                    sb.append(prefix);
6662                }
6663                if (intent.getAction() != null) {
6664                    sb.append(intent.getAction());
6665                } else if (intent.getComponent() != null) {
6666                    intent.getComponent().appendShortString(sb);
6667                } else {
6668                    sb.append("?");
6669                }
6670                return res.lastTag = sb.toString();
6671            }
6672        } catch (ClassCastException e) {
6673        }
6674        return null;
6675    }
6676
6677    @Override
6678    public void setProcessLimit(int max) {
6679        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6680                "setProcessLimit()");
6681        synchronized (this) {
6682            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6683            mProcessLimitOverride = max;
6684        }
6685        trimApplications();
6686    }
6687
6688    @Override
6689    public int getProcessLimit() {
6690        synchronized (this) {
6691            return mProcessLimitOverride;
6692        }
6693    }
6694
6695    void foregroundTokenDied(ForegroundToken token) {
6696        synchronized (ActivityManagerService.this) {
6697            synchronized (mPidsSelfLocked) {
6698                ForegroundToken cur
6699                    = mForegroundProcesses.get(token.pid);
6700                if (cur != token) {
6701                    return;
6702                }
6703                mForegroundProcesses.remove(token.pid);
6704                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6705                if (pr == null) {
6706                    return;
6707                }
6708                pr.forcingToForeground = null;
6709                updateProcessForegroundLocked(pr, false, false);
6710            }
6711            updateOomAdjLocked();
6712        }
6713    }
6714
6715    @Override
6716    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6717        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6718                "setProcessForeground()");
6719        synchronized(this) {
6720            boolean changed = false;
6721
6722            synchronized (mPidsSelfLocked) {
6723                ProcessRecord pr = mPidsSelfLocked.get(pid);
6724                if (pr == null && isForeground) {
6725                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6726                    return;
6727                }
6728                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6729                if (oldToken != null) {
6730                    oldToken.token.unlinkToDeath(oldToken, 0);
6731                    mForegroundProcesses.remove(pid);
6732                    if (pr != null) {
6733                        pr.forcingToForeground = null;
6734                    }
6735                    changed = true;
6736                }
6737                if (isForeground && token != null) {
6738                    ForegroundToken newToken = new ForegroundToken() {
6739                        @Override
6740                        public void binderDied() {
6741                            foregroundTokenDied(this);
6742                        }
6743                    };
6744                    newToken.pid = pid;
6745                    newToken.token = token;
6746                    try {
6747                        token.linkToDeath(newToken, 0);
6748                        mForegroundProcesses.put(pid, newToken);
6749                        pr.forcingToForeground = token;
6750                        changed = true;
6751                    } catch (RemoteException e) {
6752                        // If the process died while doing this, we will later
6753                        // do the cleanup with the process death link.
6754                    }
6755                }
6756            }
6757
6758            if (changed) {
6759                updateOomAdjLocked();
6760            }
6761        }
6762    }
6763
6764    // =========================================================
6765    // PERMISSIONS
6766    // =========================================================
6767
6768    static class PermissionController extends IPermissionController.Stub {
6769        ActivityManagerService mActivityManagerService;
6770        PermissionController(ActivityManagerService activityManagerService) {
6771            mActivityManagerService = activityManagerService;
6772        }
6773
6774        @Override
6775        public boolean checkPermission(String permission, int pid, int uid) {
6776            return mActivityManagerService.checkPermission(permission, pid,
6777                    uid) == PackageManager.PERMISSION_GRANTED;
6778        }
6779    }
6780
6781    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6782        @Override
6783        public int checkComponentPermission(String permission, int pid, int uid,
6784                int owningUid, boolean exported) {
6785            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6786                    owningUid, exported);
6787        }
6788
6789        @Override
6790        public Object getAMSLock() {
6791            return ActivityManagerService.this;
6792        }
6793    }
6794
6795    /**
6796     * This can be called with or without the global lock held.
6797     */
6798    int checkComponentPermission(String permission, int pid, int uid,
6799            int owningUid, boolean exported) {
6800        // We might be performing an operation on behalf of an indirect binder
6801        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6802        // client identity accordingly before proceeding.
6803        Identity tlsIdentity = sCallerIdentity.get();
6804        if (tlsIdentity != null) {
6805            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6806                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6807            uid = tlsIdentity.uid;
6808            pid = tlsIdentity.pid;
6809        }
6810
6811        if (pid == MY_PID) {
6812            return PackageManager.PERMISSION_GRANTED;
6813        }
6814
6815        return ActivityManager.checkComponentPermission(permission, uid,
6816                owningUid, exported);
6817    }
6818
6819    /**
6820     * As the only public entry point for permissions checking, this method
6821     * can enforce the semantic that requesting a check on a null global
6822     * permission is automatically denied.  (Internally a null permission
6823     * string is used when calling {@link #checkComponentPermission} in cases
6824     * when only uid-based security is needed.)
6825     *
6826     * This can be called with or without the global lock held.
6827     */
6828    @Override
6829    public int checkPermission(String permission, int pid, int uid) {
6830        if (permission == null) {
6831            return PackageManager.PERMISSION_DENIED;
6832        }
6833        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6834    }
6835
6836    /**
6837     * Binder IPC calls go through the public entry point.
6838     * This can be called with or without the global lock held.
6839     */
6840    int checkCallingPermission(String permission) {
6841        return checkPermission(permission,
6842                Binder.getCallingPid(),
6843                UserHandle.getAppId(Binder.getCallingUid()));
6844    }
6845
6846    /**
6847     * This can be called with or without the global lock held.
6848     */
6849    void enforceCallingPermission(String permission, String func) {
6850        if (checkCallingPermission(permission)
6851                == PackageManager.PERMISSION_GRANTED) {
6852            return;
6853        }
6854
6855        String msg = "Permission Denial: " + func + " from pid="
6856                + Binder.getCallingPid()
6857                + ", uid=" + Binder.getCallingUid()
6858                + " requires " + permission;
6859        Slog.w(TAG, msg);
6860        throw new SecurityException(msg);
6861    }
6862
6863    /**
6864     * Determine if UID is holding permissions required to access {@link Uri} in
6865     * the given {@link ProviderInfo}. Final permission checking is always done
6866     * in {@link ContentProvider}.
6867     */
6868    private final boolean checkHoldingPermissionsLocked(
6869            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6870        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6871                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6872        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6873            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6874                    != PERMISSION_GRANTED) {
6875                return false;
6876            }
6877        }
6878        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6879    }
6880
6881    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6882            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6883        if (pi.applicationInfo.uid == uid) {
6884            return true;
6885        } else if (!pi.exported) {
6886            return false;
6887        }
6888
6889        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6890        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6891        try {
6892            // check if target holds top-level <provider> permissions
6893            if (!readMet && pi.readPermission != null && considerUidPermissions
6894                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6895                readMet = true;
6896            }
6897            if (!writeMet && pi.writePermission != null && considerUidPermissions
6898                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6899                writeMet = true;
6900            }
6901
6902            // track if unprotected read/write is allowed; any denied
6903            // <path-permission> below removes this ability
6904            boolean allowDefaultRead = pi.readPermission == null;
6905            boolean allowDefaultWrite = pi.writePermission == null;
6906
6907            // check if target holds any <path-permission> that match uri
6908            final PathPermission[] pps = pi.pathPermissions;
6909            if (pps != null) {
6910                final String path = grantUri.uri.getPath();
6911                int i = pps.length;
6912                while (i > 0 && (!readMet || !writeMet)) {
6913                    i--;
6914                    PathPermission pp = pps[i];
6915                    if (pp.match(path)) {
6916                        if (!readMet) {
6917                            final String pprperm = pp.getReadPermission();
6918                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6919                                    + pprperm + " for " + pp.getPath()
6920                                    + ": match=" + pp.match(path)
6921                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6922                            if (pprperm != null) {
6923                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6924                                        == PERMISSION_GRANTED) {
6925                                    readMet = true;
6926                                } else {
6927                                    allowDefaultRead = false;
6928                                }
6929                            }
6930                        }
6931                        if (!writeMet) {
6932                            final String ppwperm = pp.getWritePermission();
6933                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6934                                    + ppwperm + " for " + pp.getPath()
6935                                    + ": match=" + pp.match(path)
6936                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6937                            if (ppwperm != null) {
6938                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6939                                        == PERMISSION_GRANTED) {
6940                                    writeMet = true;
6941                                } else {
6942                                    allowDefaultWrite = false;
6943                                }
6944                            }
6945                        }
6946                    }
6947                }
6948            }
6949
6950            // grant unprotected <provider> read/write, if not blocked by
6951            // <path-permission> above
6952            if (allowDefaultRead) readMet = true;
6953            if (allowDefaultWrite) writeMet = true;
6954
6955        } catch (RemoteException e) {
6956            return false;
6957        }
6958
6959        return readMet && writeMet;
6960    }
6961
6962    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6963        ProviderInfo pi = null;
6964        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6965        if (cpr != null) {
6966            pi = cpr.info;
6967        } else {
6968            try {
6969                pi = AppGlobals.getPackageManager().resolveContentProvider(
6970                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6971            } catch (RemoteException ex) {
6972            }
6973        }
6974        return pi;
6975    }
6976
6977    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6978        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6979        if (targetUris != null) {
6980            return targetUris.get(grantUri);
6981        }
6982        return null;
6983    }
6984
6985    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6986            String targetPkg, int targetUid, GrantUri grantUri) {
6987        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6988        if (targetUris == null) {
6989            targetUris = Maps.newArrayMap();
6990            mGrantedUriPermissions.put(targetUid, targetUris);
6991        }
6992
6993        UriPermission perm = targetUris.get(grantUri);
6994        if (perm == null) {
6995            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6996            targetUris.put(grantUri, perm);
6997        }
6998
6999        return perm;
7000    }
7001
7002    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7003            final int modeFlags) {
7004        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7005        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7006                : UriPermission.STRENGTH_OWNED;
7007
7008        // Root gets to do everything.
7009        if (uid == 0) {
7010            return true;
7011        }
7012
7013        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7014        if (perms == null) return false;
7015
7016        // First look for exact match
7017        final UriPermission exactPerm = perms.get(grantUri);
7018        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7019            return true;
7020        }
7021
7022        // No exact match, look for prefixes
7023        final int N = perms.size();
7024        for (int i = 0; i < N; i++) {
7025            final UriPermission perm = perms.valueAt(i);
7026            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7027                    && perm.getStrength(modeFlags) >= minStrength) {
7028                return true;
7029            }
7030        }
7031
7032        return false;
7033    }
7034
7035    /**
7036     * @param uri This uri must NOT contain an embedded userId.
7037     * @param userId The userId in which the uri is to be resolved.
7038     */
7039    @Override
7040    public int checkUriPermission(Uri uri, int pid, int uid,
7041            final int modeFlags, int userId) {
7042        enforceNotIsolatedCaller("checkUriPermission");
7043
7044        // Another redirected-binder-call permissions check as in
7045        // {@link checkComponentPermission}.
7046        Identity tlsIdentity = sCallerIdentity.get();
7047        if (tlsIdentity != null) {
7048            uid = tlsIdentity.uid;
7049            pid = tlsIdentity.pid;
7050        }
7051
7052        // Our own process gets to do everything.
7053        if (pid == MY_PID) {
7054            return PackageManager.PERMISSION_GRANTED;
7055        }
7056        synchronized (this) {
7057            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7058                    ? PackageManager.PERMISSION_GRANTED
7059                    : PackageManager.PERMISSION_DENIED;
7060        }
7061    }
7062
7063    /**
7064     * Check if the targetPkg can be granted permission to access uri by
7065     * the callingUid using the given modeFlags.  Throws a security exception
7066     * if callingUid is not allowed to do this.  Returns the uid of the target
7067     * if the URI permission grant should be performed; returns -1 if it is not
7068     * needed (for example targetPkg already has permission to access the URI).
7069     * If you already know the uid of the target, you can supply it in
7070     * lastTargetUid else set that to -1.
7071     */
7072    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7073            final int modeFlags, int lastTargetUid) {
7074        if (!Intent.isAccessUriMode(modeFlags)) {
7075            return -1;
7076        }
7077
7078        if (targetPkg != null) {
7079            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7080                    "Checking grant " + targetPkg + " permission to " + grantUri);
7081        }
7082
7083        final IPackageManager pm = AppGlobals.getPackageManager();
7084
7085        // If this is not a content: uri, we can't do anything with it.
7086        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7087            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7088                    "Can't grant URI permission for non-content URI: " + grantUri);
7089            return -1;
7090        }
7091
7092        final String authority = grantUri.uri.getAuthority();
7093        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7094        if (pi == null) {
7095            Slog.w(TAG, "No content provider found for permission check: " +
7096                    grantUri.uri.toSafeString());
7097            return -1;
7098        }
7099
7100        int targetUid = lastTargetUid;
7101        if (targetUid < 0 && targetPkg != null) {
7102            try {
7103                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7104                if (targetUid < 0) {
7105                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7106                            "Can't grant URI permission no uid for: " + targetPkg);
7107                    return -1;
7108                }
7109            } catch (RemoteException ex) {
7110                return -1;
7111            }
7112        }
7113
7114        if (targetUid >= 0) {
7115            // First...  does the target actually need this permission?
7116            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7117                // No need to grant the target this permission.
7118                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7119                        "Target " + targetPkg + " already has full permission to " + grantUri);
7120                return -1;
7121            }
7122        } else {
7123            // First...  there is no target package, so can anyone access it?
7124            boolean allowed = pi.exported;
7125            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7126                if (pi.readPermission != null) {
7127                    allowed = false;
7128                }
7129            }
7130            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7131                if (pi.writePermission != null) {
7132                    allowed = false;
7133                }
7134            }
7135            if (allowed) {
7136                return -1;
7137            }
7138        }
7139
7140        /* There is a special cross user grant if:
7141         * - The target is on another user.
7142         * - Apps on the current user can access the uri without any uid permissions.
7143         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7144         * grant uri permissions.
7145         */
7146        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7147                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7148                modeFlags, false /*without considering the uid permissions*/);
7149
7150        // Second...  is the provider allowing granting of URI permissions?
7151        if (!specialCrossUserGrant) {
7152            if (!pi.grantUriPermissions) {
7153                throw new SecurityException("Provider " + pi.packageName
7154                        + "/" + pi.name
7155                        + " does not allow granting of Uri permissions (uri "
7156                        + grantUri + ")");
7157            }
7158            if (pi.uriPermissionPatterns != null) {
7159                final int N = pi.uriPermissionPatterns.length;
7160                boolean allowed = false;
7161                for (int i=0; i<N; i++) {
7162                    if (pi.uriPermissionPatterns[i] != null
7163                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7164                        allowed = true;
7165                        break;
7166                    }
7167                }
7168                if (!allowed) {
7169                    throw new SecurityException("Provider " + pi.packageName
7170                            + "/" + pi.name
7171                            + " does not allow granting of permission to path of Uri "
7172                            + grantUri);
7173                }
7174            }
7175        }
7176
7177        // Third...  does the caller itself have permission to access
7178        // this uri?
7179        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7180            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7181                // Require they hold a strong enough Uri permission
7182                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7183                    throw new SecurityException("Uid " + callingUid
7184                            + " does not have permission to uri " + grantUri);
7185                }
7186            }
7187        }
7188        return targetUid;
7189    }
7190
7191    /**
7192     * @param uri This uri must NOT contain an embedded userId.
7193     * @param userId The userId in which the uri is to be resolved.
7194     */
7195    @Override
7196    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7197            final int modeFlags, int userId) {
7198        enforceNotIsolatedCaller("checkGrantUriPermission");
7199        synchronized(this) {
7200            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7201                    new GrantUri(userId, uri, false), modeFlags, -1);
7202        }
7203    }
7204
7205    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7206            final int modeFlags, UriPermissionOwner owner) {
7207        if (!Intent.isAccessUriMode(modeFlags)) {
7208            return;
7209        }
7210
7211        // So here we are: the caller has the assumed permission
7212        // to the uri, and the target doesn't.  Let's now give this to
7213        // the target.
7214
7215        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7216                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7217
7218        final String authority = grantUri.uri.getAuthority();
7219        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7220        if (pi == null) {
7221            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7222            return;
7223        }
7224
7225        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7226            grantUri.prefix = true;
7227        }
7228        final UriPermission perm = findOrCreateUriPermissionLocked(
7229                pi.packageName, targetPkg, targetUid, grantUri);
7230        perm.grantModes(modeFlags, owner);
7231    }
7232
7233    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7234            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7235        if (targetPkg == null) {
7236            throw new NullPointerException("targetPkg");
7237        }
7238        int targetUid;
7239        final IPackageManager pm = AppGlobals.getPackageManager();
7240        try {
7241            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7242        } catch (RemoteException ex) {
7243            return;
7244        }
7245
7246        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7247                targetUid);
7248        if (targetUid < 0) {
7249            return;
7250        }
7251
7252        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7253                owner);
7254    }
7255
7256    static class NeededUriGrants extends ArrayList<GrantUri> {
7257        final String targetPkg;
7258        final int targetUid;
7259        final int flags;
7260
7261        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7262            this.targetPkg = targetPkg;
7263            this.targetUid = targetUid;
7264            this.flags = flags;
7265        }
7266    }
7267
7268    /**
7269     * Like checkGrantUriPermissionLocked, but takes an Intent.
7270     */
7271    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7272            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7273        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7274                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7275                + " clip=" + (intent != null ? intent.getClipData() : null)
7276                + " from " + intent + "; flags=0x"
7277                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7278
7279        if (targetPkg == null) {
7280            throw new NullPointerException("targetPkg");
7281        }
7282
7283        if (intent == null) {
7284            return null;
7285        }
7286        Uri data = intent.getData();
7287        ClipData clip = intent.getClipData();
7288        if (data == null && clip == null) {
7289            return null;
7290        }
7291        // Default userId for uris in the intent (if they don't specify it themselves)
7292        int contentUserHint = intent.getContentUserHint();
7293        if (contentUserHint == UserHandle.USER_CURRENT) {
7294            contentUserHint = UserHandle.getUserId(callingUid);
7295        }
7296        final IPackageManager pm = AppGlobals.getPackageManager();
7297        int targetUid;
7298        if (needed != null) {
7299            targetUid = needed.targetUid;
7300        } else {
7301            try {
7302                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7303            } catch (RemoteException ex) {
7304                return null;
7305            }
7306            if (targetUid < 0) {
7307                if (DEBUG_URI_PERMISSION) {
7308                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7309                            + " on user " + targetUserId);
7310                }
7311                return null;
7312            }
7313        }
7314        if (data != null) {
7315            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7316            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7317                    targetUid);
7318            if (targetUid > 0) {
7319                if (needed == null) {
7320                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7321                }
7322                needed.add(grantUri);
7323            }
7324        }
7325        if (clip != null) {
7326            for (int i=0; i<clip.getItemCount(); i++) {
7327                Uri uri = clip.getItemAt(i).getUri();
7328                if (uri != null) {
7329                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7330                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7331                            targetUid);
7332                    if (targetUid > 0) {
7333                        if (needed == null) {
7334                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7335                        }
7336                        needed.add(grantUri);
7337                    }
7338                } else {
7339                    Intent clipIntent = clip.getItemAt(i).getIntent();
7340                    if (clipIntent != null) {
7341                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7342                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7343                        if (newNeeded != null) {
7344                            needed = newNeeded;
7345                        }
7346                    }
7347                }
7348            }
7349        }
7350
7351        return needed;
7352    }
7353
7354    /**
7355     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7356     */
7357    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7358            UriPermissionOwner owner) {
7359        if (needed != null) {
7360            for (int i=0; i<needed.size(); i++) {
7361                GrantUri grantUri = needed.get(i);
7362                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7363                        grantUri, needed.flags, owner);
7364            }
7365        }
7366    }
7367
7368    void grantUriPermissionFromIntentLocked(int callingUid,
7369            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7370        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7371                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7372        if (needed == null) {
7373            return;
7374        }
7375
7376        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7377    }
7378
7379    /**
7380     * @param uri This uri must NOT contain an embedded userId.
7381     * @param userId The userId in which the uri is to be resolved.
7382     */
7383    @Override
7384    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7385            final int modeFlags, int userId) {
7386        enforceNotIsolatedCaller("grantUriPermission");
7387        GrantUri grantUri = new GrantUri(userId, uri, false);
7388        synchronized(this) {
7389            final ProcessRecord r = getRecordForAppLocked(caller);
7390            if (r == null) {
7391                throw new SecurityException("Unable to find app for caller "
7392                        + caller
7393                        + " when granting permission to uri " + grantUri);
7394            }
7395            if (targetPkg == null) {
7396                throw new IllegalArgumentException("null target");
7397            }
7398            if (grantUri == null) {
7399                throw new IllegalArgumentException("null uri");
7400            }
7401
7402            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7403                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7404                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7405                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7406
7407            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7408                    UserHandle.getUserId(r.uid));
7409        }
7410    }
7411
7412    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7413        if (perm.modeFlags == 0) {
7414            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7415                    perm.targetUid);
7416            if (perms != null) {
7417                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7418                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7419
7420                perms.remove(perm.uri);
7421                if (perms.isEmpty()) {
7422                    mGrantedUriPermissions.remove(perm.targetUid);
7423                }
7424            }
7425        }
7426    }
7427
7428    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7429        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7430
7431        final IPackageManager pm = AppGlobals.getPackageManager();
7432        final String authority = grantUri.uri.getAuthority();
7433        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7434        if (pi == null) {
7435            Slog.w(TAG, "No content provider found for permission revoke: "
7436                    + grantUri.toSafeString());
7437            return;
7438        }
7439
7440        // Does the caller have this permission on the URI?
7441        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7442            // Right now, if you are not the original owner of the permission,
7443            // you are not allowed to revoke it.
7444            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7445                throw new SecurityException("Uid " + callingUid
7446                        + " does not have permission to uri " + grantUri);
7447            //}
7448        }
7449
7450        boolean persistChanged = false;
7451
7452        // Go through all of the permissions and remove any that match.
7453        int N = mGrantedUriPermissions.size();
7454        for (int i = 0; i < N; i++) {
7455            final int targetUid = mGrantedUriPermissions.keyAt(i);
7456            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7457
7458            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7459                final UriPermission perm = it.next();
7460                if (perm.uri.sourceUserId == grantUri.sourceUserId
7461                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7462                    if (DEBUG_URI_PERMISSION)
7463                        Slog.v(TAG,
7464                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7465                    persistChanged |= perm.revokeModes(
7466                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7467                    if (perm.modeFlags == 0) {
7468                        it.remove();
7469                    }
7470                }
7471            }
7472
7473            if (perms.isEmpty()) {
7474                mGrantedUriPermissions.remove(targetUid);
7475                N--;
7476                i--;
7477            }
7478        }
7479
7480        if (persistChanged) {
7481            schedulePersistUriGrants();
7482        }
7483    }
7484
7485    /**
7486     * @param uri This uri must NOT contain an embedded userId.
7487     * @param userId The userId in which the uri is to be resolved.
7488     */
7489    @Override
7490    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7491            int userId) {
7492        enforceNotIsolatedCaller("revokeUriPermission");
7493        synchronized(this) {
7494            final ProcessRecord r = getRecordForAppLocked(caller);
7495            if (r == null) {
7496                throw new SecurityException("Unable to find app for caller "
7497                        + caller
7498                        + " when revoking permission to uri " + uri);
7499            }
7500            if (uri == null) {
7501                Slog.w(TAG, "revokeUriPermission: null uri");
7502                return;
7503            }
7504
7505            if (!Intent.isAccessUriMode(modeFlags)) {
7506                return;
7507            }
7508
7509            final IPackageManager pm = AppGlobals.getPackageManager();
7510            final String authority = uri.getAuthority();
7511            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7512            if (pi == null) {
7513                Slog.w(TAG, "No content provider found for permission revoke: "
7514                        + uri.toSafeString());
7515                return;
7516            }
7517
7518            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7519        }
7520    }
7521
7522    /**
7523     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7524     * given package.
7525     *
7526     * @param packageName Package name to match, or {@code null} to apply to all
7527     *            packages.
7528     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7529     *            to all users.
7530     * @param persistable If persistable grants should be removed.
7531     */
7532    private void removeUriPermissionsForPackageLocked(
7533            String packageName, int userHandle, boolean persistable) {
7534        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7535            throw new IllegalArgumentException("Must narrow by either package or user");
7536        }
7537
7538        boolean persistChanged = false;
7539
7540        int N = mGrantedUriPermissions.size();
7541        for (int i = 0; i < N; i++) {
7542            final int targetUid = mGrantedUriPermissions.keyAt(i);
7543            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7544
7545            // Only inspect grants matching user
7546            if (userHandle == UserHandle.USER_ALL
7547                    || userHandle == UserHandle.getUserId(targetUid)) {
7548                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7549                    final UriPermission perm = it.next();
7550
7551                    // Only inspect grants matching package
7552                    if (packageName == null || perm.sourcePkg.equals(packageName)
7553                            || perm.targetPkg.equals(packageName)) {
7554                        persistChanged |= perm.revokeModes(
7555                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7556
7557                        // Only remove when no modes remain; any persisted grants
7558                        // will keep this alive.
7559                        if (perm.modeFlags == 0) {
7560                            it.remove();
7561                        }
7562                    }
7563                }
7564
7565                if (perms.isEmpty()) {
7566                    mGrantedUriPermissions.remove(targetUid);
7567                    N--;
7568                    i--;
7569                }
7570            }
7571        }
7572
7573        if (persistChanged) {
7574            schedulePersistUriGrants();
7575        }
7576    }
7577
7578    @Override
7579    public IBinder newUriPermissionOwner(String name) {
7580        enforceNotIsolatedCaller("newUriPermissionOwner");
7581        synchronized(this) {
7582            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7583            return owner.getExternalTokenLocked();
7584        }
7585    }
7586
7587    /**
7588     * @param uri This uri must NOT contain an embedded userId.
7589     * @param sourceUserId The userId in which the uri is to be resolved.
7590     * @param targetUserId The userId of the app that receives the grant.
7591     */
7592    @Override
7593    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7594            final int modeFlags, int sourceUserId, int targetUserId) {
7595        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7596                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7597        synchronized(this) {
7598            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7599            if (owner == null) {
7600                throw new IllegalArgumentException("Unknown owner: " + token);
7601            }
7602            if (fromUid != Binder.getCallingUid()) {
7603                if (Binder.getCallingUid() != Process.myUid()) {
7604                    // Only system code can grant URI permissions on behalf
7605                    // of other users.
7606                    throw new SecurityException("nice try");
7607                }
7608            }
7609            if (targetPkg == null) {
7610                throw new IllegalArgumentException("null target");
7611            }
7612            if (uri == null) {
7613                throw new IllegalArgumentException("null uri");
7614            }
7615
7616            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7617                    modeFlags, owner, targetUserId);
7618        }
7619    }
7620
7621    /**
7622     * @param uri This uri must NOT contain an embedded userId.
7623     * @param userId The userId in which the uri is to be resolved.
7624     */
7625    @Override
7626    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7627        synchronized(this) {
7628            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7629            if (owner == null) {
7630                throw new IllegalArgumentException("Unknown owner: " + token);
7631            }
7632
7633            if (uri == null) {
7634                owner.removeUriPermissionsLocked(mode);
7635            } else {
7636                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7637            }
7638        }
7639    }
7640
7641    private void schedulePersistUriGrants() {
7642        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7643            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7644                    10 * DateUtils.SECOND_IN_MILLIS);
7645        }
7646    }
7647
7648    private void writeGrantedUriPermissions() {
7649        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7650
7651        // Snapshot permissions so we can persist without lock
7652        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7653        synchronized (this) {
7654            final int size = mGrantedUriPermissions.size();
7655            for (int i = 0; i < size; i++) {
7656                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7657                for (UriPermission perm : perms.values()) {
7658                    if (perm.persistedModeFlags != 0) {
7659                        persist.add(perm.snapshot());
7660                    }
7661                }
7662            }
7663        }
7664
7665        FileOutputStream fos = null;
7666        try {
7667            fos = mGrantFile.startWrite();
7668
7669            XmlSerializer out = new FastXmlSerializer();
7670            out.setOutput(fos, "utf-8");
7671            out.startDocument(null, true);
7672            out.startTag(null, TAG_URI_GRANTS);
7673            for (UriPermission.Snapshot perm : persist) {
7674                out.startTag(null, TAG_URI_GRANT);
7675                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7676                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7677                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7678                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7679                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7680                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7681                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7682                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7683                out.endTag(null, TAG_URI_GRANT);
7684            }
7685            out.endTag(null, TAG_URI_GRANTS);
7686            out.endDocument();
7687
7688            mGrantFile.finishWrite(fos);
7689        } catch (IOException e) {
7690            if (fos != null) {
7691                mGrantFile.failWrite(fos);
7692            }
7693        }
7694    }
7695
7696    private void readGrantedUriPermissionsLocked() {
7697        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7698
7699        final long now = System.currentTimeMillis();
7700
7701        FileInputStream fis = null;
7702        try {
7703            fis = mGrantFile.openRead();
7704            final XmlPullParser in = Xml.newPullParser();
7705            in.setInput(fis, null);
7706
7707            int type;
7708            while ((type = in.next()) != END_DOCUMENT) {
7709                final String tag = in.getName();
7710                if (type == START_TAG) {
7711                    if (TAG_URI_GRANT.equals(tag)) {
7712                        final int sourceUserId;
7713                        final int targetUserId;
7714                        final int userHandle = readIntAttribute(in,
7715                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7716                        if (userHandle != UserHandle.USER_NULL) {
7717                            // For backwards compatibility.
7718                            sourceUserId = userHandle;
7719                            targetUserId = userHandle;
7720                        } else {
7721                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7722                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7723                        }
7724                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7725                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7726                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7727                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7728                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7729                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7730
7731                        // Sanity check that provider still belongs to source package
7732                        final ProviderInfo pi = getProviderInfoLocked(
7733                                uri.getAuthority(), sourceUserId);
7734                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7735                            int targetUid = -1;
7736                            try {
7737                                targetUid = AppGlobals.getPackageManager()
7738                                        .getPackageUid(targetPkg, targetUserId);
7739                            } catch (RemoteException e) {
7740                            }
7741                            if (targetUid != -1) {
7742                                final UriPermission perm = findOrCreateUriPermissionLocked(
7743                                        sourcePkg, targetPkg, targetUid,
7744                                        new GrantUri(sourceUserId, uri, prefix));
7745                                perm.initPersistedModes(modeFlags, createdTime);
7746                            }
7747                        } else {
7748                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7749                                    + " but instead found " + pi);
7750                        }
7751                    }
7752                }
7753            }
7754        } catch (FileNotFoundException e) {
7755            // Missing grants is okay
7756        } catch (IOException e) {
7757            Log.wtf(TAG, "Failed reading Uri grants", e);
7758        } catch (XmlPullParserException e) {
7759            Log.wtf(TAG, "Failed reading Uri grants", e);
7760        } finally {
7761            IoUtils.closeQuietly(fis);
7762        }
7763    }
7764
7765    /**
7766     * @param uri This uri must NOT contain an embedded userId.
7767     * @param userId The userId in which the uri is to be resolved.
7768     */
7769    @Override
7770    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7771        enforceNotIsolatedCaller("takePersistableUriPermission");
7772
7773        Preconditions.checkFlagsArgument(modeFlags,
7774                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7775
7776        synchronized (this) {
7777            final int callingUid = Binder.getCallingUid();
7778            boolean persistChanged = false;
7779            GrantUri grantUri = new GrantUri(userId, uri, false);
7780
7781            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7782                    new GrantUri(userId, uri, false));
7783            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7784                    new GrantUri(userId, uri, true));
7785
7786            final boolean exactValid = (exactPerm != null)
7787                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7788            final boolean prefixValid = (prefixPerm != null)
7789                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7790
7791            if (!(exactValid || prefixValid)) {
7792                throw new SecurityException("No persistable permission grants found for UID "
7793                        + callingUid + " and Uri " + grantUri.toSafeString());
7794            }
7795
7796            if (exactValid) {
7797                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7798            }
7799            if (prefixValid) {
7800                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7801            }
7802
7803            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7804
7805            if (persistChanged) {
7806                schedulePersistUriGrants();
7807            }
7808        }
7809    }
7810
7811    /**
7812     * @param uri This uri must NOT contain an embedded userId.
7813     * @param userId The userId in which the uri is to be resolved.
7814     */
7815    @Override
7816    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7817        enforceNotIsolatedCaller("releasePersistableUriPermission");
7818
7819        Preconditions.checkFlagsArgument(modeFlags,
7820                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7821
7822        synchronized (this) {
7823            final int callingUid = Binder.getCallingUid();
7824            boolean persistChanged = false;
7825
7826            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7827                    new GrantUri(userId, uri, false));
7828            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7829                    new GrantUri(userId, uri, true));
7830            if (exactPerm == null && prefixPerm == null) {
7831                throw new SecurityException("No permission grants found for UID " + callingUid
7832                        + " and Uri " + uri.toSafeString());
7833            }
7834
7835            if (exactPerm != null) {
7836                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7837                removeUriPermissionIfNeededLocked(exactPerm);
7838            }
7839            if (prefixPerm != null) {
7840                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7841                removeUriPermissionIfNeededLocked(prefixPerm);
7842            }
7843
7844            if (persistChanged) {
7845                schedulePersistUriGrants();
7846            }
7847        }
7848    }
7849
7850    /**
7851     * Prune any older {@link UriPermission} for the given UID until outstanding
7852     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7853     *
7854     * @return if any mutations occured that require persisting.
7855     */
7856    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7857        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7858        if (perms == null) return false;
7859        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7860
7861        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7862        for (UriPermission perm : perms.values()) {
7863            if (perm.persistedModeFlags != 0) {
7864                persisted.add(perm);
7865            }
7866        }
7867
7868        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7869        if (trimCount <= 0) return false;
7870
7871        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7872        for (int i = 0; i < trimCount; i++) {
7873            final UriPermission perm = persisted.get(i);
7874
7875            if (DEBUG_URI_PERMISSION) {
7876                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7877            }
7878
7879            perm.releasePersistableModes(~0);
7880            removeUriPermissionIfNeededLocked(perm);
7881        }
7882
7883        return true;
7884    }
7885
7886    @Override
7887    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7888            String packageName, boolean incoming) {
7889        enforceNotIsolatedCaller("getPersistedUriPermissions");
7890        Preconditions.checkNotNull(packageName, "packageName");
7891
7892        final int callingUid = Binder.getCallingUid();
7893        final IPackageManager pm = AppGlobals.getPackageManager();
7894        try {
7895            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7896            if (packageUid != callingUid) {
7897                throw new SecurityException(
7898                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7899            }
7900        } catch (RemoteException e) {
7901            throw new SecurityException("Failed to verify package name ownership");
7902        }
7903
7904        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7905        synchronized (this) {
7906            if (incoming) {
7907                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7908                        callingUid);
7909                if (perms == null) {
7910                    Slog.w(TAG, "No permission grants found for " + packageName);
7911                } else {
7912                    for (UriPermission perm : perms.values()) {
7913                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7914                            result.add(perm.buildPersistedPublicApiObject());
7915                        }
7916                    }
7917                }
7918            } else {
7919                final int size = mGrantedUriPermissions.size();
7920                for (int i = 0; i < size; i++) {
7921                    final ArrayMap<GrantUri, UriPermission> perms =
7922                            mGrantedUriPermissions.valueAt(i);
7923                    for (UriPermission perm : perms.values()) {
7924                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7925                            result.add(perm.buildPersistedPublicApiObject());
7926                        }
7927                    }
7928                }
7929            }
7930        }
7931        return new ParceledListSlice<android.content.UriPermission>(result);
7932    }
7933
7934    @Override
7935    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7936        synchronized (this) {
7937            ProcessRecord app =
7938                who != null ? getRecordForAppLocked(who) : null;
7939            if (app == null) return;
7940
7941            Message msg = Message.obtain();
7942            msg.what = WAIT_FOR_DEBUGGER_MSG;
7943            msg.obj = app;
7944            msg.arg1 = waiting ? 1 : 0;
7945            mHandler.sendMessage(msg);
7946        }
7947    }
7948
7949    @Override
7950    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7951        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7952        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7953        outInfo.availMem = Process.getFreeMemory();
7954        outInfo.totalMem = Process.getTotalMemory();
7955        outInfo.threshold = homeAppMem;
7956        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7957        outInfo.hiddenAppThreshold = cachedAppMem;
7958        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7959                ProcessList.SERVICE_ADJ);
7960        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7961                ProcessList.VISIBLE_APP_ADJ);
7962        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7963                ProcessList.FOREGROUND_APP_ADJ);
7964    }
7965
7966    // =========================================================
7967    // TASK MANAGEMENT
7968    // =========================================================
7969
7970    @Override
7971    public List<IAppTask> getAppTasks(String callingPackage) {
7972        int callingUid = Binder.getCallingUid();
7973        long ident = Binder.clearCallingIdentity();
7974
7975        synchronized(this) {
7976            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7977            try {
7978                if (localLOGV) Slog.v(TAG, "getAppTasks");
7979
7980                final int N = mRecentTasks.size();
7981                for (int i = 0; i < N; i++) {
7982                    TaskRecord tr = mRecentTasks.get(i);
7983                    // Skip tasks that do not match the caller.  We don't need to verify
7984                    // callingPackage, because we are also limiting to callingUid and know
7985                    // that will limit to the correct security sandbox.
7986                    if (tr.effectiveUid != callingUid) {
7987                        continue;
7988                    }
7989                    Intent intent = tr.getBaseIntent();
7990                    if (intent == null ||
7991                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7992                        continue;
7993                    }
7994                    ActivityManager.RecentTaskInfo taskInfo =
7995                            createRecentTaskInfoFromTaskRecord(tr);
7996                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7997                    list.add(taskImpl);
7998                }
7999            } finally {
8000                Binder.restoreCallingIdentity(ident);
8001            }
8002            return list;
8003        }
8004    }
8005
8006    @Override
8007    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8008        final int callingUid = Binder.getCallingUid();
8009        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8010
8011        synchronized(this) {
8012            if (localLOGV) Slog.v(
8013                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8014
8015            final boolean allowed = checkCallingPermission(
8016                    android.Manifest.permission.GET_TASKS)
8017                    == PackageManager.PERMISSION_GRANTED;
8018            if (!allowed) {
8019                Slog.w(TAG, "getTasks: caller " + callingUid
8020                        + " does not hold GET_TASKS; limiting output");
8021            }
8022
8023            // TODO: Improve with MRU list from all ActivityStacks.
8024            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8025        }
8026
8027        return list;
8028    }
8029
8030    TaskRecord getMostRecentTask() {
8031        return mRecentTasks.get(0);
8032    }
8033
8034    /**
8035     * Creates a new RecentTaskInfo from a TaskRecord.
8036     */
8037    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8038        // Update the task description to reflect any changes in the task stack
8039        tr.updateTaskDescription();
8040
8041        // Compose the recent task info
8042        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8043        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8044        rti.persistentId = tr.taskId;
8045        rti.baseIntent = new Intent(tr.getBaseIntent());
8046        rti.origActivity = tr.origActivity;
8047        rti.description = tr.lastDescription;
8048        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8049        rti.userId = tr.userId;
8050        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8051        rti.firstActiveTime = tr.firstActiveTime;
8052        rti.lastActiveTime = tr.lastActiveTime;
8053        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8054        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8055        return rti;
8056    }
8057
8058    @Override
8059    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8060        final int callingUid = Binder.getCallingUid();
8061        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8062                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8063
8064        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8065        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8066        synchronized (this) {
8067            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8068                    == PackageManager.PERMISSION_GRANTED;
8069            if (!allowed) {
8070                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8071                        + " does not hold GET_TASKS; limiting output");
8072            }
8073            final boolean detailed = checkCallingPermission(
8074                    android.Manifest.permission.GET_DETAILED_TASKS)
8075                    == PackageManager.PERMISSION_GRANTED;
8076
8077            final int N = mRecentTasks.size();
8078            ArrayList<ActivityManager.RecentTaskInfo> res
8079                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8080                            maxNum < N ? maxNum : N);
8081
8082            final Set<Integer> includedUsers;
8083            if (includeProfiles) {
8084                includedUsers = getProfileIdsLocked(userId);
8085            } else {
8086                includedUsers = new HashSet<Integer>();
8087            }
8088            includedUsers.add(Integer.valueOf(userId));
8089
8090            for (int i=0; i<N && maxNum > 0; i++) {
8091                TaskRecord tr = mRecentTasks.get(i);
8092                // Only add calling user or related users recent tasks
8093                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8094                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8095                    continue;
8096                }
8097
8098                // Return the entry if desired by the caller.  We always return
8099                // the first entry, because callers always expect this to be the
8100                // foreground app.  We may filter others if the caller has
8101                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8102                // we should exclude the entry.
8103
8104                if (i == 0
8105                        || withExcluded
8106                        || (tr.intent == null)
8107                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8108                                == 0)) {
8109                    if (!allowed) {
8110                        // If the caller doesn't have the GET_TASKS permission, then only
8111                        // allow them to see a small subset of tasks -- their own and home.
8112                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8113                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8114                            continue;
8115                        }
8116                    }
8117                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8118                        if (tr.stack != null && tr.stack.isHomeStack()) {
8119                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8120                            continue;
8121                        }
8122                    }
8123                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8124                        // Don't include auto remove tasks that are finished or finishing.
8125                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8126                                + tr);
8127                        continue;
8128                    }
8129                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8130                            && !tr.isAvailable) {
8131                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8132                        continue;
8133                    }
8134
8135                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8136                    if (!detailed) {
8137                        rti.baseIntent.replaceExtras((Bundle)null);
8138                    }
8139
8140                    res.add(rti);
8141                    maxNum--;
8142                }
8143            }
8144            return res;
8145        }
8146    }
8147
8148    private TaskRecord recentTaskForIdLocked(int id) {
8149        final int N = mRecentTasks.size();
8150            for (int i=0; i<N; i++) {
8151                TaskRecord tr = mRecentTasks.get(i);
8152                if (tr.taskId == id) {
8153                    return tr;
8154                }
8155            }
8156            return null;
8157    }
8158
8159    @Override
8160    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8161        synchronized (this) {
8162            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8163                    "getTaskThumbnail()");
8164            TaskRecord tr = recentTaskForIdLocked(id);
8165            if (tr != null) {
8166                return tr.getTaskThumbnailLocked();
8167            }
8168        }
8169        return null;
8170    }
8171
8172    @Override
8173    public int addAppTask(IBinder activityToken, Intent intent,
8174            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8175        final int callingUid = Binder.getCallingUid();
8176        final long callingIdent = Binder.clearCallingIdentity();
8177
8178        try {
8179            synchronized (this) {
8180                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8181                if (r == null) {
8182                    throw new IllegalArgumentException("Activity does not exist; token="
8183                            + activityToken);
8184                }
8185                ComponentName comp = intent.getComponent();
8186                if (comp == null) {
8187                    throw new IllegalArgumentException("Intent " + intent
8188                            + " must specify explicit component");
8189                }
8190                if (thumbnail.getWidth() != mThumbnailWidth
8191                        || thumbnail.getHeight() != mThumbnailHeight) {
8192                    throw new IllegalArgumentException("Bad thumbnail size: got "
8193                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8194                            + mThumbnailWidth + "x" + mThumbnailHeight);
8195                }
8196                if (intent.getSelector() != null) {
8197                    intent.setSelector(null);
8198                }
8199                if (intent.getSourceBounds() != null) {
8200                    intent.setSourceBounds(null);
8201                }
8202                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8203                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8204                        // The caller has added this as an auto-remove task...  that makes no
8205                        // sense, so turn off auto-remove.
8206                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8207                    }
8208                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8209                    // Must be a new task.
8210                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8211                }
8212                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8213                    mLastAddedTaskActivity = null;
8214                }
8215                ActivityInfo ainfo = mLastAddedTaskActivity;
8216                if (ainfo == null) {
8217                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8218                            comp, 0, UserHandle.getUserId(callingUid));
8219                    if (ainfo.applicationInfo.uid != callingUid) {
8220                        throw new SecurityException(
8221                                "Can't add task for another application: target uid="
8222                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8223                    }
8224                }
8225
8226                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8227                        intent, description);
8228
8229                int trimIdx = trimRecentsForTask(task, false);
8230                if (trimIdx >= 0) {
8231                    // If this would have caused a trim, then we'll abort because that
8232                    // means it would be added at the end of the list but then just removed.
8233                    return -1;
8234                }
8235
8236                final int N = mRecentTasks.size();
8237                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8238                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8239                    tr.removedFromRecents(mTaskPersister);
8240                }
8241
8242                task.inRecents = true;
8243                mRecentTasks.add(task);
8244                r.task.stack.addTask(task, false, false);
8245
8246                task.setLastThumbnail(thumbnail);
8247                task.freeLastThumbnail();
8248
8249                return task.taskId;
8250            }
8251        } finally {
8252            Binder.restoreCallingIdentity(callingIdent);
8253        }
8254    }
8255
8256    @Override
8257    public Point getAppTaskThumbnailSize() {
8258        synchronized (this) {
8259            return new Point(mThumbnailWidth,  mThumbnailHeight);
8260        }
8261    }
8262
8263    @Override
8264    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8265        synchronized (this) {
8266            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8267            if (r != null) {
8268                r.taskDescription = td;
8269                r.task.updateTaskDescription();
8270            }
8271        }
8272    }
8273
8274    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8275        mRecentTasks.remove(tr);
8276        tr.removedFromRecents(mTaskPersister);
8277        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8278        Intent baseIntent = new Intent(
8279                tr.intent != null ? tr.intent : tr.affinityIntent);
8280        ComponentName component = baseIntent.getComponent();
8281        if (component == null) {
8282            Slog.w(TAG, "Now component for base intent of task: " + tr);
8283            return;
8284        }
8285
8286        // Find any running services associated with this app.
8287        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8288
8289        if (killProcesses) {
8290            // Find any running processes associated with this app.
8291            final String pkg = component.getPackageName();
8292            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8293            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8294            for (int i=0; i<pmap.size(); i++) {
8295                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8296                for (int j=0; j<uids.size(); j++) {
8297                    ProcessRecord proc = uids.valueAt(j);
8298                    if (proc.userId != tr.userId) {
8299                        continue;
8300                    }
8301                    if (!proc.pkgList.containsKey(pkg)) {
8302                        continue;
8303                    }
8304                    procs.add(proc);
8305                }
8306            }
8307
8308            // Kill the running processes.
8309            for (int i=0; i<procs.size(); i++) {
8310                ProcessRecord pr = procs.get(i);
8311                if (pr == mHomeProcess) {
8312                    // Don't kill the home process along with tasks from the same package.
8313                    continue;
8314                }
8315                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8316                    pr.kill("remove task", true);
8317                } else {
8318                    pr.waitingToKill = "remove task";
8319                }
8320            }
8321        }
8322    }
8323
8324    /**
8325     * Removes the task with the specified task id.
8326     *
8327     * @param taskId Identifier of the task to be removed.
8328     * @param flags Additional operational flags.  May be 0 or
8329     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8330     * @return Returns true if the given task was found and removed.
8331     */
8332    private boolean removeTaskByIdLocked(int taskId, int flags) {
8333        TaskRecord tr = recentTaskForIdLocked(taskId);
8334        if (tr != null) {
8335            tr.removeTaskActivitiesLocked();
8336            cleanUpRemovedTaskLocked(tr, flags);
8337            if (tr.isPersistable) {
8338                notifyTaskPersisterLocked(null, true);
8339            }
8340            return true;
8341        }
8342        return false;
8343    }
8344
8345    @Override
8346    public boolean removeTask(int taskId, int flags) {
8347        synchronized (this) {
8348            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8349                    "removeTask()");
8350            long ident = Binder.clearCallingIdentity();
8351            try {
8352                return removeTaskByIdLocked(taskId, flags);
8353            } finally {
8354                Binder.restoreCallingIdentity(ident);
8355            }
8356        }
8357    }
8358
8359    /**
8360     * TODO: Add mController hook
8361     */
8362    @Override
8363    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8364        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8365                "moveTaskToFront()");
8366
8367        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8368        synchronized(this) {
8369            moveTaskToFrontLocked(taskId, flags, options);
8370        }
8371    }
8372
8373    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8374        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8375                Binder.getCallingUid(), "Task to front")) {
8376            ActivityOptions.abort(options);
8377            return;
8378        }
8379        final long origId = Binder.clearCallingIdentity();
8380        try {
8381            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8382            if (task == null) {
8383                return;
8384            }
8385            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8386                mStackSupervisor.showLockTaskToast();
8387                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8388                return;
8389            }
8390            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8391            if (prev != null && prev.isRecentsActivity()) {
8392                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8393            }
8394            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8395        } finally {
8396            Binder.restoreCallingIdentity(origId);
8397        }
8398        ActivityOptions.abort(options);
8399    }
8400
8401    @Override
8402    public void moveTaskToBack(int taskId) {
8403        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8404                "moveTaskToBack()");
8405
8406        synchronized(this) {
8407            TaskRecord tr = recentTaskForIdLocked(taskId);
8408            if (tr != null) {
8409                if (tr == mStackSupervisor.mLockTaskModeTask) {
8410                    mStackSupervisor.showLockTaskToast();
8411                    return;
8412                }
8413                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8414                ActivityStack stack = tr.stack;
8415                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8416                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8417                            Binder.getCallingUid(), "Task to back")) {
8418                        return;
8419                    }
8420                }
8421                final long origId = Binder.clearCallingIdentity();
8422                try {
8423                    stack.moveTaskToBackLocked(taskId, null);
8424                } finally {
8425                    Binder.restoreCallingIdentity(origId);
8426                }
8427            }
8428        }
8429    }
8430
8431    /**
8432     * Moves an activity, and all of the other activities within the same task, to the bottom
8433     * of the history stack.  The activity's order within the task is unchanged.
8434     *
8435     * @param token A reference to the activity we wish to move
8436     * @param nonRoot If false then this only works if the activity is the root
8437     *                of a task; if true it will work for any activity in a task.
8438     * @return Returns true if the move completed, false if not.
8439     */
8440    @Override
8441    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8442        enforceNotIsolatedCaller("moveActivityTaskToBack");
8443        synchronized(this) {
8444            final long origId = Binder.clearCallingIdentity();
8445            try {
8446                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8447                if (taskId >= 0) {
8448                    if ((mStackSupervisor.mLockTaskModeTask != null)
8449                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8450                        mStackSupervisor.showLockTaskToast();
8451                        return false;
8452                    }
8453                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8454                }
8455            } finally {
8456                Binder.restoreCallingIdentity(origId);
8457            }
8458        }
8459        return false;
8460    }
8461
8462    @Override
8463    public void moveTaskBackwards(int task) {
8464        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8465                "moveTaskBackwards()");
8466
8467        synchronized(this) {
8468            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8469                    Binder.getCallingUid(), "Task backwards")) {
8470                return;
8471            }
8472            final long origId = Binder.clearCallingIdentity();
8473            moveTaskBackwardsLocked(task);
8474            Binder.restoreCallingIdentity(origId);
8475        }
8476    }
8477
8478    private final void moveTaskBackwardsLocked(int task) {
8479        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8480    }
8481
8482    @Override
8483    public IBinder getHomeActivityToken() throws RemoteException {
8484        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8485                "getHomeActivityToken()");
8486        synchronized (this) {
8487            return mStackSupervisor.getHomeActivityToken();
8488        }
8489    }
8490
8491    @Override
8492    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8493            IActivityContainerCallback callback) throws RemoteException {
8494        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8495                "createActivityContainer()");
8496        synchronized (this) {
8497            if (parentActivityToken == null) {
8498                throw new IllegalArgumentException("parent token must not be null");
8499            }
8500            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8501            if (r == null) {
8502                return null;
8503            }
8504            if (callback == null) {
8505                throw new IllegalArgumentException("callback must not be null");
8506            }
8507            return mStackSupervisor.createActivityContainer(r, callback);
8508        }
8509    }
8510
8511    @Override
8512    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8513        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8514                "deleteActivityContainer()");
8515        synchronized (this) {
8516            mStackSupervisor.deleteActivityContainer(container);
8517        }
8518    }
8519
8520    @Override
8521    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8522            throws RemoteException {
8523        synchronized (this) {
8524            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8525            if (stack != null) {
8526                return stack.mActivityContainer;
8527            }
8528            return null;
8529        }
8530    }
8531
8532    @Override
8533    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8534        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8535                "moveTaskToStack()");
8536        if (stackId == HOME_STACK_ID) {
8537            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8538                    new RuntimeException("here").fillInStackTrace());
8539        }
8540        synchronized (this) {
8541            long ident = Binder.clearCallingIdentity();
8542            try {
8543                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8544                        + stackId + " toTop=" + toTop);
8545                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8546            } finally {
8547                Binder.restoreCallingIdentity(ident);
8548            }
8549        }
8550    }
8551
8552    @Override
8553    public void resizeStack(int stackBoxId, Rect bounds) {
8554        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8555                "resizeStackBox()");
8556        long ident = Binder.clearCallingIdentity();
8557        try {
8558            mWindowManager.resizeStack(stackBoxId, bounds);
8559        } finally {
8560            Binder.restoreCallingIdentity(ident);
8561        }
8562    }
8563
8564    @Override
8565    public List<StackInfo> getAllStackInfos() {
8566        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8567                "getAllStackInfos()");
8568        long ident = Binder.clearCallingIdentity();
8569        try {
8570            synchronized (this) {
8571                return mStackSupervisor.getAllStackInfosLocked();
8572            }
8573        } finally {
8574            Binder.restoreCallingIdentity(ident);
8575        }
8576    }
8577
8578    @Override
8579    public StackInfo getStackInfo(int stackId) {
8580        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8581                "getStackInfo()");
8582        long ident = Binder.clearCallingIdentity();
8583        try {
8584            synchronized (this) {
8585                return mStackSupervisor.getStackInfoLocked(stackId);
8586            }
8587        } finally {
8588            Binder.restoreCallingIdentity(ident);
8589        }
8590    }
8591
8592    @Override
8593    public boolean isInHomeStack(int taskId) {
8594        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8595                "getStackInfo()");
8596        long ident = Binder.clearCallingIdentity();
8597        try {
8598            synchronized (this) {
8599                TaskRecord tr = recentTaskForIdLocked(taskId);
8600                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8601            }
8602        } finally {
8603            Binder.restoreCallingIdentity(ident);
8604        }
8605    }
8606
8607    @Override
8608    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8609        synchronized(this) {
8610            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8611        }
8612    }
8613
8614    private boolean isLockTaskAuthorized(String pkg) {
8615        final DevicePolicyManager dpm = (DevicePolicyManager)
8616                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8617        try {
8618            int uid = mContext.getPackageManager().getPackageUid(pkg,
8619                    Binder.getCallingUserHandle().getIdentifier());
8620            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8621        } catch (NameNotFoundException e) {
8622            return false;
8623        }
8624    }
8625
8626    void startLockTaskMode(TaskRecord task) {
8627        final String pkg;
8628        synchronized (this) {
8629            pkg = task.intent.getComponent().getPackageName();
8630        }
8631        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8632        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8633            final TaskRecord taskRecord = task;
8634            mHandler.post(new Runnable() {
8635                @Override
8636                public void run() {
8637                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8638                }
8639            });
8640            return;
8641        }
8642        long ident = Binder.clearCallingIdentity();
8643        try {
8644            synchronized (this) {
8645                // Since we lost lock on task, make sure it is still there.
8646                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8647                if (task != null) {
8648                    if (!isSystemInitiated
8649                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8650                        throw new IllegalArgumentException("Invalid task, not in foreground");
8651                    }
8652                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8653                }
8654            }
8655        } finally {
8656            Binder.restoreCallingIdentity(ident);
8657        }
8658    }
8659
8660    @Override
8661    public void startLockTaskMode(int taskId) {
8662        final TaskRecord task;
8663        long ident = Binder.clearCallingIdentity();
8664        try {
8665            synchronized (this) {
8666                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8667            }
8668        } finally {
8669            Binder.restoreCallingIdentity(ident);
8670        }
8671        if (task != null) {
8672            startLockTaskMode(task);
8673        }
8674    }
8675
8676    @Override
8677    public void startLockTaskMode(IBinder token) {
8678        final TaskRecord task;
8679        long ident = Binder.clearCallingIdentity();
8680        try {
8681            synchronized (this) {
8682                final ActivityRecord r = ActivityRecord.forToken(token);
8683                if (r == null) {
8684                    return;
8685                }
8686                task = r.task;
8687            }
8688        } finally {
8689            Binder.restoreCallingIdentity(ident);
8690        }
8691        if (task != null) {
8692            startLockTaskMode(task);
8693        }
8694    }
8695
8696    @Override
8697    public void startLockTaskModeOnCurrent() throws RemoteException {
8698        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8699                "startLockTaskModeOnCurrent");
8700        ActivityRecord r = null;
8701        synchronized (this) {
8702            r = mStackSupervisor.topRunningActivityLocked();
8703        }
8704        startLockTaskMode(r.task);
8705    }
8706
8707    @Override
8708    public void stopLockTaskMode() {
8709        // Verify that the user matches the package of the intent for the TaskRecord
8710        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8711        // and stopLockTaskMode.
8712        final int callingUid = Binder.getCallingUid();
8713        if (callingUid != Process.SYSTEM_UID) {
8714            try {
8715                String pkg =
8716                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8717                int uid = mContext.getPackageManager().getPackageUid(pkg,
8718                        Binder.getCallingUserHandle().getIdentifier());
8719                if (uid != callingUid) {
8720                    throw new SecurityException("Invalid uid, expected " + uid);
8721                }
8722            } catch (NameNotFoundException e) {
8723                Log.d(TAG, "stopLockTaskMode " + e);
8724                return;
8725            }
8726        }
8727        long ident = Binder.clearCallingIdentity();
8728        try {
8729            Log.d(TAG, "stopLockTaskMode");
8730            // Stop lock task
8731            synchronized (this) {
8732                mStackSupervisor.setLockTaskModeLocked(null, false);
8733            }
8734        } finally {
8735            Binder.restoreCallingIdentity(ident);
8736        }
8737    }
8738
8739    @Override
8740    public void stopLockTaskModeOnCurrent() throws RemoteException {
8741        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8742                "stopLockTaskModeOnCurrent");
8743        long ident = Binder.clearCallingIdentity();
8744        try {
8745            stopLockTaskMode();
8746        } finally {
8747            Binder.restoreCallingIdentity(ident);
8748        }
8749    }
8750
8751    @Override
8752    public boolean isInLockTaskMode() {
8753        synchronized (this) {
8754            return mStackSupervisor.isInLockTaskMode();
8755        }
8756    }
8757
8758    // =========================================================
8759    // CONTENT PROVIDERS
8760    // =========================================================
8761
8762    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8763        List<ProviderInfo> providers = null;
8764        try {
8765            providers = AppGlobals.getPackageManager().
8766                queryContentProviders(app.processName, app.uid,
8767                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8768        } catch (RemoteException ex) {
8769        }
8770        if (DEBUG_MU)
8771            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8772        int userId = app.userId;
8773        if (providers != null) {
8774            int N = providers.size();
8775            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8776            for (int i=0; i<N; i++) {
8777                ProviderInfo cpi =
8778                    (ProviderInfo)providers.get(i);
8779                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8780                        cpi.name, cpi.flags);
8781                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8782                    // This is a singleton provider, but a user besides the
8783                    // default user is asking to initialize a process it runs
8784                    // in...  well, no, it doesn't actually run in this process,
8785                    // it runs in the process of the default user.  Get rid of it.
8786                    providers.remove(i);
8787                    N--;
8788                    i--;
8789                    continue;
8790                }
8791
8792                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8793                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8794                if (cpr == null) {
8795                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8796                    mProviderMap.putProviderByClass(comp, cpr);
8797                }
8798                if (DEBUG_MU)
8799                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8800                app.pubProviders.put(cpi.name, cpr);
8801                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8802                    // Don't add this if it is a platform component that is marked
8803                    // to run in multiple processes, because this is actually
8804                    // part of the framework so doesn't make sense to track as a
8805                    // separate apk in the process.
8806                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8807                            mProcessStats);
8808                }
8809                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8810            }
8811        }
8812        return providers;
8813    }
8814
8815    /**
8816     * Check if {@link ProcessRecord} has a possible chance at accessing the
8817     * given {@link ProviderInfo}. Final permission checking is always done
8818     * in {@link ContentProvider}.
8819     */
8820    private final String checkContentProviderPermissionLocked(
8821            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8822        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8823        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8824        boolean checkedGrants = false;
8825        if (checkUser) {
8826            // Looking for cross-user grants before enforcing the typical cross-users permissions
8827            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8828            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8829                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8830                    return null;
8831                }
8832                checkedGrants = true;
8833            }
8834            userId = handleIncomingUser(callingPid, callingUid, userId,
8835                    false, ALLOW_NON_FULL,
8836                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8837            if (userId != tmpTargetUserId) {
8838                // When we actually went to determine the final targer user ID, this ended
8839                // up different than our initial check for the authority.  This is because
8840                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8841                // SELF.  So we need to re-check the grants again.
8842                checkedGrants = false;
8843            }
8844        }
8845        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8846                cpi.applicationInfo.uid, cpi.exported)
8847                == PackageManager.PERMISSION_GRANTED) {
8848            return null;
8849        }
8850        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8851                cpi.applicationInfo.uid, cpi.exported)
8852                == PackageManager.PERMISSION_GRANTED) {
8853            return null;
8854        }
8855
8856        PathPermission[] pps = cpi.pathPermissions;
8857        if (pps != null) {
8858            int i = pps.length;
8859            while (i > 0) {
8860                i--;
8861                PathPermission pp = pps[i];
8862                String pprperm = pp.getReadPermission();
8863                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8864                        cpi.applicationInfo.uid, cpi.exported)
8865                        == PackageManager.PERMISSION_GRANTED) {
8866                    return null;
8867                }
8868                String ppwperm = pp.getWritePermission();
8869                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8870                        cpi.applicationInfo.uid, cpi.exported)
8871                        == PackageManager.PERMISSION_GRANTED) {
8872                    return null;
8873                }
8874            }
8875        }
8876        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8877            return null;
8878        }
8879
8880        String msg;
8881        if (!cpi.exported) {
8882            msg = "Permission Denial: opening provider " + cpi.name
8883                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8884                    + ", uid=" + callingUid + ") that is not exported from uid "
8885                    + cpi.applicationInfo.uid;
8886        } else {
8887            msg = "Permission Denial: opening provider " + cpi.name
8888                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8889                    + ", uid=" + callingUid + ") requires "
8890                    + cpi.readPermission + " or " + cpi.writePermission;
8891        }
8892        Slog.w(TAG, msg);
8893        return msg;
8894    }
8895
8896    /**
8897     * Returns if the ContentProvider has granted a uri to callingUid
8898     */
8899    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8900        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8901        if (perms != null) {
8902            for (int i=perms.size()-1; i>=0; i--) {
8903                GrantUri grantUri = perms.keyAt(i);
8904                if (grantUri.sourceUserId == userId || !checkUser) {
8905                    if (matchesProvider(grantUri.uri, cpi)) {
8906                        return true;
8907                    }
8908                }
8909            }
8910        }
8911        return false;
8912    }
8913
8914    /**
8915     * Returns true if the uri authority is one of the authorities specified in the provider.
8916     */
8917    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8918        String uriAuth = uri.getAuthority();
8919        String cpiAuth = cpi.authority;
8920        if (cpiAuth.indexOf(';') == -1) {
8921            return cpiAuth.equals(uriAuth);
8922        }
8923        String[] cpiAuths = cpiAuth.split(";");
8924        int length = cpiAuths.length;
8925        for (int i = 0; i < length; i++) {
8926            if (cpiAuths[i].equals(uriAuth)) return true;
8927        }
8928        return false;
8929    }
8930
8931    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8932            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8933        if (r != null) {
8934            for (int i=0; i<r.conProviders.size(); i++) {
8935                ContentProviderConnection conn = r.conProviders.get(i);
8936                if (conn.provider == cpr) {
8937                    if (DEBUG_PROVIDER) Slog.v(TAG,
8938                            "Adding provider requested by "
8939                            + r.processName + " from process "
8940                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8941                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8942                    if (stable) {
8943                        conn.stableCount++;
8944                        conn.numStableIncs++;
8945                    } else {
8946                        conn.unstableCount++;
8947                        conn.numUnstableIncs++;
8948                    }
8949                    return conn;
8950                }
8951            }
8952            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8953            if (stable) {
8954                conn.stableCount = 1;
8955                conn.numStableIncs = 1;
8956            } else {
8957                conn.unstableCount = 1;
8958                conn.numUnstableIncs = 1;
8959            }
8960            cpr.connections.add(conn);
8961            r.conProviders.add(conn);
8962            return conn;
8963        }
8964        cpr.addExternalProcessHandleLocked(externalProcessToken);
8965        return null;
8966    }
8967
8968    boolean decProviderCountLocked(ContentProviderConnection conn,
8969            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8970        if (conn != null) {
8971            cpr = conn.provider;
8972            if (DEBUG_PROVIDER) Slog.v(TAG,
8973                    "Removing provider requested by "
8974                    + conn.client.processName + " from process "
8975                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8976                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8977            if (stable) {
8978                conn.stableCount--;
8979            } else {
8980                conn.unstableCount--;
8981            }
8982            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8983                cpr.connections.remove(conn);
8984                conn.client.conProviders.remove(conn);
8985                return true;
8986            }
8987            return false;
8988        }
8989        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8990        return false;
8991    }
8992
8993    private void checkTime(long startTime, String where) {
8994        long now = SystemClock.elapsedRealtime();
8995        if ((now-startTime) > 1000) {
8996            // If we are taking more than a second, log about it.
8997            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8998        }
8999    }
9000
9001    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9002            String name, IBinder token, boolean stable, int userId) {
9003        ContentProviderRecord cpr;
9004        ContentProviderConnection conn = null;
9005        ProviderInfo cpi = null;
9006
9007        synchronized(this) {
9008            long startTime = SystemClock.elapsedRealtime();
9009
9010            ProcessRecord r = null;
9011            if (caller != null) {
9012                r = getRecordForAppLocked(caller);
9013                if (r == null) {
9014                    throw new SecurityException(
9015                            "Unable to find app for caller " + caller
9016                          + " (pid=" + Binder.getCallingPid()
9017                          + ") when getting content provider " + name);
9018                }
9019            }
9020
9021            boolean checkCrossUser = true;
9022
9023            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9024
9025            // First check if this content provider has been published...
9026            cpr = mProviderMap.getProviderByName(name, userId);
9027            // If that didn't work, check if it exists for user 0 and then
9028            // verify that it's a singleton provider before using it.
9029            if (cpr == null && userId != UserHandle.USER_OWNER) {
9030                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9031                if (cpr != null) {
9032                    cpi = cpr.info;
9033                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9034                            cpi.name, cpi.flags)
9035                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9036                        userId = UserHandle.USER_OWNER;
9037                        checkCrossUser = false;
9038                    } else {
9039                        cpr = null;
9040                        cpi = null;
9041                    }
9042                }
9043            }
9044
9045            boolean providerRunning = cpr != null;
9046            if (providerRunning) {
9047                cpi = cpr.info;
9048                String msg;
9049                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9050                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9051                        != null) {
9052                    throw new SecurityException(msg);
9053                }
9054                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9055
9056                if (r != null && cpr.canRunHere(r)) {
9057                    // This provider has been published or is in the process
9058                    // of being published...  but it is also allowed to run
9059                    // in the caller's process, so don't make a connection
9060                    // and just let the caller instantiate its own instance.
9061                    ContentProviderHolder holder = cpr.newHolder(null);
9062                    // don't give caller the provider object, it needs
9063                    // to make its own.
9064                    holder.provider = null;
9065                    return holder;
9066                }
9067
9068                final long origId = Binder.clearCallingIdentity();
9069
9070                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9071
9072                // In this case the provider instance already exists, so we can
9073                // return it right away.
9074                conn = incProviderCountLocked(r, cpr, token, stable);
9075                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9076                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9077                        // If this is a perceptible app accessing the provider,
9078                        // make sure to count it as being accessed and thus
9079                        // back up on the LRU list.  This is good because
9080                        // content providers are often expensive to start.
9081                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9082                        updateLruProcessLocked(cpr.proc, false, null);
9083                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9084                    }
9085                }
9086
9087                if (cpr.proc != null) {
9088                    if (false) {
9089                        if (cpr.name.flattenToShortString().equals(
9090                                "com.android.providers.calendar/.CalendarProvider2")) {
9091                            Slog.v(TAG, "****************** KILLING "
9092                                + cpr.name.flattenToShortString());
9093                            Process.killProcess(cpr.proc.pid);
9094                        }
9095                    }
9096                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9097                    boolean success = updateOomAdjLocked(cpr.proc);
9098                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9099                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9100                    // NOTE: there is still a race here where a signal could be
9101                    // pending on the process even though we managed to update its
9102                    // adj level.  Not sure what to do about this, but at least
9103                    // the race is now smaller.
9104                    if (!success) {
9105                        // Uh oh...  it looks like the provider's process
9106                        // has been killed on us.  We need to wait for a new
9107                        // process to be started, and make sure its death
9108                        // doesn't kill our process.
9109                        Slog.i(TAG,
9110                                "Existing provider " + cpr.name.flattenToShortString()
9111                                + " is crashing; detaching " + r);
9112                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9113                        checkTime(startTime, "getContentProviderImpl: before appDied");
9114                        appDiedLocked(cpr.proc);
9115                        checkTime(startTime, "getContentProviderImpl: after appDied");
9116                        if (!lastRef) {
9117                            // This wasn't the last ref our process had on
9118                            // the provider...  we have now been killed, bail.
9119                            return null;
9120                        }
9121                        providerRunning = false;
9122                        conn = null;
9123                    }
9124                }
9125
9126                Binder.restoreCallingIdentity(origId);
9127            }
9128
9129            boolean singleton;
9130            if (!providerRunning) {
9131                try {
9132                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9133                    cpi = AppGlobals.getPackageManager().
9134                        resolveContentProvider(name,
9135                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9136                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9137                } catch (RemoteException ex) {
9138                }
9139                if (cpi == null) {
9140                    return null;
9141                }
9142                // If the provider is a singleton AND
9143                // (it's a call within the same user || the provider is a
9144                // privileged app)
9145                // Then allow connecting to the singleton provider
9146                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9147                        cpi.name, cpi.flags)
9148                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9149                if (singleton) {
9150                    userId = UserHandle.USER_OWNER;
9151                }
9152                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9153                checkTime(startTime, "getContentProviderImpl: got app info for user");
9154
9155                String msg;
9156                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9157                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9158                        != null) {
9159                    throw new SecurityException(msg);
9160                }
9161                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9162
9163                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9164                        && !cpi.processName.equals("system")) {
9165                    // If this content provider does not run in the system
9166                    // process, and the system is not yet ready to run other
9167                    // processes, then fail fast instead of hanging.
9168                    throw new IllegalArgumentException(
9169                            "Attempt to launch content provider before system ready");
9170                }
9171
9172                // Make sure that the user who owns this provider is started.  If not,
9173                // we don't want to allow it to run.
9174                if (mStartedUsers.get(userId) == null) {
9175                    Slog.w(TAG, "Unable to launch app "
9176                            + cpi.applicationInfo.packageName + "/"
9177                            + cpi.applicationInfo.uid + " for provider "
9178                            + name + ": user " + userId + " is stopped");
9179                    return null;
9180                }
9181
9182                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9183                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9184                cpr = mProviderMap.getProviderByClass(comp, userId);
9185                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9186                final boolean firstClass = cpr == null;
9187                if (firstClass) {
9188                    try {
9189                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9190                        ApplicationInfo ai =
9191                            AppGlobals.getPackageManager().
9192                                getApplicationInfo(
9193                                        cpi.applicationInfo.packageName,
9194                                        STOCK_PM_FLAGS, userId);
9195                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9196                        if (ai == null) {
9197                            Slog.w(TAG, "No package info for content provider "
9198                                    + cpi.name);
9199                            return null;
9200                        }
9201                        ai = getAppInfoForUser(ai, userId);
9202                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9203                    } catch (RemoteException ex) {
9204                        // pm is in same process, this will never happen.
9205                    }
9206                }
9207
9208                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9209
9210                if (r != null && cpr.canRunHere(r)) {
9211                    // If this is a multiprocess provider, then just return its
9212                    // info and allow the caller to instantiate it.  Only do
9213                    // this if the provider is the same user as the caller's
9214                    // process, or can run as root (so can be in any process).
9215                    return cpr.newHolder(null);
9216                }
9217
9218                if (DEBUG_PROVIDER) {
9219                    RuntimeException e = new RuntimeException("here");
9220                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9221                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9222                }
9223
9224                // This is single process, and our app is now connecting to it.
9225                // See if we are already in the process of launching this
9226                // provider.
9227                final int N = mLaunchingProviders.size();
9228                int i;
9229                for (i=0; i<N; i++) {
9230                    if (mLaunchingProviders.get(i) == cpr) {
9231                        break;
9232                    }
9233                }
9234
9235                // If the provider is not already being launched, then get it
9236                // started.
9237                if (i >= N) {
9238                    final long origId = Binder.clearCallingIdentity();
9239
9240                    try {
9241                        // Content provider is now in use, its package can't be stopped.
9242                        try {
9243                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9244                            AppGlobals.getPackageManager().setPackageStoppedState(
9245                                    cpr.appInfo.packageName, false, userId);
9246                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9247                        } catch (RemoteException e) {
9248                        } catch (IllegalArgumentException e) {
9249                            Slog.w(TAG, "Failed trying to unstop package "
9250                                    + cpr.appInfo.packageName + ": " + e);
9251                        }
9252
9253                        // Use existing process if already started
9254                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9255                        ProcessRecord proc = getProcessRecordLocked(
9256                                cpi.processName, cpr.appInfo.uid, false);
9257                        if (proc != null && proc.thread != null) {
9258                            if (DEBUG_PROVIDER) {
9259                                Slog.d(TAG, "Installing in existing process " + proc);
9260                            }
9261                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9262                            proc.pubProviders.put(cpi.name, cpr);
9263                            try {
9264                                proc.thread.scheduleInstallProvider(cpi);
9265                            } catch (RemoteException e) {
9266                            }
9267                        } else {
9268                            checkTime(startTime, "getContentProviderImpl: before start process");
9269                            proc = startProcessLocked(cpi.processName,
9270                                    cpr.appInfo, false, 0, "content provider",
9271                                    new ComponentName(cpi.applicationInfo.packageName,
9272                                            cpi.name), false, false, false);
9273                            checkTime(startTime, "getContentProviderImpl: after start process");
9274                            if (proc == null) {
9275                                Slog.w(TAG, "Unable to launch app "
9276                                        + cpi.applicationInfo.packageName + "/"
9277                                        + cpi.applicationInfo.uid + " for provider "
9278                                        + name + ": process is bad");
9279                                return null;
9280                            }
9281                        }
9282                        cpr.launchingApp = proc;
9283                        mLaunchingProviders.add(cpr);
9284                    } finally {
9285                        Binder.restoreCallingIdentity(origId);
9286                    }
9287                }
9288
9289                checkTime(startTime, "getContentProviderImpl: updating data structures");
9290
9291                // Make sure the provider is published (the same provider class
9292                // may be published under multiple names).
9293                if (firstClass) {
9294                    mProviderMap.putProviderByClass(comp, cpr);
9295                }
9296
9297                mProviderMap.putProviderByName(name, cpr);
9298                conn = incProviderCountLocked(r, cpr, token, stable);
9299                if (conn != null) {
9300                    conn.waiting = true;
9301                }
9302            }
9303            checkTime(startTime, "getContentProviderImpl: done!");
9304        }
9305
9306        // Wait for the provider to be published...
9307        synchronized (cpr) {
9308            while (cpr.provider == null) {
9309                if (cpr.launchingApp == null) {
9310                    Slog.w(TAG, "Unable to launch app "
9311                            + cpi.applicationInfo.packageName + "/"
9312                            + cpi.applicationInfo.uid + " for provider "
9313                            + name + ": launching app became null");
9314                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9315                            UserHandle.getUserId(cpi.applicationInfo.uid),
9316                            cpi.applicationInfo.packageName,
9317                            cpi.applicationInfo.uid, name);
9318                    return null;
9319                }
9320                try {
9321                    if (DEBUG_MU) {
9322                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9323                                + cpr.launchingApp);
9324                    }
9325                    if (conn != null) {
9326                        conn.waiting = true;
9327                    }
9328                    cpr.wait();
9329                } catch (InterruptedException ex) {
9330                } finally {
9331                    if (conn != null) {
9332                        conn.waiting = false;
9333                    }
9334                }
9335            }
9336        }
9337        return cpr != null ? cpr.newHolder(conn) : null;
9338    }
9339
9340    @Override
9341    public final ContentProviderHolder getContentProvider(
9342            IApplicationThread caller, String name, int userId, boolean stable) {
9343        enforceNotIsolatedCaller("getContentProvider");
9344        if (caller == null) {
9345            String msg = "null IApplicationThread when getting content provider "
9346                    + name;
9347            Slog.w(TAG, msg);
9348            throw new SecurityException(msg);
9349        }
9350        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9351        // with cross-user grant.
9352        return getContentProviderImpl(caller, name, null, stable, userId);
9353    }
9354
9355    public ContentProviderHolder getContentProviderExternal(
9356            String name, int userId, IBinder token) {
9357        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9358            "Do not have permission in call getContentProviderExternal()");
9359        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9360                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9361        return getContentProviderExternalUnchecked(name, token, userId);
9362    }
9363
9364    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9365            IBinder token, int userId) {
9366        return getContentProviderImpl(null, name, token, true, userId);
9367    }
9368
9369    /**
9370     * Drop a content provider from a ProcessRecord's bookkeeping
9371     */
9372    public void removeContentProvider(IBinder connection, boolean stable) {
9373        enforceNotIsolatedCaller("removeContentProvider");
9374        long ident = Binder.clearCallingIdentity();
9375        try {
9376            synchronized (this) {
9377                ContentProviderConnection conn;
9378                try {
9379                    conn = (ContentProviderConnection)connection;
9380                } catch (ClassCastException e) {
9381                    String msg ="removeContentProvider: " + connection
9382                            + " not a ContentProviderConnection";
9383                    Slog.w(TAG, msg);
9384                    throw new IllegalArgumentException(msg);
9385                }
9386                if (conn == null) {
9387                    throw new NullPointerException("connection is null");
9388                }
9389                if (decProviderCountLocked(conn, null, null, stable)) {
9390                    updateOomAdjLocked();
9391                }
9392            }
9393        } finally {
9394            Binder.restoreCallingIdentity(ident);
9395        }
9396    }
9397
9398    public void removeContentProviderExternal(String name, IBinder token) {
9399        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9400            "Do not have permission in call removeContentProviderExternal()");
9401        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9402    }
9403
9404    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9405        synchronized (this) {
9406            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9407            if(cpr == null) {
9408                //remove from mProvidersByClass
9409                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9410                return;
9411            }
9412
9413            //update content provider record entry info
9414            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9415            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9416            if (localCpr.hasExternalProcessHandles()) {
9417                if (localCpr.removeExternalProcessHandleLocked(token)) {
9418                    updateOomAdjLocked();
9419                } else {
9420                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9421                            + " with no external reference for token: "
9422                            + token + ".");
9423                }
9424            } else {
9425                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9426                        + " with no external references.");
9427            }
9428        }
9429    }
9430
9431    public final void publishContentProviders(IApplicationThread caller,
9432            List<ContentProviderHolder> providers) {
9433        if (providers == null) {
9434            return;
9435        }
9436
9437        enforceNotIsolatedCaller("publishContentProviders");
9438        synchronized (this) {
9439            final ProcessRecord r = getRecordForAppLocked(caller);
9440            if (DEBUG_MU)
9441                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9442            if (r == null) {
9443                throw new SecurityException(
9444                        "Unable to find app for caller " + caller
9445                      + " (pid=" + Binder.getCallingPid()
9446                      + ") when publishing content providers");
9447            }
9448
9449            final long origId = Binder.clearCallingIdentity();
9450
9451            final int N = providers.size();
9452            for (int i=0; i<N; i++) {
9453                ContentProviderHolder src = providers.get(i);
9454                if (src == null || src.info == null || src.provider == null) {
9455                    continue;
9456                }
9457                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9458                if (DEBUG_MU)
9459                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9460                if (dst != null) {
9461                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9462                    mProviderMap.putProviderByClass(comp, dst);
9463                    String names[] = dst.info.authority.split(";");
9464                    for (int j = 0; j < names.length; j++) {
9465                        mProviderMap.putProviderByName(names[j], dst);
9466                    }
9467
9468                    int NL = mLaunchingProviders.size();
9469                    int j;
9470                    for (j=0; j<NL; j++) {
9471                        if (mLaunchingProviders.get(j) == dst) {
9472                            mLaunchingProviders.remove(j);
9473                            j--;
9474                            NL--;
9475                        }
9476                    }
9477                    synchronized (dst) {
9478                        dst.provider = src.provider;
9479                        dst.proc = r;
9480                        dst.notifyAll();
9481                    }
9482                    updateOomAdjLocked(r);
9483                }
9484            }
9485
9486            Binder.restoreCallingIdentity(origId);
9487        }
9488    }
9489
9490    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9491        ContentProviderConnection conn;
9492        try {
9493            conn = (ContentProviderConnection)connection;
9494        } catch (ClassCastException e) {
9495            String msg ="refContentProvider: " + connection
9496                    + " not a ContentProviderConnection";
9497            Slog.w(TAG, msg);
9498            throw new IllegalArgumentException(msg);
9499        }
9500        if (conn == null) {
9501            throw new NullPointerException("connection is null");
9502        }
9503
9504        synchronized (this) {
9505            if (stable > 0) {
9506                conn.numStableIncs += stable;
9507            }
9508            stable = conn.stableCount + stable;
9509            if (stable < 0) {
9510                throw new IllegalStateException("stableCount < 0: " + stable);
9511            }
9512
9513            if (unstable > 0) {
9514                conn.numUnstableIncs += unstable;
9515            }
9516            unstable = conn.unstableCount + unstable;
9517            if (unstable < 0) {
9518                throw new IllegalStateException("unstableCount < 0: " + unstable);
9519            }
9520
9521            if ((stable+unstable) <= 0) {
9522                throw new IllegalStateException("ref counts can't go to zero here: stable="
9523                        + stable + " unstable=" + unstable);
9524            }
9525            conn.stableCount = stable;
9526            conn.unstableCount = unstable;
9527            return !conn.dead;
9528        }
9529    }
9530
9531    public void unstableProviderDied(IBinder connection) {
9532        ContentProviderConnection conn;
9533        try {
9534            conn = (ContentProviderConnection)connection;
9535        } catch (ClassCastException e) {
9536            String msg ="refContentProvider: " + connection
9537                    + " not a ContentProviderConnection";
9538            Slog.w(TAG, msg);
9539            throw new IllegalArgumentException(msg);
9540        }
9541        if (conn == null) {
9542            throw new NullPointerException("connection is null");
9543        }
9544
9545        // Safely retrieve the content provider associated with the connection.
9546        IContentProvider provider;
9547        synchronized (this) {
9548            provider = conn.provider.provider;
9549        }
9550
9551        if (provider == null) {
9552            // Um, yeah, we're way ahead of you.
9553            return;
9554        }
9555
9556        // Make sure the caller is being honest with us.
9557        if (provider.asBinder().pingBinder()) {
9558            // Er, no, still looks good to us.
9559            synchronized (this) {
9560                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9561                        + " says " + conn + " died, but we don't agree");
9562                return;
9563            }
9564        }
9565
9566        // Well look at that!  It's dead!
9567        synchronized (this) {
9568            if (conn.provider.provider != provider) {
9569                // But something changed...  good enough.
9570                return;
9571            }
9572
9573            ProcessRecord proc = conn.provider.proc;
9574            if (proc == null || proc.thread == null) {
9575                // Seems like the process is already cleaned up.
9576                return;
9577            }
9578
9579            // As far as we're concerned, this is just like receiving a
9580            // death notification...  just a bit prematurely.
9581            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9582                    + ") early provider death");
9583            final long ident = Binder.clearCallingIdentity();
9584            try {
9585                appDiedLocked(proc);
9586            } finally {
9587                Binder.restoreCallingIdentity(ident);
9588            }
9589        }
9590    }
9591
9592    @Override
9593    public void appNotRespondingViaProvider(IBinder connection) {
9594        enforceCallingPermission(
9595                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9596
9597        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9598        if (conn == null) {
9599            Slog.w(TAG, "ContentProviderConnection is null");
9600            return;
9601        }
9602
9603        final ProcessRecord host = conn.provider.proc;
9604        if (host == null) {
9605            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9606            return;
9607        }
9608
9609        final long token = Binder.clearCallingIdentity();
9610        try {
9611            appNotResponding(host, null, null, false, "ContentProvider not responding");
9612        } finally {
9613            Binder.restoreCallingIdentity(token);
9614        }
9615    }
9616
9617    public final void installSystemProviders() {
9618        List<ProviderInfo> providers;
9619        synchronized (this) {
9620            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9621            providers = generateApplicationProvidersLocked(app);
9622            if (providers != null) {
9623                for (int i=providers.size()-1; i>=0; i--) {
9624                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9625                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9626                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9627                                + ": not system .apk");
9628                        providers.remove(i);
9629                    }
9630                }
9631            }
9632        }
9633        if (providers != null) {
9634            mSystemThread.installSystemProviders(providers);
9635        }
9636
9637        mCoreSettingsObserver = new CoreSettingsObserver(this);
9638
9639        //mUsageStatsService.monitorPackages();
9640    }
9641
9642    /**
9643     * Allows apps to retrieve the MIME type of a URI.
9644     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9645     * users, then it does not need permission to access the ContentProvider.
9646     * Either, it needs cross-user uri grants.
9647     *
9648     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9649     *
9650     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9651     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9652     */
9653    public String getProviderMimeType(Uri uri, int userId) {
9654        enforceNotIsolatedCaller("getProviderMimeType");
9655        final String name = uri.getAuthority();
9656        int callingUid = Binder.getCallingUid();
9657        int callingPid = Binder.getCallingPid();
9658        long ident = 0;
9659        boolean clearedIdentity = false;
9660        userId = unsafeConvertIncomingUser(userId);
9661        if (UserHandle.getUserId(callingUid) != userId) {
9662            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9663                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9664                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9665                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9666                clearedIdentity = true;
9667                ident = Binder.clearCallingIdentity();
9668            }
9669        }
9670        ContentProviderHolder holder = null;
9671        try {
9672            holder = getContentProviderExternalUnchecked(name, null, userId);
9673            if (holder != null) {
9674                return holder.provider.getType(uri);
9675            }
9676        } catch (RemoteException e) {
9677            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9678            return null;
9679        } finally {
9680            // We need to clear the identity to call removeContentProviderExternalUnchecked
9681            if (!clearedIdentity) {
9682                ident = Binder.clearCallingIdentity();
9683            }
9684            try {
9685                if (holder != null) {
9686                    removeContentProviderExternalUnchecked(name, null, userId);
9687                }
9688            } finally {
9689                Binder.restoreCallingIdentity(ident);
9690            }
9691        }
9692
9693        return null;
9694    }
9695
9696    // =========================================================
9697    // GLOBAL MANAGEMENT
9698    // =========================================================
9699
9700    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9701            boolean isolated, int isolatedUid) {
9702        String proc = customProcess != null ? customProcess : info.processName;
9703        BatteryStatsImpl.Uid.Proc ps = null;
9704        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9705        int uid = info.uid;
9706        if (isolated) {
9707            if (isolatedUid == 0) {
9708                int userId = UserHandle.getUserId(uid);
9709                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9710                while (true) {
9711                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9712                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9713                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9714                    }
9715                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9716                    mNextIsolatedProcessUid++;
9717                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9718                        // No process for this uid, use it.
9719                        break;
9720                    }
9721                    stepsLeft--;
9722                    if (stepsLeft <= 0) {
9723                        return null;
9724                    }
9725                }
9726            } else {
9727                // Special case for startIsolatedProcess (internal only), where
9728                // the uid of the isolated process is specified by the caller.
9729                uid = isolatedUid;
9730            }
9731        }
9732        return new ProcessRecord(stats, info, proc, uid);
9733    }
9734
9735    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9736            String abiOverride) {
9737        ProcessRecord app;
9738        if (!isolated) {
9739            app = getProcessRecordLocked(info.processName, info.uid, true);
9740        } else {
9741            app = null;
9742        }
9743
9744        if (app == null) {
9745            app = newProcessRecordLocked(info, null, isolated, 0);
9746            mProcessNames.put(info.processName, app.uid, app);
9747            if (isolated) {
9748                mIsolatedProcesses.put(app.uid, app);
9749            }
9750            updateLruProcessLocked(app, false, null);
9751            updateOomAdjLocked();
9752        }
9753
9754        // This package really, really can not be stopped.
9755        try {
9756            AppGlobals.getPackageManager().setPackageStoppedState(
9757                    info.packageName, false, UserHandle.getUserId(app.uid));
9758        } catch (RemoteException e) {
9759        } catch (IllegalArgumentException e) {
9760            Slog.w(TAG, "Failed trying to unstop package "
9761                    + info.packageName + ": " + e);
9762        }
9763
9764        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9765                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9766            app.persistent = true;
9767            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9768        }
9769        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9770            mPersistentStartingProcesses.add(app);
9771            startProcessLocked(app, "added application", app.processName, abiOverride,
9772                    null /* entryPoint */, null /* entryPointArgs */);
9773        }
9774
9775        return app;
9776    }
9777
9778    public void unhandledBack() {
9779        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9780                "unhandledBack()");
9781
9782        synchronized(this) {
9783            final long origId = Binder.clearCallingIdentity();
9784            try {
9785                getFocusedStack().unhandledBackLocked();
9786            } finally {
9787                Binder.restoreCallingIdentity(origId);
9788            }
9789        }
9790    }
9791
9792    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9793        enforceNotIsolatedCaller("openContentUri");
9794        final int userId = UserHandle.getCallingUserId();
9795        String name = uri.getAuthority();
9796        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9797        ParcelFileDescriptor pfd = null;
9798        if (cph != null) {
9799            // We record the binder invoker's uid in thread-local storage before
9800            // going to the content provider to open the file.  Later, in the code
9801            // that handles all permissions checks, we look for this uid and use
9802            // that rather than the Activity Manager's own uid.  The effect is that
9803            // we do the check against the caller's permissions even though it looks
9804            // to the content provider like the Activity Manager itself is making
9805            // the request.
9806            sCallerIdentity.set(new Identity(
9807                    Binder.getCallingPid(), Binder.getCallingUid()));
9808            try {
9809                pfd = cph.provider.openFile(null, uri, "r", null);
9810            } catch (FileNotFoundException e) {
9811                // do nothing; pfd will be returned null
9812            } finally {
9813                // Ensure that whatever happens, we clean up the identity state
9814                sCallerIdentity.remove();
9815            }
9816
9817            // We've got the fd now, so we're done with the provider.
9818            removeContentProviderExternalUnchecked(name, null, userId);
9819        } else {
9820            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9821        }
9822        return pfd;
9823    }
9824
9825    // Actually is sleeping or shutting down or whatever else in the future
9826    // is an inactive state.
9827    public boolean isSleepingOrShuttingDown() {
9828        return mSleeping || mShuttingDown;
9829    }
9830
9831    public boolean isSleeping() {
9832        return mSleeping;
9833    }
9834
9835    void goingToSleep() {
9836        synchronized(this) {
9837            mWentToSleep = true;
9838            updateEventDispatchingLocked();
9839            goToSleepIfNeededLocked();
9840        }
9841    }
9842
9843    void finishRunningVoiceLocked() {
9844        if (mRunningVoice) {
9845            mRunningVoice = false;
9846            goToSleepIfNeededLocked();
9847        }
9848    }
9849
9850    void goToSleepIfNeededLocked() {
9851        if (mWentToSleep && !mRunningVoice) {
9852            if (!mSleeping) {
9853                mSleeping = true;
9854                mStackSupervisor.goingToSleepLocked();
9855
9856                // Initialize the wake times of all processes.
9857                checkExcessivePowerUsageLocked(false);
9858                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9859                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9860                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9861            }
9862        }
9863    }
9864
9865    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9866        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9867            // Never persist the home stack.
9868            return;
9869        }
9870        mTaskPersister.wakeup(task, flush);
9871    }
9872
9873    @Override
9874    public boolean shutdown(int timeout) {
9875        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9876                != PackageManager.PERMISSION_GRANTED) {
9877            throw new SecurityException("Requires permission "
9878                    + android.Manifest.permission.SHUTDOWN);
9879        }
9880
9881        boolean timedout = false;
9882
9883        synchronized(this) {
9884            mShuttingDown = true;
9885            updateEventDispatchingLocked();
9886            timedout = mStackSupervisor.shutdownLocked(timeout);
9887        }
9888
9889        mAppOpsService.shutdown();
9890        if (mUsageStatsService != null) {
9891            mUsageStatsService.prepareShutdown();
9892        }
9893        mBatteryStatsService.shutdown();
9894        synchronized (this) {
9895            mProcessStats.shutdownLocked();
9896        }
9897        notifyTaskPersisterLocked(null, true);
9898
9899        return timedout;
9900    }
9901
9902    public final void activitySlept(IBinder token) {
9903        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9904
9905        final long origId = Binder.clearCallingIdentity();
9906
9907        synchronized (this) {
9908            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9909            if (r != null) {
9910                mStackSupervisor.activitySleptLocked(r);
9911            }
9912        }
9913
9914        Binder.restoreCallingIdentity(origId);
9915    }
9916
9917    void logLockScreen(String msg) {
9918        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9919                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9920                mWentToSleep + " mSleeping=" + mSleeping);
9921    }
9922
9923    private void comeOutOfSleepIfNeededLocked() {
9924        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9925            if (mSleeping) {
9926                mSleeping = false;
9927                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9928            }
9929        }
9930    }
9931
9932    void wakingUp() {
9933        synchronized(this) {
9934            mWentToSleep = false;
9935            updateEventDispatchingLocked();
9936            comeOutOfSleepIfNeededLocked();
9937        }
9938    }
9939
9940    void startRunningVoiceLocked() {
9941        if (!mRunningVoice) {
9942            mRunningVoice = true;
9943            comeOutOfSleepIfNeededLocked();
9944        }
9945    }
9946
9947    private void updateEventDispatchingLocked() {
9948        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9949    }
9950
9951    public void setLockScreenShown(boolean shown) {
9952        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9953                != PackageManager.PERMISSION_GRANTED) {
9954            throw new SecurityException("Requires permission "
9955                    + android.Manifest.permission.DEVICE_POWER);
9956        }
9957
9958        synchronized(this) {
9959            long ident = Binder.clearCallingIdentity();
9960            try {
9961                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9962                mLockScreenShown = shown;
9963                comeOutOfSleepIfNeededLocked();
9964            } finally {
9965                Binder.restoreCallingIdentity(ident);
9966            }
9967        }
9968    }
9969
9970    @Override
9971    public void stopAppSwitches() {
9972        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9973                != PackageManager.PERMISSION_GRANTED) {
9974            throw new SecurityException("Requires permission "
9975                    + android.Manifest.permission.STOP_APP_SWITCHES);
9976        }
9977
9978        synchronized(this) {
9979            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9980                    + APP_SWITCH_DELAY_TIME;
9981            mDidAppSwitch = false;
9982            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9983            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9984            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9985        }
9986    }
9987
9988    public void resumeAppSwitches() {
9989        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9990                != PackageManager.PERMISSION_GRANTED) {
9991            throw new SecurityException("Requires permission "
9992                    + android.Manifest.permission.STOP_APP_SWITCHES);
9993        }
9994
9995        synchronized(this) {
9996            // Note that we don't execute any pending app switches... we will
9997            // let those wait until either the timeout, or the next start
9998            // activity request.
9999            mAppSwitchesAllowedTime = 0;
10000        }
10001    }
10002
10003    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10004            String name) {
10005        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10006            return true;
10007        }
10008
10009        final int perm = checkComponentPermission(
10010                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10011                callingUid, -1, true);
10012        if (perm == PackageManager.PERMISSION_GRANTED) {
10013            return true;
10014        }
10015
10016        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10017        return false;
10018    }
10019
10020    public void setDebugApp(String packageName, boolean waitForDebugger,
10021            boolean persistent) {
10022        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10023                "setDebugApp()");
10024
10025        long ident = Binder.clearCallingIdentity();
10026        try {
10027            // Note that this is not really thread safe if there are multiple
10028            // callers into it at the same time, but that's not a situation we
10029            // care about.
10030            if (persistent) {
10031                final ContentResolver resolver = mContext.getContentResolver();
10032                Settings.Global.putString(
10033                    resolver, Settings.Global.DEBUG_APP,
10034                    packageName);
10035                Settings.Global.putInt(
10036                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10037                    waitForDebugger ? 1 : 0);
10038            }
10039
10040            synchronized (this) {
10041                if (!persistent) {
10042                    mOrigDebugApp = mDebugApp;
10043                    mOrigWaitForDebugger = mWaitForDebugger;
10044                }
10045                mDebugApp = packageName;
10046                mWaitForDebugger = waitForDebugger;
10047                mDebugTransient = !persistent;
10048                if (packageName != null) {
10049                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10050                            false, UserHandle.USER_ALL, "set debug app");
10051                }
10052            }
10053        } finally {
10054            Binder.restoreCallingIdentity(ident);
10055        }
10056    }
10057
10058    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10059        synchronized (this) {
10060            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10061            if (!isDebuggable) {
10062                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10063                    throw new SecurityException("Process not debuggable: " + app.packageName);
10064                }
10065            }
10066
10067            mOpenGlTraceApp = processName;
10068        }
10069    }
10070
10071    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10072        synchronized (this) {
10073            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10074            if (!isDebuggable) {
10075                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10076                    throw new SecurityException("Process not debuggable: " + app.packageName);
10077                }
10078            }
10079            mProfileApp = processName;
10080            mProfileFile = profilerInfo.profileFile;
10081            if (mProfileFd != null) {
10082                try {
10083                    mProfileFd.close();
10084                } catch (IOException e) {
10085                }
10086                mProfileFd = null;
10087            }
10088            mProfileFd = profilerInfo.profileFd;
10089            mSamplingInterval = profilerInfo.samplingInterval;
10090            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10091            mProfileType = 0;
10092        }
10093    }
10094
10095    @Override
10096    public void setAlwaysFinish(boolean enabled) {
10097        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10098                "setAlwaysFinish()");
10099
10100        Settings.Global.putInt(
10101                mContext.getContentResolver(),
10102                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10103
10104        synchronized (this) {
10105            mAlwaysFinishActivities = enabled;
10106        }
10107    }
10108
10109    @Override
10110    public void setActivityController(IActivityController controller) {
10111        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10112                "setActivityController()");
10113        synchronized (this) {
10114            mController = controller;
10115            Watchdog.getInstance().setActivityController(controller);
10116        }
10117    }
10118
10119    @Override
10120    public void setUserIsMonkey(boolean userIsMonkey) {
10121        synchronized (this) {
10122            synchronized (mPidsSelfLocked) {
10123                final int callingPid = Binder.getCallingPid();
10124                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10125                if (precessRecord == null) {
10126                    throw new SecurityException("Unknown process: " + callingPid);
10127                }
10128                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10129                    throw new SecurityException("Only an instrumentation process "
10130                            + "with a UiAutomation can call setUserIsMonkey");
10131                }
10132            }
10133            mUserIsMonkey = userIsMonkey;
10134        }
10135    }
10136
10137    @Override
10138    public boolean isUserAMonkey() {
10139        synchronized (this) {
10140            // If there is a controller also implies the user is a monkey.
10141            return (mUserIsMonkey || mController != null);
10142        }
10143    }
10144
10145    public void requestBugReport() {
10146        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10147        SystemProperties.set("ctl.start", "bugreport");
10148    }
10149
10150    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10151        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10152    }
10153
10154    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10155        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10156            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10157        }
10158        return KEY_DISPATCHING_TIMEOUT;
10159    }
10160
10161    @Override
10162    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10163        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10164                != PackageManager.PERMISSION_GRANTED) {
10165            throw new SecurityException("Requires permission "
10166                    + android.Manifest.permission.FILTER_EVENTS);
10167        }
10168        ProcessRecord proc;
10169        long timeout;
10170        synchronized (this) {
10171            synchronized (mPidsSelfLocked) {
10172                proc = mPidsSelfLocked.get(pid);
10173            }
10174            timeout = getInputDispatchingTimeoutLocked(proc);
10175        }
10176
10177        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10178            return -1;
10179        }
10180
10181        return timeout;
10182    }
10183
10184    /**
10185     * Handle input dispatching timeouts.
10186     * Returns whether input dispatching should be aborted or not.
10187     */
10188    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10189            final ActivityRecord activity, final ActivityRecord parent,
10190            final boolean aboveSystem, String reason) {
10191        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10192                != PackageManager.PERMISSION_GRANTED) {
10193            throw new SecurityException("Requires permission "
10194                    + android.Manifest.permission.FILTER_EVENTS);
10195        }
10196
10197        final String annotation;
10198        if (reason == null) {
10199            annotation = "Input dispatching timed out";
10200        } else {
10201            annotation = "Input dispatching timed out (" + reason + ")";
10202        }
10203
10204        if (proc != null) {
10205            synchronized (this) {
10206                if (proc.debugging) {
10207                    return false;
10208                }
10209
10210                if (mDidDexOpt) {
10211                    // Give more time since we were dexopting.
10212                    mDidDexOpt = false;
10213                    return false;
10214                }
10215
10216                if (proc.instrumentationClass != null) {
10217                    Bundle info = new Bundle();
10218                    info.putString("shortMsg", "keyDispatchingTimedOut");
10219                    info.putString("longMsg", annotation);
10220                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10221                    return true;
10222                }
10223            }
10224            mHandler.post(new Runnable() {
10225                @Override
10226                public void run() {
10227                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10228                }
10229            });
10230        }
10231
10232        return true;
10233    }
10234
10235    public Bundle getAssistContextExtras(int requestType) {
10236        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10237                "getAssistContextExtras()");
10238        PendingAssistExtras pae;
10239        Bundle extras = new Bundle();
10240        synchronized (this) {
10241            ActivityRecord activity = getFocusedStack().mResumedActivity;
10242            if (activity == null) {
10243                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10244                return null;
10245            }
10246            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10247            if (activity.app == null || activity.app.thread == null) {
10248                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10249                return extras;
10250            }
10251            if (activity.app.pid == Binder.getCallingPid()) {
10252                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10253                return extras;
10254            }
10255            pae = new PendingAssistExtras(activity);
10256            try {
10257                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10258                        requestType);
10259                mPendingAssistExtras.add(pae);
10260                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10261            } catch (RemoteException e) {
10262                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10263                return extras;
10264            }
10265        }
10266        synchronized (pae) {
10267            while (!pae.haveResult) {
10268                try {
10269                    pae.wait();
10270                } catch (InterruptedException e) {
10271                }
10272            }
10273            if (pae.result != null) {
10274                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10275            }
10276        }
10277        synchronized (this) {
10278            mPendingAssistExtras.remove(pae);
10279            mHandler.removeCallbacks(pae);
10280        }
10281        return extras;
10282    }
10283
10284    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10285        PendingAssistExtras pae = (PendingAssistExtras)token;
10286        synchronized (pae) {
10287            pae.result = extras;
10288            pae.haveResult = true;
10289            pae.notifyAll();
10290        }
10291    }
10292
10293    public void registerProcessObserver(IProcessObserver observer) {
10294        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10295                "registerProcessObserver()");
10296        synchronized (this) {
10297            mProcessObservers.register(observer);
10298        }
10299    }
10300
10301    @Override
10302    public void unregisterProcessObserver(IProcessObserver observer) {
10303        synchronized (this) {
10304            mProcessObservers.unregister(observer);
10305        }
10306    }
10307
10308    @Override
10309    public boolean convertFromTranslucent(IBinder token) {
10310        final long origId = Binder.clearCallingIdentity();
10311        try {
10312            synchronized (this) {
10313                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10314                if (r == null) {
10315                    return false;
10316                }
10317                final boolean translucentChanged = r.changeWindowTranslucency(true);
10318                if (translucentChanged) {
10319                    r.task.stack.releaseBackgroundResources();
10320                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10321                }
10322                mWindowManager.setAppFullscreen(token, true);
10323                return translucentChanged;
10324            }
10325        } finally {
10326            Binder.restoreCallingIdentity(origId);
10327        }
10328    }
10329
10330    @Override
10331    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10332        final long origId = Binder.clearCallingIdentity();
10333        try {
10334            synchronized (this) {
10335                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10336                if (r == null) {
10337                    return false;
10338                }
10339                int index = r.task.mActivities.lastIndexOf(r);
10340                if (index > 0) {
10341                    ActivityRecord under = r.task.mActivities.get(index - 1);
10342                    under.returningOptions = options;
10343                }
10344                final boolean translucentChanged = r.changeWindowTranslucency(false);
10345                if (translucentChanged) {
10346                    r.task.stack.convertToTranslucent(r);
10347                }
10348                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10349                mWindowManager.setAppFullscreen(token, false);
10350                return translucentChanged;
10351            }
10352        } finally {
10353            Binder.restoreCallingIdentity(origId);
10354        }
10355    }
10356
10357    @Override
10358    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10359        final long origId = Binder.clearCallingIdentity();
10360        try {
10361            synchronized (this) {
10362                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10363                if (r != null) {
10364                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10365                }
10366            }
10367            return false;
10368        } finally {
10369            Binder.restoreCallingIdentity(origId);
10370        }
10371    }
10372
10373    @Override
10374    public boolean isBackgroundVisibleBehind(IBinder token) {
10375        final long origId = Binder.clearCallingIdentity();
10376        try {
10377            synchronized (this) {
10378                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10379                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10380                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10381                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10382                return visible;
10383            }
10384        } finally {
10385            Binder.restoreCallingIdentity(origId);
10386        }
10387    }
10388
10389    @Override
10390    public ActivityOptions getActivityOptions(IBinder token) {
10391        final long origId = Binder.clearCallingIdentity();
10392        try {
10393            synchronized (this) {
10394                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10395                if (r != null) {
10396                    final ActivityOptions activityOptions = r.pendingOptions;
10397                    r.pendingOptions = null;
10398                    return activityOptions;
10399                }
10400                return null;
10401            }
10402        } finally {
10403            Binder.restoreCallingIdentity(origId);
10404        }
10405    }
10406
10407    @Override
10408    public void setImmersive(IBinder token, boolean immersive) {
10409        synchronized(this) {
10410            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10411            if (r == null) {
10412                throw new IllegalArgumentException();
10413            }
10414            r.immersive = immersive;
10415
10416            // update associated state if we're frontmost
10417            if (r == mFocusedActivity) {
10418                if (DEBUG_IMMERSIVE) {
10419                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10420                }
10421                applyUpdateLockStateLocked(r);
10422            }
10423        }
10424    }
10425
10426    @Override
10427    public boolean isImmersive(IBinder token) {
10428        synchronized (this) {
10429            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10430            if (r == null) {
10431                throw new IllegalArgumentException();
10432            }
10433            return r.immersive;
10434        }
10435    }
10436
10437    public boolean isTopActivityImmersive() {
10438        enforceNotIsolatedCaller("startActivity");
10439        synchronized (this) {
10440            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10441            return (r != null) ? r.immersive : false;
10442        }
10443    }
10444
10445    @Override
10446    public boolean isTopOfTask(IBinder token) {
10447        synchronized (this) {
10448            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10449            if (r == null) {
10450                throw new IllegalArgumentException();
10451            }
10452            return r.task.getTopActivity() == r;
10453        }
10454    }
10455
10456    public final void enterSafeMode() {
10457        synchronized(this) {
10458            // It only makes sense to do this before the system is ready
10459            // and started launching other packages.
10460            if (!mSystemReady) {
10461                try {
10462                    AppGlobals.getPackageManager().enterSafeMode();
10463                } catch (RemoteException e) {
10464                }
10465            }
10466
10467            mSafeMode = true;
10468        }
10469    }
10470
10471    public final void showSafeModeOverlay() {
10472        View v = LayoutInflater.from(mContext).inflate(
10473                com.android.internal.R.layout.safe_mode, null);
10474        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10475        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10476        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10477        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10478        lp.gravity = Gravity.BOTTOM | Gravity.START;
10479        lp.format = v.getBackground().getOpacity();
10480        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10481                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10482        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10483        ((WindowManager)mContext.getSystemService(
10484                Context.WINDOW_SERVICE)).addView(v, lp);
10485    }
10486
10487    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10488        if (!(sender instanceof PendingIntentRecord)) {
10489            return;
10490        }
10491        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10492        synchronized (stats) {
10493            if (mBatteryStatsService.isOnBattery()) {
10494                mBatteryStatsService.enforceCallingPermission();
10495                PendingIntentRecord rec = (PendingIntentRecord)sender;
10496                int MY_UID = Binder.getCallingUid();
10497                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10498                BatteryStatsImpl.Uid.Pkg pkg =
10499                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10500                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10501                pkg.incWakeupsLocked();
10502            }
10503        }
10504    }
10505
10506    public boolean killPids(int[] pids, String pReason, boolean secure) {
10507        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10508            throw new SecurityException("killPids only available to the system");
10509        }
10510        String reason = (pReason == null) ? "Unknown" : pReason;
10511        // XXX Note: don't acquire main activity lock here, because the window
10512        // manager calls in with its locks held.
10513
10514        boolean killed = false;
10515        synchronized (mPidsSelfLocked) {
10516            int[] types = new int[pids.length];
10517            int worstType = 0;
10518            for (int i=0; i<pids.length; i++) {
10519                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10520                if (proc != null) {
10521                    int type = proc.setAdj;
10522                    types[i] = type;
10523                    if (type > worstType) {
10524                        worstType = type;
10525                    }
10526                }
10527            }
10528
10529            // If the worst oom_adj is somewhere in the cached proc LRU range,
10530            // then constrain it so we will kill all cached procs.
10531            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10532                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10533                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10534            }
10535
10536            // If this is not a secure call, don't let it kill processes that
10537            // are important.
10538            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10539                worstType = ProcessList.SERVICE_ADJ;
10540            }
10541
10542            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10543            for (int i=0; i<pids.length; i++) {
10544                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10545                if (proc == null) {
10546                    continue;
10547                }
10548                int adj = proc.setAdj;
10549                if (adj >= worstType && !proc.killedByAm) {
10550                    proc.kill(reason, true);
10551                    killed = true;
10552                }
10553            }
10554        }
10555        return killed;
10556    }
10557
10558    @Override
10559    public void killUid(int uid, String reason) {
10560        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10561            throw new SecurityException("killUid only available to the system");
10562        }
10563        synchronized (this) {
10564            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10565                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10566                    reason != null ? reason : "kill uid");
10567        }
10568    }
10569
10570    @Override
10571    public boolean killProcessesBelowForeground(String reason) {
10572        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10573            throw new SecurityException("killProcessesBelowForeground() only available to system");
10574        }
10575
10576        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10577    }
10578
10579    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10580        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10581            throw new SecurityException("killProcessesBelowAdj() only available to system");
10582        }
10583
10584        boolean killed = false;
10585        synchronized (mPidsSelfLocked) {
10586            final int size = mPidsSelfLocked.size();
10587            for (int i = 0; i < size; i++) {
10588                final int pid = mPidsSelfLocked.keyAt(i);
10589                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10590                if (proc == null) continue;
10591
10592                final int adj = proc.setAdj;
10593                if (adj > belowAdj && !proc.killedByAm) {
10594                    proc.kill(reason, true);
10595                    killed = true;
10596                }
10597            }
10598        }
10599        return killed;
10600    }
10601
10602    @Override
10603    public void hang(final IBinder who, boolean allowRestart) {
10604        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10605                != PackageManager.PERMISSION_GRANTED) {
10606            throw new SecurityException("Requires permission "
10607                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10608        }
10609
10610        final IBinder.DeathRecipient death = new DeathRecipient() {
10611            @Override
10612            public void binderDied() {
10613                synchronized (this) {
10614                    notifyAll();
10615                }
10616            }
10617        };
10618
10619        try {
10620            who.linkToDeath(death, 0);
10621        } catch (RemoteException e) {
10622            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10623            return;
10624        }
10625
10626        synchronized (this) {
10627            Watchdog.getInstance().setAllowRestart(allowRestart);
10628            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10629            synchronized (death) {
10630                while (who.isBinderAlive()) {
10631                    try {
10632                        death.wait();
10633                    } catch (InterruptedException e) {
10634                    }
10635                }
10636            }
10637            Watchdog.getInstance().setAllowRestart(true);
10638        }
10639    }
10640
10641    @Override
10642    public void restart() {
10643        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10644                != PackageManager.PERMISSION_GRANTED) {
10645            throw new SecurityException("Requires permission "
10646                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10647        }
10648
10649        Log.i(TAG, "Sending shutdown broadcast...");
10650
10651        BroadcastReceiver br = new BroadcastReceiver() {
10652            @Override public void onReceive(Context context, Intent intent) {
10653                // Now the broadcast is done, finish up the low-level shutdown.
10654                Log.i(TAG, "Shutting down activity manager...");
10655                shutdown(10000);
10656                Log.i(TAG, "Shutdown complete, restarting!");
10657                Process.killProcess(Process.myPid());
10658                System.exit(10);
10659            }
10660        };
10661
10662        // First send the high-level shut down broadcast.
10663        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10664        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10665        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10666        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10667        mContext.sendOrderedBroadcastAsUser(intent,
10668                UserHandle.ALL, null, br, mHandler, 0, null, null);
10669        */
10670        br.onReceive(mContext, intent);
10671    }
10672
10673    private long getLowRamTimeSinceIdle(long now) {
10674        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10675    }
10676
10677    @Override
10678    public void performIdleMaintenance() {
10679        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10680                != PackageManager.PERMISSION_GRANTED) {
10681            throw new SecurityException("Requires permission "
10682                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10683        }
10684
10685        synchronized (this) {
10686            final long now = SystemClock.uptimeMillis();
10687            final long timeSinceLastIdle = now - mLastIdleTime;
10688            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10689            mLastIdleTime = now;
10690            mLowRamTimeSinceLastIdle = 0;
10691            if (mLowRamStartTime != 0) {
10692                mLowRamStartTime = now;
10693            }
10694
10695            StringBuilder sb = new StringBuilder(128);
10696            sb.append("Idle maintenance over ");
10697            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10698            sb.append(" low RAM for ");
10699            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10700            Slog.i(TAG, sb.toString());
10701
10702            // If at least 1/3 of our time since the last idle period has been spent
10703            // with RAM low, then we want to kill processes.
10704            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10705
10706            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10707                ProcessRecord proc = mLruProcesses.get(i);
10708                if (proc.notCachedSinceIdle) {
10709                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10710                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10711                        if (doKilling && proc.initialIdlePss != 0
10712                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10713                            proc.kill("idle maint (pss " + proc.lastPss
10714                                    + " from " + proc.initialIdlePss + ")", true);
10715                        }
10716                    }
10717                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10718                    proc.notCachedSinceIdle = true;
10719                    proc.initialIdlePss = 0;
10720                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10721                            isSleeping(), now);
10722                }
10723            }
10724
10725            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10726            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10727        }
10728    }
10729
10730    private void retrieveSettings() {
10731        final ContentResolver resolver = mContext.getContentResolver();
10732        String debugApp = Settings.Global.getString(
10733            resolver, Settings.Global.DEBUG_APP);
10734        boolean waitForDebugger = Settings.Global.getInt(
10735            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10736        boolean alwaysFinishActivities = Settings.Global.getInt(
10737            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10738        boolean forceRtl = Settings.Global.getInt(
10739                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10740        // Transfer any global setting for forcing RTL layout, into a System Property
10741        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10742
10743        Configuration configuration = new Configuration();
10744        Settings.System.getConfiguration(resolver, configuration);
10745        if (forceRtl) {
10746            // This will take care of setting the correct layout direction flags
10747            configuration.setLayoutDirection(configuration.locale);
10748        }
10749
10750        synchronized (this) {
10751            mDebugApp = mOrigDebugApp = debugApp;
10752            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10753            mAlwaysFinishActivities = alwaysFinishActivities;
10754            // This happens before any activities are started, so we can
10755            // change mConfiguration in-place.
10756            updateConfigurationLocked(configuration, null, false, true);
10757            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10758        }
10759    }
10760
10761    /** Loads resources after the current configuration has been set. */
10762    private void loadResourcesOnSystemReady() {
10763        final Resources res = mContext.getResources();
10764        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10765        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10766        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10767    }
10768
10769    public boolean testIsSystemReady() {
10770        // no need to synchronize(this) just to read & return the value
10771        return mSystemReady;
10772    }
10773
10774    private static File getCalledPreBootReceiversFile() {
10775        File dataDir = Environment.getDataDirectory();
10776        File systemDir = new File(dataDir, "system");
10777        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10778        return fname;
10779    }
10780
10781    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10782        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10783        File file = getCalledPreBootReceiversFile();
10784        FileInputStream fis = null;
10785        try {
10786            fis = new FileInputStream(file);
10787            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10788            int fvers = dis.readInt();
10789            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10790                String vers = dis.readUTF();
10791                String codename = dis.readUTF();
10792                String build = dis.readUTF();
10793                if (android.os.Build.VERSION.RELEASE.equals(vers)
10794                        && android.os.Build.VERSION.CODENAME.equals(codename)
10795                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10796                    int num = dis.readInt();
10797                    while (num > 0) {
10798                        num--;
10799                        String pkg = dis.readUTF();
10800                        String cls = dis.readUTF();
10801                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10802                    }
10803                }
10804            }
10805        } catch (FileNotFoundException e) {
10806        } catch (IOException e) {
10807            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10808        } finally {
10809            if (fis != null) {
10810                try {
10811                    fis.close();
10812                } catch (IOException e) {
10813                }
10814            }
10815        }
10816        return lastDoneReceivers;
10817    }
10818
10819    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10820        File file = getCalledPreBootReceiversFile();
10821        FileOutputStream fos = null;
10822        DataOutputStream dos = null;
10823        try {
10824            fos = new FileOutputStream(file);
10825            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10826            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10827            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10828            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10829            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10830            dos.writeInt(list.size());
10831            for (int i=0; i<list.size(); i++) {
10832                dos.writeUTF(list.get(i).getPackageName());
10833                dos.writeUTF(list.get(i).getClassName());
10834            }
10835        } catch (IOException e) {
10836            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10837            file.delete();
10838        } finally {
10839            FileUtils.sync(fos);
10840            if (dos != null) {
10841                try {
10842                    dos.close();
10843                } catch (IOException e) {
10844                    // TODO Auto-generated catch block
10845                    e.printStackTrace();
10846                }
10847            }
10848        }
10849    }
10850
10851    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10852            ArrayList<ComponentName> doneReceivers, int userId) {
10853        boolean waitingUpdate = false;
10854        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10855        List<ResolveInfo> ris = null;
10856        try {
10857            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10858                    intent, null, 0, userId);
10859        } catch (RemoteException e) {
10860        }
10861        if (ris != null) {
10862            for (int i=ris.size()-1; i>=0; i--) {
10863                if ((ris.get(i).activityInfo.applicationInfo.flags
10864                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10865                    ris.remove(i);
10866                }
10867            }
10868            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10869
10870            // For User 0, load the version number. When delivering to a new user, deliver
10871            // to all receivers.
10872            if (userId == UserHandle.USER_OWNER) {
10873                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10874                for (int i=0; i<ris.size(); i++) {
10875                    ActivityInfo ai = ris.get(i).activityInfo;
10876                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10877                    if (lastDoneReceivers.contains(comp)) {
10878                        // We already did the pre boot receiver for this app with the current
10879                        // platform version, so don't do it again...
10880                        ris.remove(i);
10881                        i--;
10882                        // ...however, do keep it as one that has been done, so we don't
10883                        // forget about it when rewriting the file of last done receivers.
10884                        doneReceivers.add(comp);
10885                    }
10886                }
10887            }
10888
10889            // If primary user, send broadcast to all available users, else just to userId
10890            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10891                    : new int[] { userId };
10892            for (int i = 0; i < ris.size(); i++) {
10893                ActivityInfo ai = ris.get(i).activityInfo;
10894                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10895                doneReceivers.add(comp);
10896                intent.setComponent(comp);
10897                for (int j=0; j<users.length; j++) {
10898                    IIntentReceiver finisher = null;
10899                    // On last receiver and user, set up a completion callback
10900                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10901                        finisher = new IIntentReceiver.Stub() {
10902                            public void performReceive(Intent intent, int resultCode,
10903                                    String data, Bundle extras, boolean ordered,
10904                                    boolean sticky, int sendingUser) {
10905                                // The raw IIntentReceiver interface is called
10906                                // with the AM lock held, so redispatch to
10907                                // execute our code without the lock.
10908                                mHandler.post(onFinishCallback);
10909                            }
10910                        };
10911                    }
10912                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10913                            + " for user " + users[j]);
10914                    broadcastIntentLocked(null, null, intent, null, finisher,
10915                            0, null, null, null, AppOpsManager.OP_NONE,
10916                            true, false, MY_PID, Process.SYSTEM_UID,
10917                            users[j]);
10918                    if (finisher != null) {
10919                        waitingUpdate = true;
10920                    }
10921                }
10922            }
10923        }
10924
10925        return waitingUpdate;
10926    }
10927
10928    public void systemReady(final Runnable goingCallback) {
10929        synchronized(this) {
10930            if (mSystemReady) {
10931                // If we're done calling all the receivers, run the next "boot phase" passed in
10932                // by the SystemServer
10933                if (goingCallback != null) {
10934                    goingCallback.run();
10935                }
10936                return;
10937            }
10938
10939            // Make sure we have the current profile info, since it is needed for
10940            // security checks.
10941            updateCurrentProfileIdsLocked();
10942
10943            if (mRecentTasks == null) {
10944                mRecentTasks = mTaskPersister.restoreTasksLocked();
10945                if (!mRecentTasks.isEmpty()) {
10946                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10947                }
10948                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10949                mTaskPersister.startPersisting();
10950            }
10951
10952            // Check to see if there are any update receivers to run.
10953            if (!mDidUpdate) {
10954                if (mWaitingUpdate) {
10955                    return;
10956                }
10957                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10958                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10959                    public void run() {
10960                        synchronized (ActivityManagerService.this) {
10961                            mDidUpdate = true;
10962                        }
10963                        writeLastDonePreBootReceivers(doneReceivers);
10964                        showBootMessage(mContext.getText(
10965                                R.string.android_upgrading_complete),
10966                                false);
10967                        systemReady(goingCallback);
10968                    }
10969                }, doneReceivers, UserHandle.USER_OWNER);
10970
10971                if (mWaitingUpdate) {
10972                    return;
10973                }
10974                mDidUpdate = true;
10975            }
10976
10977            mAppOpsService.systemReady();
10978            mSystemReady = true;
10979        }
10980
10981        ArrayList<ProcessRecord> procsToKill = null;
10982        synchronized(mPidsSelfLocked) {
10983            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10984                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10985                if (!isAllowedWhileBooting(proc.info)){
10986                    if (procsToKill == null) {
10987                        procsToKill = new ArrayList<ProcessRecord>();
10988                    }
10989                    procsToKill.add(proc);
10990                }
10991            }
10992        }
10993
10994        synchronized(this) {
10995            if (procsToKill != null) {
10996                for (int i=procsToKill.size()-1; i>=0; i--) {
10997                    ProcessRecord proc = procsToKill.get(i);
10998                    Slog.i(TAG, "Removing system update proc: " + proc);
10999                    removeProcessLocked(proc, true, false, "system update done");
11000                }
11001            }
11002
11003            // Now that we have cleaned up any update processes, we
11004            // are ready to start launching real processes and know that
11005            // we won't trample on them any more.
11006            mProcessesReady = true;
11007        }
11008
11009        Slog.i(TAG, "System now ready");
11010        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11011            SystemClock.uptimeMillis());
11012
11013        synchronized(this) {
11014            // Make sure we have no pre-ready processes sitting around.
11015
11016            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11017                ResolveInfo ri = mContext.getPackageManager()
11018                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11019                                STOCK_PM_FLAGS);
11020                CharSequence errorMsg = null;
11021                if (ri != null) {
11022                    ActivityInfo ai = ri.activityInfo;
11023                    ApplicationInfo app = ai.applicationInfo;
11024                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11025                        mTopAction = Intent.ACTION_FACTORY_TEST;
11026                        mTopData = null;
11027                        mTopComponent = new ComponentName(app.packageName,
11028                                ai.name);
11029                    } else {
11030                        errorMsg = mContext.getResources().getText(
11031                                com.android.internal.R.string.factorytest_not_system);
11032                    }
11033                } else {
11034                    errorMsg = mContext.getResources().getText(
11035                            com.android.internal.R.string.factorytest_no_action);
11036                }
11037                if (errorMsg != null) {
11038                    mTopAction = null;
11039                    mTopData = null;
11040                    mTopComponent = null;
11041                    Message msg = Message.obtain();
11042                    msg.what = SHOW_FACTORY_ERROR_MSG;
11043                    msg.getData().putCharSequence("msg", errorMsg);
11044                    mHandler.sendMessage(msg);
11045                }
11046            }
11047        }
11048
11049        retrieveSettings();
11050        loadResourcesOnSystemReady();
11051
11052        synchronized (this) {
11053            readGrantedUriPermissionsLocked();
11054        }
11055
11056        if (goingCallback != null) goingCallback.run();
11057
11058        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11059                Integer.toString(mCurrentUserId), mCurrentUserId);
11060        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11061                Integer.toString(mCurrentUserId), mCurrentUserId);
11062        mSystemServiceManager.startUser(mCurrentUserId);
11063
11064        synchronized (this) {
11065            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11066                try {
11067                    List apps = AppGlobals.getPackageManager().
11068                        getPersistentApplications(STOCK_PM_FLAGS);
11069                    if (apps != null) {
11070                        int N = apps.size();
11071                        int i;
11072                        for (i=0; i<N; i++) {
11073                            ApplicationInfo info
11074                                = (ApplicationInfo)apps.get(i);
11075                            if (info != null &&
11076                                    !info.packageName.equals("android")) {
11077                                addAppLocked(info, false, null /* ABI override */);
11078                            }
11079                        }
11080                    }
11081                } catch (RemoteException ex) {
11082                    // pm is in same process, this will never happen.
11083                }
11084            }
11085
11086            // Start up initial activity.
11087            mBooting = true;
11088
11089            try {
11090                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11091                    Message msg = Message.obtain();
11092                    msg.what = SHOW_UID_ERROR_MSG;
11093                    mHandler.sendMessage(msg);
11094                }
11095            } catch (RemoteException e) {
11096            }
11097
11098            long ident = Binder.clearCallingIdentity();
11099            try {
11100                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11101                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11102                        | Intent.FLAG_RECEIVER_FOREGROUND);
11103                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11104                broadcastIntentLocked(null, null, intent,
11105                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11106                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11107                intent = new Intent(Intent.ACTION_USER_STARTING);
11108                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11109                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11110                broadcastIntentLocked(null, null, intent,
11111                        null, new IIntentReceiver.Stub() {
11112                            @Override
11113                            public void performReceive(Intent intent, int resultCode, String data,
11114                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11115                                    throws RemoteException {
11116                            }
11117                        }, 0, null, null,
11118                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11119                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11120            } catch (Throwable t) {
11121                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11122            } finally {
11123                Binder.restoreCallingIdentity(ident);
11124            }
11125            mStackSupervisor.resumeTopActivitiesLocked();
11126            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11127        }
11128    }
11129
11130    private boolean makeAppCrashingLocked(ProcessRecord app,
11131            String shortMsg, String longMsg, String stackTrace) {
11132        app.crashing = true;
11133        app.crashingReport = generateProcessError(app,
11134                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11135        startAppProblemLocked(app);
11136        app.stopFreezingAllLocked();
11137        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11138    }
11139
11140    private void makeAppNotRespondingLocked(ProcessRecord app,
11141            String activity, String shortMsg, String longMsg) {
11142        app.notResponding = true;
11143        app.notRespondingReport = generateProcessError(app,
11144                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11145                activity, shortMsg, longMsg, null);
11146        startAppProblemLocked(app);
11147        app.stopFreezingAllLocked();
11148    }
11149
11150    /**
11151     * Generate a process error record, suitable for attachment to a ProcessRecord.
11152     *
11153     * @param app The ProcessRecord in which the error occurred.
11154     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11155     *                      ActivityManager.AppErrorStateInfo
11156     * @param activity The activity associated with the crash, if known.
11157     * @param shortMsg Short message describing the crash.
11158     * @param longMsg Long message describing the crash.
11159     * @param stackTrace Full crash stack trace, may be null.
11160     *
11161     * @return Returns a fully-formed AppErrorStateInfo record.
11162     */
11163    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11164            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11165        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11166
11167        report.condition = condition;
11168        report.processName = app.processName;
11169        report.pid = app.pid;
11170        report.uid = app.info.uid;
11171        report.tag = activity;
11172        report.shortMsg = shortMsg;
11173        report.longMsg = longMsg;
11174        report.stackTrace = stackTrace;
11175
11176        return report;
11177    }
11178
11179    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11180        synchronized (this) {
11181            app.crashing = false;
11182            app.crashingReport = null;
11183            app.notResponding = false;
11184            app.notRespondingReport = null;
11185            if (app.anrDialog == fromDialog) {
11186                app.anrDialog = null;
11187            }
11188            if (app.waitDialog == fromDialog) {
11189                app.waitDialog = null;
11190            }
11191            if (app.pid > 0 && app.pid != MY_PID) {
11192                handleAppCrashLocked(app, null, null, null);
11193                app.kill("user request after error", true);
11194            }
11195        }
11196    }
11197
11198    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11199            String stackTrace) {
11200        long now = SystemClock.uptimeMillis();
11201
11202        Long crashTime;
11203        if (!app.isolated) {
11204            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11205        } else {
11206            crashTime = null;
11207        }
11208        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11209            // This process loses!
11210            Slog.w(TAG, "Process " + app.info.processName
11211                    + " has crashed too many times: killing!");
11212            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11213                    app.userId, app.info.processName, app.uid);
11214            mStackSupervisor.handleAppCrashLocked(app);
11215            if (!app.persistent) {
11216                // We don't want to start this process again until the user
11217                // explicitly does so...  but for persistent process, we really
11218                // need to keep it running.  If a persistent process is actually
11219                // repeatedly crashing, then badness for everyone.
11220                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11221                        app.info.processName);
11222                if (!app.isolated) {
11223                    // XXX We don't have a way to mark isolated processes
11224                    // as bad, since they don't have a peristent identity.
11225                    mBadProcesses.put(app.info.processName, app.uid,
11226                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11227                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11228                }
11229                app.bad = true;
11230                app.removed = true;
11231                // Don't let services in this process be restarted and potentially
11232                // annoy the user repeatedly.  Unless it is persistent, since those
11233                // processes run critical code.
11234                removeProcessLocked(app, false, false, "crash");
11235                mStackSupervisor.resumeTopActivitiesLocked();
11236                return false;
11237            }
11238            mStackSupervisor.resumeTopActivitiesLocked();
11239        } else {
11240            mStackSupervisor.finishTopRunningActivityLocked(app);
11241        }
11242
11243        // Bump up the crash count of any services currently running in the proc.
11244        for (int i=app.services.size()-1; i>=0; i--) {
11245            // Any services running in the application need to be placed
11246            // back in the pending list.
11247            ServiceRecord sr = app.services.valueAt(i);
11248            sr.crashCount++;
11249        }
11250
11251        // If the crashing process is what we consider to be the "home process" and it has been
11252        // replaced by a third-party app, clear the package preferred activities from packages
11253        // with a home activity running in the process to prevent a repeatedly crashing app
11254        // from blocking the user to manually clear the list.
11255        final ArrayList<ActivityRecord> activities = app.activities;
11256        if (app == mHomeProcess && activities.size() > 0
11257                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11258            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11259                final ActivityRecord r = activities.get(activityNdx);
11260                if (r.isHomeActivity()) {
11261                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11262                    try {
11263                        ActivityThread.getPackageManager()
11264                                .clearPackagePreferredActivities(r.packageName);
11265                    } catch (RemoteException c) {
11266                        // pm is in same process, this will never happen.
11267                    }
11268                }
11269            }
11270        }
11271
11272        if (!app.isolated) {
11273            // XXX Can't keep track of crash times for isolated processes,
11274            // because they don't have a perisistent identity.
11275            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11276        }
11277
11278        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11279        return true;
11280    }
11281
11282    void startAppProblemLocked(ProcessRecord app) {
11283        // If this app is not running under the current user, then we
11284        // can't give it a report button because that would require
11285        // launching the report UI under a different user.
11286        app.errorReportReceiver = null;
11287
11288        for (int userId : mCurrentProfileIds) {
11289            if (app.userId == userId) {
11290                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11291                        mContext, app.info.packageName, app.info.flags);
11292            }
11293        }
11294        skipCurrentReceiverLocked(app);
11295    }
11296
11297    void skipCurrentReceiverLocked(ProcessRecord app) {
11298        for (BroadcastQueue queue : mBroadcastQueues) {
11299            queue.skipCurrentReceiverLocked(app);
11300        }
11301    }
11302
11303    /**
11304     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11305     * The application process will exit immediately after this call returns.
11306     * @param app object of the crashing app, null for the system server
11307     * @param crashInfo describing the exception
11308     */
11309    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11310        ProcessRecord r = findAppProcess(app, "Crash");
11311        final String processName = app == null ? "system_server"
11312                : (r == null ? "unknown" : r.processName);
11313
11314        handleApplicationCrashInner("crash", r, processName, crashInfo);
11315    }
11316
11317    /* Native crash reporting uses this inner version because it needs to be somewhat
11318     * decoupled from the AM-managed cleanup lifecycle
11319     */
11320    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11321            ApplicationErrorReport.CrashInfo crashInfo) {
11322        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11323                UserHandle.getUserId(Binder.getCallingUid()), processName,
11324                r == null ? -1 : r.info.flags,
11325                crashInfo.exceptionClassName,
11326                crashInfo.exceptionMessage,
11327                crashInfo.throwFileName,
11328                crashInfo.throwLineNumber);
11329
11330        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11331
11332        crashApplication(r, crashInfo);
11333    }
11334
11335    public void handleApplicationStrictModeViolation(
11336            IBinder app,
11337            int violationMask,
11338            StrictMode.ViolationInfo info) {
11339        ProcessRecord r = findAppProcess(app, "StrictMode");
11340        if (r == null) {
11341            return;
11342        }
11343
11344        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11345            Integer stackFingerprint = info.hashCode();
11346            boolean logIt = true;
11347            synchronized (mAlreadyLoggedViolatedStacks) {
11348                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11349                    logIt = false;
11350                    // TODO: sub-sample into EventLog for these, with
11351                    // the info.durationMillis?  Then we'd get
11352                    // the relative pain numbers, without logging all
11353                    // the stack traces repeatedly.  We'd want to do
11354                    // likewise in the client code, which also does
11355                    // dup suppression, before the Binder call.
11356                } else {
11357                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11358                        mAlreadyLoggedViolatedStacks.clear();
11359                    }
11360                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11361                }
11362            }
11363            if (logIt) {
11364                logStrictModeViolationToDropBox(r, info);
11365            }
11366        }
11367
11368        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11369            AppErrorResult result = new AppErrorResult();
11370            synchronized (this) {
11371                final long origId = Binder.clearCallingIdentity();
11372
11373                Message msg = Message.obtain();
11374                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11375                HashMap<String, Object> data = new HashMap<String, Object>();
11376                data.put("result", result);
11377                data.put("app", r);
11378                data.put("violationMask", violationMask);
11379                data.put("info", info);
11380                msg.obj = data;
11381                mHandler.sendMessage(msg);
11382
11383                Binder.restoreCallingIdentity(origId);
11384            }
11385            int res = result.get();
11386            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11387        }
11388    }
11389
11390    // Depending on the policy in effect, there could be a bunch of
11391    // these in quick succession so we try to batch these together to
11392    // minimize disk writes, number of dropbox entries, and maximize
11393    // compression, by having more fewer, larger records.
11394    private void logStrictModeViolationToDropBox(
11395            ProcessRecord process,
11396            StrictMode.ViolationInfo info) {
11397        if (info == null) {
11398            return;
11399        }
11400        final boolean isSystemApp = process == null ||
11401                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11402                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11403        final String processName = process == null ? "unknown" : process.processName;
11404        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11405        final DropBoxManager dbox = (DropBoxManager)
11406                mContext.getSystemService(Context.DROPBOX_SERVICE);
11407
11408        // Exit early if the dropbox isn't configured to accept this report type.
11409        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11410
11411        boolean bufferWasEmpty;
11412        boolean needsFlush;
11413        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11414        synchronized (sb) {
11415            bufferWasEmpty = sb.length() == 0;
11416            appendDropBoxProcessHeaders(process, processName, sb);
11417            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11418            sb.append("System-App: ").append(isSystemApp).append("\n");
11419            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11420            if (info.violationNumThisLoop != 0) {
11421                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11422            }
11423            if (info.numAnimationsRunning != 0) {
11424                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11425            }
11426            if (info.broadcastIntentAction != null) {
11427                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11428            }
11429            if (info.durationMillis != -1) {
11430                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11431            }
11432            if (info.numInstances != -1) {
11433                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11434            }
11435            if (info.tags != null) {
11436                for (String tag : info.tags) {
11437                    sb.append("Span-Tag: ").append(tag).append("\n");
11438                }
11439            }
11440            sb.append("\n");
11441            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11442                sb.append(info.crashInfo.stackTrace);
11443            }
11444            sb.append("\n");
11445
11446            // Only buffer up to ~64k.  Various logging bits truncate
11447            // things at 128k.
11448            needsFlush = (sb.length() > 64 * 1024);
11449        }
11450
11451        // Flush immediately if the buffer's grown too large, or this
11452        // is a non-system app.  Non-system apps are isolated with a
11453        // different tag & policy and not batched.
11454        //
11455        // Batching is useful during internal testing with
11456        // StrictMode settings turned up high.  Without batching,
11457        // thousands of separate files could be created on boot.
11458        if (!isSystemApp || needsFlush) {
11459            new Thread("Error dump: " + dropboxTag) {
11460                @Override
11461                public void run() {
11462                    String report;
11463                    synchronized (sb) {
11464                        report = sb.toString();
11465                        sb.delete(0, sb.length());
11466                        sb.trimToSize();
11467                    }
11468                    if (report.length() != 0) {
11469                        dbox.addText(dropboxTag, report);
11470                    }
11471                }
11472            }.start();
11473            return;
11474        }
11475
11476        // System app batching:
11477        if (!bufferWasEmpty) {
11478            // An existing dropbox-writing thread is outstanding, so
11479            // we don't need to start it up.  The existing thread will
11480            // catch the buffer appends we just did.
11481            return;
11482        }
11483
11484        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11485        // (After this point, we shouldn't access AMS internal data structures.)
11486        new Thread("Error dump: " + dropboxTag) {
11487            @Override
11488            public void run() {
11489                // 5 second sleep to let stacks arrive and be batched together
11490                try {
11491                    Thread.sleep(5000);  // 5 seconds
11492                } catch (InterruptedException e) {}
11493
11494                String errorReport;
11495                synchronized (mStrictModeBuffer) {
11496                    errorReport = mStrictModeBuffer.toString();
11497                    if (errorReport.length() == 0) {
11498                        return;
11499                    }
11500                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11501                    mStrictModeBuffer.trimToSize();
11502                }
11503                dbox.addText(dropboxTag, errorReport);
11504            }
11505        }.start();
11506    }
11507
11508    /**
11509     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11510     * @param app object of the crashing app, null for the system server
11511     * @param tag reported by the caller
11512     * @param system whether this wtf is coming from the system
11513     * @param crashInfo describing the context of the error
11514     * @return true if the process should exit immediately (WTF is fatal)
11515     */
11516    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11517            final ApplicationErrorReport.CrashInfo crashInfo) {
11518        final ProcessRecord r = findAppProcess(app, "WTF");
11519        final String processName = app == null ? "system_server"
11520                : (r == null ? "unknown" : r.processName);
11521
11522        EventLog.writeEvent(EventLogTags.AM_WTF,
11523                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11524                processName,
11525                r == null ? -1 : r.info.flags,
11526                tag, crashInfo.exceptionMessage);
11527
11528        if (system) {
11529            // If this is coming from the system, we could very well have low-level
11530            // system locks held, so we want to do this all asynchronously.  And we
11531            // never want this to become fatal, so there is that too.
11532            mHandler.post(new Runnable() {
11533                @Override public void run() {
11534                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11535                            crashInfo);
11536                }
11537            });
11538            return false;
11539        }
11540
11541        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11542
11543        if (r != null && r.pid != Process.myPid() &&
11544                Settings.Global.getInt(mContext.getContentResolver(),
11545                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11546            crashApplication(r, crashInfo);
11547            return true;
11548        } else {
11549            return false;
11550        }
11551    }
11552
11553    /**
11554     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11555     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11556     */
11557    private ProcessRecord findAppProcess(IBinder app, String reason) {
11558        if (app == null) {
11559            return null;
11560        }
11561
11562        synchronized (this) {
11563            final int NP = mProcessNames.getMap().size();
11564            for (int ip=0; ip<NP; ip++) {
11565                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11566                final int NA = apps.size();
11567                for (int ia=0; ia<NA; ia++) {
11568                    ProcessRecord p = apps.valueAt(ia);
11569                    if (p.thread != null && p.thread.asBinder() == app) {
11570                        return p;
11571                    }
11572                }
11573            }
11574
11575            Slog.w(TAG, "Can't find mystery application for " + reason
11576                    + " from pid=" + Binder.getCallingPid()
11577                    + " uid=" + Binder.getCallingUid() + ": " + app);
11578            return null;
11579        }
11580    }
11581
11582    /**
11583     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11584     * to append various headers to the dropbox log text.
11585     */
11586    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11587            StringBuilder sb) {
11588        // Watchdog thread ends up invoking this function (with
11589        // a null ProcessRecord) to add the stack file to dropbox.
11590        // Do not acquire a lock on this (am) in such cases, as it
11591        // could cause a potential deadlock, if and when watchdog
11592        // is invoked due to unavailability of lock on am and it
11593        // would prevent watchdog from killing system_server.
11594        if (process == null) {
11595            sb.append("Process: ").append(processName).append("\n");
11596            return;
11597        }
11598        // Note: ProcessRecord 'process' is guarded by the service
11599        // instance.  (notably process.pkgList, which could otherwise change
11600        // concurrently during execution of this method)
11601        synchronized (this) {
11602            sb.append("Process: ").append(processName).append("\n");
11603            int flags = process.info.flags;
11604            IPackageManager pm = AppGlobals.getPackageManager();
11605            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11606            for (int ip=0; ip<process.pkgList.size(); ip++) {
11607                String pkg = process.pkgList.keyAt(ip);
11608                sb.append("Package: ").append(pkg);
11609                try {
11610                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11611                    if (pi != null) {
11612                        sb.append(" v").append(pi.versionCode);
11613                        if (pi.versionName != null) {
11614                            sb.append(" (").append(pi.versionName).append(")");
11615                        }
11616                    }
11617                } catch (RemoteException e) {
11618                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11619                }
11620                sb.append("\n");
11621            }
11622        }
11623    }
11624
11625    private static String processClass(ProcessRecord process) {
11626        if (process == null || process.pid == MY_PID) {
11627            return "system_server";
11628        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11629            return "system_app";
11630        } else {
11631            return "data_app";
11632        }
11633    }
11634
11635    /**
11636     * Write a description of an error (crash, WTF, ANR) to the drop box.
11637     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11638     * @param process which caused the error, null means the system server
11639     * @param activity which triggered the error, null if unknown
11640     * @param parent activity related to the error, null if unknown
11641     * @param subject line related to the error, null if absent
11642     * @param report in long form describing the error, null if absent
11643     * @param logFile to include in the report, null if none
11644     * @param crashInfo giving an application stack trace, null if absent
11645     */
11646    public void addErrorToDropBox(String eventType,
11647            ProcessRecord process, String processName, ActivityRecord activity,
11648            ActivityRecord parent, String subject,
11649            final String report, final File logFile,
11650            final ApplicationErrorReport.CrashInfo crashInfo) {
11651        // NOTE -- this must never acquire the ActivityManagerService lock,
11652        // otherwise the watchdog may be prevented from resetting the system.
11653
11654        final String dropboxTag = processClass(process) + "_" + eventType;
11655        final DropBoxManager dbox = (DropBoxManager)
11656                mContext.getSystemService(Context.DROPBOX_SERVICE);
11657
11658        // Exit early if the dropbox isn't configured to accept this report type.
11659        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11660
11661        final StringBuilder sb = new StringBuilder(1024);
11662        appendDropBoxProcessHeaders(process, processName, sb);
11663        if (activity != null) {
11664            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11665        }
11666        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11667            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11668        }
11669        if (parent != null && parent != activity) {
11670            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11671        }
11672        if (subject != null) {
11673            sb.append("Subject: ").append(subject).append("\n");
11674        }
11675        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11676        if (Debug.isDebuggerConnected()) {
11677            sb.append("Debugger: Connected\n");
11678        }
11679        sb.append("\n");
11680
11681        // Do the rest in a worker thread to avoid blocking the caller on I/O
11682        // (After this point, we shouldn't access AMS internal data structures.)
11683        Thread worker = new Thread("Error dump: " + dropboxTag) {
11684            @Override
11685            public void run() {
11686                if (report != null) {
11687                    sb.append(report);
11688                }
11689                if (logFile != null) {
11690                    try {
11691                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11692                                    "\n\n[[TRUNCATED]]"));
11693                    } catch (IOException e) {
11694                        Slog.e(TAG, "Error reading " + logFile, e);
11695                    }
11696                }
11697                if (crashInfo != null && crashInfo.stackTrace != null) {
11698                    sb.append(crashInfo.stackTrace);
11699                }
11700
11701                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11702                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11703                if (lines > 0) {
11704                    sb.append("\n");
11705
11706                    // Merge several logcat streams, and take the last N lines
11707                    InputStreamReader input = null;
11708                    try {
11709                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11710                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11711                                "-b", "crash",
11712                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11713
11714                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11715                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11716                        input = new InputStreamReader(logcat.getInputStream());
11717
11718                        int num;
11719                        char[] buf = new char[8192];
11720                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11721                    } catch (IOException e) {
11722                        Slog.e(TAG, "Error running logcat", e);
11723                    } finally {
11724                        if (input != null) try { input.close(); } catch (IOException e) {}
11725                    }
11726                }
11727
11728                dbox.addText(dropboxTag, sb.toString());
11729            }
11730        };
11731
11732        if (process == null) {
11733            // If process is null, we are being called from some internal code
11734            // and may be about to die -- run this synchronously.
11735            worker.run();
11736        } else {
11737            worker.start();
11738        }
11739    }
11740
11741    /**
11742     * Bring up the "unexpected error" dialog box for a crashing app.
11743     * Deal with edge cases (intercepts from instrumented applications,
11744     * ActivityController, error intent receivers, that sort of thing).
11745     * @param r the application crashing
11746     * @param crashInfo describing the failure
11747     */
11748    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11749        long timeMillis = System.currentTimeMillis();
11750        String shortMsg = crashInfo.exceptionClassName;
11751        String longMsg = crashInfo.exceptionMessage;
11752        String stackTrace = crashInfo.stackTrace;
11753        if (shortMsg != null && longMsg != null) {
11754            longMsg = shortMsg + ": " + longMsg;
11755        } else if (shortMsg != null) {
11756            longMsg = shortMsg;
11757        }
11758
11759        AppErrorResult result = new AppErrorResult();
11760        synchronized (this) {
11761            if (mController != null) {
11762                try {
11763                    String name = r != null ? r.processName : null;
11764                    int pid = r != null ? r.pid : Binder.getCallingPid();
11765                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11766                    if (!mController.appCrashed(name, pid,
11767                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11768                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11769                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11770                            Slog.w(TAG, "Skip killing native crashed app " + name
11771                                    + "(" + pid + ") during testing");
11772                        } else {
11773                            Slog.w(TAG, "Force-killing crashed app " + name
11774                                    + " at watcher's request");
11775                            if (r != null) {
11776                                r.kill("crash", true);
11777                            } else {
11778                                // Huh.
11779                                Process.killProcess(pid);
11780                                Process.killProcessGroup(uid, pid);
11781                            }
11782                        }
11783                        return;
11784                    }
11785                } catch (RemoteException e) {
11786                    mController = null;
11787                    Watchdog.getInstance().setActivityController(null);
11788                }
11789            }
11790
11791            final long origId = Binder.clearCallingIdentity();
11792
11793            // If this process is running instrumentation, finish it.
11794            if (r != null && r.instrumentationClass != null) {
11795                Slog.w(TAG, "Error in app " + r.processName
11796                      + " running instrumentation " + r.instrumentationClass + ":");
11797                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11798                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11799                Bundle info = new Bundle();
11800                info.putString("shortMsg", shortMsg);
11801                info.putString("longMsg", longMsg);
11802                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11803                Binder.restoreCallingIdentity(origId);
11804                return;
11805            }
11806
11807            // If we can't identify the process or it's already exceeded its crash quota,
11808            // quit right away without showing a crash dialog.
11809            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11810                Binder.restoreCallingIdentity(origId);
11811                return;
11812            }
11813
11814            Message msg = Message.obtain();
11815            msg.what = SHOW_ERROR_MSG;
11816            HashMap data = new HashMap();
11817            data.put("result", result);
11818            data.put("app", r);
11819            msg.obj = data;
11820            mHandler.sendMessage(msg);
11821
11822            Binder.restoreCallingIdentity(origId);
11823        }
11824
11825        int res = result.get();
11826
11827        Intent appErrorIntent = null;
11828        synchronized (this) {
11829            if (r != null && !r.isolated) {
11830                // XXX Can't keep track of crash time for isolated processes,
11831                // since they don't have a persistent identity.
11832                mProcessCrashTimes.put(r.info.processName, r.uid,
11833                        SystemClock.uptimeMillis());
11834            }
11835            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11836                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11837            }
11838        }
11839
11840        if (appErrorIntent != null) {
11841            try {
11842                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11843            } catch (ActivityNotFoundException e) {
11844                Slog.w(TAG, "bug report receiver dissappeared", e);
11845            }
11846        }
11847    }
11848
11849    Intent createAppErrorIntentLocked(ProcessRecord r,
11850            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11851        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11852        if (report == null) {
11853            return null;
11854        }
11855        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11856        result.setComponent(r.errorReportReceiver);
11857        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11858        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11859        return result;
11860    }
11861
11862    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11863            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11864        if (r.errorReportReceiver == null) {
11865            return null;
11866        }
11867
11868        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11869            return null;
11870        }
11871
11872        ApplicationErrorReport report = new ApplicationErrorReport();
11873        report.packageName = r.info.packageName;
11874        report.installerPackageName = r.errorReportReceiver.getPackageName();
11875        report.processName = r.processName;
11876        report.time = timeMillis;
11877        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11878
11879        if (r.crashing || r.forceCrashReport) {
11880            report.type = ApplicationErrorReport.TYPE_CRASH;
11881            report.crashInfo = crashInfo;
11882        } else if (r.notResponding) {
11883            report.type = ApplicationErrorReport.TYPE_ANR;
11884            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11885
11886            report.anrInfo.activity = r.notRespondingReport.tag;
11887            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11888            report.anrInfo.info = r.notRespondingReport.longMsg;
11889        }
11890
11891        return report;
11892    }
11893
11894    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11895        enforceNotIsolatedCaller("getProcessesInErrorState");
11896        // assume our apps are happy - lazy create the list
11897        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11898
11899        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11900                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11901        int userId = UserHandle.getUserId(Binder.getCallingUid());
11902
11903        synchronized (this) {
11904
11905            // iterate across all processes
11906            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11907                ProcessRecord app = mLruProcesses.get(i);
11908                if (!allUsers && app.userId != userId) {
11909                    continue;
11910                }
11911                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11912                    // This one's in trouble, so we'll generate a report for it
11913                    // crashes are higher priority (in case there's a crash *and* an anr)
11914                    ActivityManager.ProcessErrorStateInfo report = null;
11915                    if (app.crashing) {
11916                        report = app.crashingReport;
11917                    } else if (app.notResponding) {
11918                        report = app.notRespondingReport;
11919                    }
11920
11921                    if (report != null) {
11922                        if (errList == null) {
11923                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11924                        }
11925                        errList.add(report);
11926                    } else {
11927                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11928                                " crashing = " + app.crashing +
11929                                " notResponding = " + app.notResponding);
11930                    }
11931                }
11932            }
11933        }
11934
11935        return errList;
11936    }
11937
11938    static int procStateToImportance(int procState, int memAdj,
11939            ActivityManager.RunningAppProcessInfo currApp) {
11940        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11941        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11942            currApp.lru = memAdj;
11943        } else {
11944            currApp.lru = 0;
11945        }
11946        return imp;
11947    }
11948
11949    private void fillInProcMemInfo(ProcessRecord app,
11950            ActivityManager.RunningAppProcessInfo outInfo) {
11951        outInfo.pid = app.pid;
11952        outInfo.uid = app.info.uid;
11953        if (mHeavyWeightProcess == app) {
11954            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11955        }
11956        if (app.persistent) {
11957            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11958        }
11959        if (app.activities.size() > 0) {
11960            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11961        }
11962        outInfo.lastTrimLevel = app.trimMemoryLevel;
11963        int adj = app.curAdj;
11964        int procState = app.curProcState;
11965        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11966        outInfo.importanceReasonCode = app.adjTypeCode;
11967        outInfo.processState = app.curProcState;
11968    }
11969
11970    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11971        enforceNotIsolatedCaller("getRunningAppProcesses");
11972        // Lazy instantiation of list
11973        List<ActivityManager.RunningAppProcessInfo> runList = null;
11974        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11975                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11976        int userId = UserHandle.getUserId(Binder.getCallingUid());
11977        synchronized (this) {
11978            // Iterate across all processes
11979            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11980                ProcessRecord app = mLruProcesses.get(i);
11981                if (!allUsers && app.userId != userId) {
11982                    continue;
11983                }
11984                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11985                    // Generate process state info for running application
11986                    ActivityManager.RunningAppProcessInfo currApp =
11987                        new ActivityManager.RunningAppProcessInfo(app.processName,
11988                                app.pid, app.getPackageList());
11989                    fillInProcMemInfo(app, currApp);
11990                    if (app.adjSource instanceof ProcessRecord) {
11991                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11992                        currApp.importanceReasonImportance =
11993                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11994                                        app.adjSourceProcState);
11995                    } else if (app.adjSource instanceof ActivityRecord) {
11996                        ActivityRecord r = (ActivityRecord)app.adjSource;
11997                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11998                    }
11999                    if (app.adjTarget instanceof ComponentName) {
12000                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12001                    }
12002                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12003                    //        + " lru=" + currApp.lru);
12004                    if (runList == null) {
12005                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12006                    }
12007                    runList.add(currApp);
12008                }
12009            }
12010        }
12011        return runList;
12012    }
12013
12014    public List<ApplicationInfo> getRunningExternalApplications() {
12015        enforceNotIsolatedCaller("getRunningExternalApplications");
12016        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12017        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12018        if (runningApps != null && runningApps.size() > 0) {
12019            Set<String> extList = new HashSet<String>();
12020            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12021                if (app.pkgList != null) {
12022                    for (String pkg : app.pkgList) {
12023                        extList.add(pkg);
12024                    }
12025                }
12026            }
12027            IPackageManager pm = AppGlobals.getPackageManager();
12028            for (String pkg : extList) {
12029                try {
12030                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12031                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12032                        retList.add(info);
12033                    }
12034                } catch (RemoteException e) {
12035                }
12036            }
12037        }
12038        return retList;
12039    }
12040
12041    @Override
12042    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12043        enforceNotIsolatedCaller("getMyMemoryState");
12044        synchronized (this) {
12045            ProcessRecord proc;
12046            synchronized (mPidsSelfLocked) {
12047                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12048            }
12049            fillInProcMemInfo(proc, outInfo);
12050        }
12051    }
12052
12053    @Override
12054    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12055        if (checkCallingPermission(android.Manifest.permission.DUMP)
12056                != PackageManager.PERMISSION_GRANTED) {
12057            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12058                    + Binder.getCallingPid()
12059                    + ", uid=" + Binder.getCallingUid()
12060                    + " without permission "
12061                    + android.Manifest.permission.DUMP);
12062            return;
12063        }
12064
12065        boolean dumpAll = false;
12066        boolean dumpClient = false;
12067        String dumpPackage = null;
12068
12069        int opti = 0;
12070        while (opti < args.length) {
12071            String opt = args[opti];
12072            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12073                break;
12074            }
12075            opti++;
12076            if ("-a".equals(opt)) {
12077                dumpAll = true;
12078            } else if ("-c".equals(opt)) {
12079                dumpClient = true;
12080            } else if ("-h".equals(opt)) {
12081                pw.println("Activity manager dump options:");
12082                pw.println("  [-a] [-c] [-h] [cmd] ...");
12083                pw.println("  cmd may be one of:");
12084                pw.println("    a[ctivities]: activity stack state");
12085                pw.println("    r[recents]: recent activities state");
12086                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12087                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12088                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12089                pw.println("    o[om]: out of memory management");
12090                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12091                pw.println("    provider [COMP_SPEC]: provider client-side state");
12092                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12093                pw.println("    service [COMP_SPEC]: service client-side state");
12094                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12095                pw.println("    all: dump all activities");
12096                pw.println("    top: dump the top activity");
12097                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12098                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12099                pw.println("    a partial substring in a component name, a");
12100                pw.println("    hex object identifier.");
12101                pw.println("  -a: include all available server state.");
12102                pw.println("  -c: include client state.");
12103                return;
12104            } else {
12105                pw.println("Unknown argument: " + opt + "; use -h for help");
12106            }
12107        }
12108
12109        long origId = Binder.clearCallingIdentity();
12110        boolean more = false;
12111        // Is the caller requesting to dump a particular piece of data?
12112        if (opti < args.length) {
12113            String cmd = args[opti];
12114            opti++;
12115            if ("activities".equals(cmd) || "a".equals(cmd)) {
12116                synchronized (this) {
12117                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12118                }
12119            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12120                synchronized (this) {
12121                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12122                }
12123            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12124                String[] newArgs;
12125                String name;
12126                if (opti >= args.length) {
12127                    name = null;
12128                    newArgs = EMPTY_STRING_ARRAY;
12129                } else {
12130                    name = args[opti];
12131                    opti++;
12132                    newArgs = new String[args.length - opti];
12133                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12134                            args.length - opti);
12135                }
12136                synchronized (this) {
12137                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12138                }
12139            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12140                String[] newArgs;
12141                String name;
12142                if (opti >= args.length) {
12143                    name = null;
12144                    newArgs = EMPTY_STRING_ARRAY;
12145                } else {
12146                    name = args[opti];
12147                    opti++;
12148                    newArgs = new String[args.length - opti];
12149                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12150                            args.length - opti);
12151                }
12152                synchronized (this) {
12153                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12154                }
12155            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12156                String[] newArgs;
12157                String name;
12158                if (opti >= args.length) {
12159                    name = null;
12160                    newArgs = EMPTY_STRING_ARRAY;
12161                } else {
12162                    name = args[opti];
12163                    opti++;
12164                    newArgs = new String[args.length - opti];
12165                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12166                            args.length - opti);
12167                }
12168                synchronized (this) {
12169                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12170                }
12171            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12172                synchronized (this) {
12173                    dumpOomLocked(fd, pw, args, opti, true);
12174                }
12175            } else if ("provider".equals(cmd)) {
12176                String[] newArgs;
12177                String name;
12178                if (opti >= args.length) {
12179                    name = null;
12180                    newArgs = EMPTY_STRING_ARRAY;
12181                } else {
12182                    name = args[opti];
12183                    opti++;
12184                    newArgs = new String[args.length - opti];
12185                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12186                }
12187                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12188                    pw.println("No providers match: " + name);
12189                    pw.println("Use -h for help.");
12190                }
12191            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12192                synchronized (this) {
12193                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12194                }
12195            } else if ("service".equals(cmd)) {
12196                String[] newArgs;
12197                String name;
12198                if (opti >= args.length) {
12199                    name = null;
12200                    newArgs = EMPTY_STRING_ARRAY;
12201                } else {
12202                    name = args[opti];
12203                    opti++;
12204                    newArgs = new String[args.length - opti];
12205                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12206                            args.length - opti);
12207                }
12208                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12209                    pw.println("No services match: " + name);
12210                    pw.println("Use -h for help.");
12211                }
12212            } else if ("package".equals(cmd)) {
12213                String[] newArgs;
12214                if (opti >= args.length) {
12215                    pw.println("package: no package name specified");
12216                    pw.println("Use -h for help.");
12217                } else {
12218                    dumpPackage = args[opti];
12219                    opti++;
12220                    newArgs = new String[args.length - opti];
12221                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12222                            args.length - opti);
12223                    args = newArgs;
12224                    opti = 0;
12225                    more = true;
12226                }
12227            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12228                synchronized (this) {
12229                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12230                }
12231            } else {
12232                // Dumping a single activity?
12233                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12234                    pw.println("Bad activity command, or no activities match: " + cmd);
12235                    pw.println("Use -h for help.");
12236                }
12237            }
12238            if (!more) {
12239                Binder.restoreCallingIdentity(origId);
12240                return;
12241            }
12242        }
12243
12244        // No piece of data specified, dump everything.
12245        synchronized (this) {
12246            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12247            pw.println();
12248            if (dumpAll) {
12249                pw.println("-------------------------------------------------------------------------------");
12250            }
12251            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12252            pw.println();
12253            if (dumpAll) {
12254                pw.println("-------------------------------------------------------------------------------");
12255            }
12256            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12257            pw.println();
12258            if (dumpAll) {
12259                pw.println("-------------------------------------------------------------------------------");
12260            }
12261            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12262            pw.println();
12263            if (dumpAll) {
12264                pw.println("-------------------------------------------------------------------------------");
12265            }
12266            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12267            pw.println();
12268            if (dumpAll) {
12269                pw.println("-------------------------------------------------------------------------------");
12270            }
12271            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12272            pw.println();
12273            if (dumpAll) {
12274                pw.println("-------------------------------------------------------------------------------");
12275            }
12276            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12277        }
12278        Binder.restoreCallingIdentity(origId);
12279    }
12280
12281    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12282            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12283        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12284
12285        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12286                dumpPackage);
12287        boolean needSep = printedAnything;
12288
12289        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12290                dumpPackage, needSep, "  mFocusedActivity: ");
12291        if (printed) {
12292            printedAnything = true;
12293            needSep = false;
12294        }
12295
12296        if (dumpPackage == null) {
12297            if (needSep) {
12298                pw.println();
12299            }
12300            needSep = true;
12301            printedAnything = true;
12302            mStackSupervisor.dump(pw, "  ");
12303        }
12304
12305        if (!printedAnything) {
12306            pw.println("  (nothing)");
12307        }
12308    }
12309
12310    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12311            int opti, boolean dumpAll, String dumpPackage) {
12312        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12313
12314        boolean printedAnything = false;
12315
12316        if (mRecentTasks.size() > 0) {
12317            boolean printedHeader = false;
12318
12319            final int N = mRecentTasks.size();
12320            for (int i=0; i<N; i++) {
12321                TaskRecord tr = mRecentTasks.get(i);
12322                if (dumpPackage != null) {
12323                    if (tr.realActivity == null ||
12324                            !dumpPackage.equals(tr.realActivity)) {
12325                        continue;
12326                    }
12327                }
12328                if (!printedHeader) {
12329                    pw.println("  Recent tasks:");
12330                    printedHeader = true;
12331                    printedAnything = true;
12332                }
12333                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12334                        pw.println(tr);
12335                if (dumpAll) {
12336                    mRecentTasks.get(i).dump(pw, "    ");
12337                }
12338            }
12339        }
12340
12341        if (!printedAnything) {
12342            pw.println("  (nothing)");
12343        }
12344    }
12345
12346    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12347            int opti, boolean dumpAll, String dumpPackage) {
12348        boolean needSep = false;
12349        boolean printedAnything = false;
12350        int numPers = 0;
12351
12352        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12353
12354        if (dumpAll) {
12355            final int NP = mProcessNames.getMap().size();
12356            for (int ip=0; ip<NP; ip++) {
12357                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12358                final int NA = procs.size();
12359                for (int ia=0; ia<NA; ia++) {
12360                    ProcessRecord r = procs.valueAt(ia);
12361                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12362                        continue;
12363                    }
12364                    if (!needSep) {
12365                        pw.println("  All known processes:");
12366                        needSep = true;
12367                        printedAnything = true;
12368                    }
12369                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12370                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12371                        pw.print(" "); pw.println(r);
12372                    r.dump(pw, "    ");
12373                    if (r.persistent) {
12374                        numPers++;
12375                    }
12376                }
12377            }
12378        }
12379
12380        if (mIsolatedProcesses.size() > 0) {
12381            boolean printed = false;
12382            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12383                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12384                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12385                    continue;
12386                }
12387                if (!printed) {
12388                    if (needSep) {
12389                        pw.println();
12390                    }
12391                    pw.println("  Isolated process list (sorted by uid):");
12392                    printedAnything = true;
12393                    printed = true;
12394                    needSep = true;
12395                }
12396                pw.println(String.format("%sIsolated #%2d: %s",
12397                        "    ", i, r.toString()));
12398            }
12399        }
12400
12401        if (mLruProcesses.size() > 0) {
12402            if (needSep) {
12403                pw.println();
12404            }
12405            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12406                    pw.print(" total, non-act at ");
12407                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12408                    pw.print(", non-svc at ");
12409                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12410                    pw.println("):");
12411            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12412            needSep = true;
12413            printedAnything = true;
12414        }
12415
12416        if (dumpAll || dumpPackage != null) {
12417            synchronized (mPidsSelfLocked) {
12418                boolean printed = false;
12419                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12420                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12421                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12422                        continue;
12423                    }
12424                    if (!printed) {
12425                        if (needSep) pw.println();
12426                        needSep = true;
12427                        pw.println("  PID mappings:");
12428                        printed = true;
12429                        printedAnything = true;
12430                    }
12431                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12432                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12433                }
12434            }
12435        }
12436
12437        if (mForegroundProcesses.size() > 0) {
12438            synchronized (mPidsSelfLocked) {
12439                boolean printed = false;
12440                for (int i=0; i<mForegroundProcesses.size(); i++) {
12441                    ProcessRecord r = mPidsSelfLocked.get(
12442                            mForegroundProcesses.valueAt(i).pid);
12443                    if (dumpPackage != null && (r == null
12444                            || !r.pkgList.containsKey(dumpPackage))) {
12445                        continue;
12446                    }
12447                    if (!printed) {
12448                        if (needSep) pw.println();
12449                        needSep = true;
12450                        pw.println("  Foreground Processes:");
12451                        printed = true;
12452                        printedAnything = true;
12453                    }
12454                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12455                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12456                }
12457            }
12458        }
12459
12460        if (mPersistentStartingProcesses.size() > 0) {
12461            if (needSep) pw.println();
12462            needSep = true;
12463            printedAnything = true;
12464            pw.println("  Persisent processes that are starting:");
12465            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12466                    "Starting Norm", "Restarting PERS", dumpPackage);
12467        }
12468
12469        if (mRemovedProcesses.size() > 0) {
12470            if (needSep) pw.println();
12471            needSep = true;
12472            printedAnything = true;
12473            pw.println("  Processes that are being removed:");
12474            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12475                    "Removed Norm", "Removed PERS", dumpPackage);
12476        }
12477
12478        if (mProcessesOnHold.size() > 0) {
12479            if (needSep) pw.println();
12480            needSep = true;
12481            printedAnything = true;
12482            pw.println("  Processes that are on old until the system is ready:");
12483            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12484                    "OnHold Norm", "OnHold PERS", dumpPackage);
12485        }
12486
12487        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12488
12489        if (mProcessCrashTimes.getMap().size() > 0) {
12490            boolean printed = false;
12491            long now = SystemClock.uptimeMillis();
12492            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12493            final int NP = pmap.size();
12494            for (int ip=0; ip<NP; ip++) {
12495                String pname = pmap.keyAt(ip);
12496                SparseArray<Long> uids = pmap.valueAt(ip);
12497                final int N = uids.size();
12498                for (int i=0; i<N; i++) {
12499                    int puid = uids.keyAt(i);
12500                    ProcessRecord r = mProcessNames.get(pname, puid);
12501                    if (dumpPackage != null && (r == null
12502                            || !r.pkgList.containsKey(dumpPackage))) {
12503                        continue;
12504                    }
12505                    if (!printed) {
12506                        if (needSep) pw.println();
12507                        needSep = true;
12508                        pw.println("  Time since processes crashed:");
12509                        printed = true;
12510                        printedAnything = true;
12511                    }
12512                    pw.print("    Process "); pw.print(pname);
12513                            pw.print(" uid "); pw.print(puid);
12514                            pw.print(": last crashed ");
12515                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12516                            pw.println(" ago");
12517                }
12518            }
12519        }
12520
12521        if (mBadProcesses.getMap().size() > 0) {
12522            boolean printed = false;
12523            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12524            final int NP = pmap.size();
12525            for (int ip=0; ip<NP; ip++) {
12526                String pname = pmap.keyAt(ip);
12527                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12528                final int N = uids.size();
12529                for (int i=0; i<N; i++) {
12530                    int puid = uids.keyAt(i);
12531                    ProcessRecord r = mProcessNames.get(pname, puid);
12532                    if (dumpPackage != null && (r == null
12533                            || !r.pkgList.containsKey(dumpPackage))) {
12534                        continue;
12535                    }
12536                    if (!printed) {
12537                        if (needSep) pw.println();
12538                        needSep = true;
12539                        pw.println("  Bad processes:");
12540                        printedAnything = true;
12541                    }
12542                    BadProcessInfo info = uids.valueAt(i);
12543                    pw.print("    Bad process "); pw.print(pname);
12544                            pw.print(" uid "); pw.print(puid);
12545                            pw.print(": crashed at time "); pw.println(info.time);
12546                    if (info.shortMsg != null) {
12547                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12548                    }
12549                    if (info.longMsg != null) {
12550                        pw.print("      Long msg: "); pw.println(info.longMsg);
12551                    }
12552                    if (info.stack != null) {
12553                        pw.println("      Stack:");
12554                        int lastPos = 0;
12555                        for (int pos=0; pos<info.stack.length(); pos++) {
12556                            if (info.stack.charAt(pos) == '\n') {
12557                                pw.print("        ");
12558                                pw.write(info.stack, lastPos, pos-lastPos);
12559                                pw.println();
12560                                lastPos = pos+1;
12561                            }
12562                        }
12563                        if (lastPos < info.stack.length()) {
12564                            pw.print("        ");
12565                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12566                            pw.println();
12567                        }
12568                    }
12569                }
12570            }
12571        }
12572
12573        if (dumpPackage == null) {
12574            pw.println();
12575            needSep = false;
12576            pw.println("  mStartedUsers:");
12577            for (int i=0; i<mStartedUsers.size(); i++) {
12578                UserStartedState uss = mStartedUsers.valueAt(i);
12579                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12580                        pw.print(": "); uss.dump("", pw);
12581            }
12582            pw.print("  mStartedUserArray: [");
12583            for (int i=0; i<mStartedUserArray.length; i++) {
12584                if (i > 0) pw.print(", ");
12585                pw.print(mStartedUserArray[i]);
12586            }
12587            pw.println("]");
12588            pw.print("  mUserLru: [");
12589            for (int i=0; i<mUserLru.size(); i++) {
12590                if (i > 0) pw.print(", ");
12591                pw.print(mUserLru.get(i));
12592            }
12593            pw.println("]");
12594            if (dumpAll) {
12595                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12596            }
12597            synchronized (mUserProfileGroupIdsSelfLocked) {
12598                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12599                    pw.println("  mUserProfileGroupIds:");
12600                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12601                        pw.print("    User #");
12602                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12603                        pw.print(" -> profile #");
12604                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12605                    }
12606                }
12607            }
12608        }
12609        if (mHomeProcess != null && (dumpPackage == null
12610                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12611            if (needSep) {
12612                pw.println();
12613                needSep = false;
12614            }
12615            pw.println("  mHomeProcess: " + mHomeProcess);
12616        }
12617        if (mPreviousProcess != null && (dumpPackage == null
12618                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12619            if (needSep) {
12620                pw.println();
12621                needSep = false;
12622            }
12623            pw.println("  mPreviousProcess: " + mPreviousProcess);
12624        }
12625        if (dumpAll) {
12626            StringBuilder sb = new StringBuilder(128);
12627            sb.append("  mPreviousProcessVisibleTime: ");
12628            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12629            pw.println(sb);
12630        }
12631        if (mHeavyWeightProcess != null && (dumpPackage == null
12632                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12633            if (needSep) {
12634                pw.println();
12635                needSep = false;
12636            }
12637            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12638        }
12639        if (dumpPackage == null) {
12640            pw.println("  mConfiguration: " + mConfiguration);
12641        }
12642        if (dumpAll) {
12643            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12644            if (mCompatModePackages.getPackages().size() > 0) {
12645                boolean printed = false;
12646                for (Map.Entry<String, Integer> entry
12647                        : mCompatModePackages.getPackages().entrySet()) {
12648                    String pkg = entry.getKey();
12649                    int mode = entry.getValue();
12650                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12651                        continue;
12652                    }
12653                    if (!printed) {
12654                        pw.println("  mScreenCompatPackages:");
12655                        printed = true;
12656                    }
12657                    pw.print("    "); pw.print(pkg); pw.print(": ");
12658                            pw.print(mode); pw.println();
12659                }
12660            }
12661        }
12662        if (dumpPackage == null) {
12663            if (mSleeping || mWentToSleep || mLockScreenShown) {
12664                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12665                        + " mLockScreenShown " + mLockScreenShown);
12666            }
12667            if (mShuttingDown || mRunningVoice) {
12668                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12669            }
12670        }
12671        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12672                || mOrigWaitForDebugger) {
12673            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12674                    || dumpPackage.equals(mOrigDebugApp)) {
12675                if (needSep) {
12676                    pw.println();
12677                    needSep = false;
12678                }
12679                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12680                        + " mDebugTransient=" + mDebugTransient
12681                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12682            }
12683        }
12684        if (mOpenGlTraceApp != null) {
12685            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12686                if (needSep) {
12687                    pw.println();
12688                    needSep = false;
12689                }
12690                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12691            }
12692        }
12693        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12694                || mProfileFd != null) {
12695            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12696                if (needSep) {
12697                    pw.println();
12698                    needSep = false;
12699                }
12700                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12701                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12702                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12703                        + mAutoStopProfiler);
12704                pw.println("  mProfileType=" + mProfileType);
12705            }
12706        }
12707        if (dumpPackage == null) {
12708            if (mAlwaysFinishActivities || mController != null) {
12709                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12710                        + " mController=" + mController);
12711            }
12712            if (dumpAll) {
12713                pw.println("  Total persistent processes: " + numPers);
12714                pw.println("  mProcessesReady=" + mProcessesReady
12715                        + " mSystemReady=" + mSystemReady);
12716                pw.println("  mBooting=" + mBooting
12717                        + " mBooted=" + mBooted
12718                        + " mFactoryTest=" + mFactoryTest);
12719                pw.print("  mLastPowerCheckRealtime=");
12720                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12721                        pw.println("");
12722                pw.print("  mLastPowerCheckUptime=");
12723                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12724                        pw.println("");
12725                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12726                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12727                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12728                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12729                        + " (" + mLruProcesses.size() + " total)"
12730                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12731                        + " mNumServiceProcs=" + mNumServiceProcs
12732                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12733                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12734                        + " mLastMemoryLevel" + mLastMemoryLevel
12735                        + " mLastNumProcesses" + mLastNumProcesses);
12736                long now = SystemClock.uptimeMillis();
12737                pw.print("  mLastIdleTime=");
12738                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12739                        pw.print(" mLowRamSinceLastIdle=");
12740                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12741                        pw.println();
12742            }
12743        }
12744
12745        if (!printedAnything) {
12746            pw.println("  (nothing)");
12747        }
12748    }
12749
12750    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12751            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12752        if (mProcessesToGc.size() > 0) {
12753            boolean printed = false;
12754            long now = SystemClock.uptimeMillis();
12755            for (int i=0; i<mProcessesToGc.size(); i++) {
12756                ProcessRecord proc = mProcessesToGc.get(i);
12757                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12758                    continue;
12759                }
12760                if (!printed) {
12761                    if (needSep) pw.println();
12762                    needSep = true;
12763                    pw.println("  Processes that are waiting to GC:");
12764                    printed = true;
12765                }
12766                pw.print("    Process "); pw.println(proc);
12767                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12768                        pw.print(", last gced=");
12769                        pw.print(now-proc.lastRequestedGc);
12770                        pw.print(" ms ago, last lowMem=");
12771                        pw.print(now-proc.lastLowMemory);
12772                        pw.println(" ms ago");
12773
12774            }
12775        }
12776        return needSep;
12777    }
12778
12779    void printOomLevel(PrintWriter pw, String name, int adj) {
12780        pw.print("    ");
12781        if (adj >= 0) {
12782            pw.print(' ');
12783            if (adj < 10) pw.print(' ');
12784        } else {
12785            if (adj > -10) pw.print(' ');
12786        }
12787        pw.print(adj);
12788        pw.print(": ");
12789        pw.print(name);
12790        pw.print(" (");
12791        pw.print(mProcessList.getMemLevel(adj)/1024);
12792        pw.println(" kB)");
12793    }
12794
12795    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12796            int opti, boolean dumpAll) {
12797        boolean needSep = false;
12798
12799        if (mLruProcesses.size() > 0) {
12800            if (needSep) pw.println();
12801            needSep = true;
12802            pw.println("  OOM levels:");
12803            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12804            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12805            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12806            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12807            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12808            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12809            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12810            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12811            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12812            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12813            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12814            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12815            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12816
12817            if (needSep) pw.println();
12818            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12819                    pw.print(" total, non-act at ");
12820                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12821                    pw.print(", non-svc at ");
12822                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12823                    pw.println("):");
12824            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12825            needSep = true;
12826        }
12827
12828        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12829
12830        pw.println();
12831        pw.println("  mHomeProcess: " + mHomeProcess);
12832        pw.println("  mPreviousProcess: " + mPreviousProcess);
12833        if (mHeavyWeightProcess != null) {
12834            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12835        }
12836
12837        return true;
12838    }
12839
12840    /**
12841     * There are three ways to call this:
12842     *  - no provider specified: dump all the providers
12843     *  - a flattened component name that matched an existing provider was specified as the
12844     *    first arg: dump that one provider
12845     *  - the first arg isn't the flattened component name of an existing provider:
12846     *    dump all providers whose component contains the first arg as a substring
12847     */
12848    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12849            int opti, boolean dumpAll) {
12850        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12851    }
12852
12853    static class ItemMatcher {
12854        ArrayList<ComponentName> components;
12855        ArrayList<String> strings;
12856        ArrayList<Integer> objects;
12857        boolean all;
12858
12859        ItemMatcher() {
12860            all = true;
12861        }
12862
12863        void build(String name) {
12864            ComponentName componentName = ComponentName.unflattenFromString(name);
12865            if (componentName != null) {
12866                if (components == null) {
12867                    components = new ArrayList<ComponentName>();
12868                }
12869                components.add(componentName);
12870                all = false;
12871            } else {
12872                int objectId = 0;
12873                // Not a '/' separated full component name; maybe an object ID?
12874                try {
12875                    objectId = Integer.parseInt(name, 16);
12876                    if (objects == null) {
12877                        objects = new ArrayList<Integer>();
12878                    }
12879                    objects.add(objectId);
12880                    all = false;
12881                } catch (RuntimeException e) {
12882                    // Not an integer; just do string match.
12883                    if (strings == null) {
12884                        strings = new ArrayList<String>();
12885                    }
12886                    strings.add(name);
12887                    all = false;
12888                }
12889            }
12890        }
12891
12892        int build(String[] args, int opti) {
12893            for (; opti<args.length; opti++) {
12894                String name = args[opti];
12895                if ("--".equals(name)) {
12896                    return opti+1;
12897                }
12898                build(name);
12899            }
12900            return opti;
12901        }
12902
12903        boolean match(Object object, ComponentName comp) {
12904            if (all) {
12905                return true;
12906            }
12907            if (components != null) {
12908                for (int i=0; i<components.size(); i++) {
12909                    if (components.get(i).equals(comp)) {
12910                        return true;
12911                    }
12912                }
12913            }
12914            if (objects != null) {
12915                for (int i=0; i<objects.size(); i++) {
12916                    if (System.identityHashCode(object) == objects.get(i)) {
12917                        return true;
12918                    }
12919                }
12920            }
12921            if (strings != null) {
12922                String flat = comp.flattenToString();
12923                for (int i=0; i<strings.size(); i++) {
12924                    if (flat.contains(strings.get(i))) {
12925                        return true;
12926                    }
12927                }
12928            }
12929            return false;
12930        }
12931    }
12932
12933    /**
12934     * There are three things that cmd can be:
12935     *  - a flattened component name that matches an existing activity
12936     *  - the cmd arg isn't the flattened component name of an existing activity:
12937     *    dump all activity whose component contains the cmd as a substring
12938     *  - A hex number of the ActivityRecord object instance.
12939     */
12940    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12941            int opti, boolean dumpAll) {
12942        ArrayList<ActivityRecord> activities;
12943
12944        synchronized (this) {
12945            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12946        }
12947
12948        if (activities.size() <= 0) {
12949            return false;
12950        }
12951
12952        String[] newArgs = new String[args.length - opti];
12953        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12954
12955        TaskRecord lastTask = null;
12956        boolean needSep = false;
12957        for (int i=activities.size()-1; i>=0; i--) {
12958            ActivityRecord r = activities.get(i);
12959            if (needSep) {
12960                pw.println();
12961            }
12962            needSep = true;
12963            synchronized (this) {
12964                if (lastTask != r.task) {
12965                    lastTask = r.task;
12966                    pw.print("TASK "); pw.print(lastTask.affinity);
12967                            pw.print(" id="); pw.println(lastTask.taskId);
12968                    if (dumpAll) {
12969                        lastTask.dump(pw, "  ");
12970                    }
12971                }
12972            }
12973            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12974        }
12975        return true;
12976    }
12977
12978    /**
12979     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12980     * there is a thread associated with the activity.
12981     */
12982    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12983            final ActivityRecord r, String[] args, boolean dumpAll) {
12984        String innerPrefix = prefix + "  ";
12985        synchronized (this) {
12986            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12987                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12988                    pw.print(" pid=");
12989                    if (r.app != null) pw.println(r.app.pid);
12990                    else pw.println("(not running)");
12991            if (dumpAll) {
12992                r.dump(pw, innerPrefix);
12993            }
12994        }
12995        if (r.app != null && r.app.thread != null) {
12996            // flush anything that is already in the PrintWriter since the thread is going
12997            // to write to the file descriptor directly
12998            pw.flush();
12999            try {
13000                TransferPipe tp = new TransferPipe();
13001                try {
13002                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13003                            r.appToken, innerPrefix, args);
13004                    tp.go(fd);
13005                } finally {
13006                    tp.kill();
13007                }
13008            } catch (IOException e) {
13009                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13010            } catch (RemoteException e) {
13011                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13012            }
13013        }
13014    }
13015
13016    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13017            int opti, boolean dumpAll, String dumpPackage) {
13018        boolean needSep = false;
13019        boolean onlyHistory = false;
13020        boolean printedAnything = false;
13021
13022        if ("history".equals(dumpPackage)) {
13023            if (opti < args.length && "-s".equals(args[opti])) {
13024                dumpAll = false;
13025            }
13026            onlyHistory = true;
13027            dumpPackage = null;
13028        }
13029
13030        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13031        if (!onlyHistory && dumpAll) {
13032            if (mRegisteredReceivers.size() > 0) {
13033                boolean printed = false;
13034                Iterator it = mRegisteredReceivers.values().iterator();
13035                while (it.hasNext()) {
13036                    ReceiverList r = (ReceiverList)it.next();
13037                    if (dumpPackage != null && (r.app == null ||
13038                            !dumpPackage.equals(r.app.info.packageName))) {
13039                        continue;
13040                    }
13041                    if (!printed) {
13042                        pw.println("  Registered Receivers:");
13043                        needSep = true;
13044                        printed = true;
13045                        printedAnything = true;
13046                    }
13047                    pw.print("  * "); pw.println(r);
13048                    r.dump(pw, "    ");
13049                }
13050            }
13051
13052            if (mReceiverResolver.dump(pw, needSep ?
13053                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13054                    "    ", dumpPackage, false)) {
13055                needSep = true;
13056                printedAnything = true;
13057            }
13058        }
13059
13060        for (BroadcastQueue q : mBroadcastQueues) {
13061            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13062            printedAnything |= needSep;
13063        }
13064
13065        needSep = true;
13066
13067        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13068            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13069                if (needSep) {
13070                    pw.println();
13071                }
13072                needSep = true;
13073                printedAnything = true;
13074                pw.print("  Sticky broadcasts for user ");
13075                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13076                StringBuilder sb = new StringBuilder(128);
13077                for (Map.Entry<String, ArrayList<Intent>> ent
13078                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13079                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13080                    if (dumpAll) {
13081                        pw.println(":");
13082                        ArrayList<Intent> intents = ent.getValue();
13083                        final int N = intents.size();
13084                        for (int i=0; i<N; i++) {
13085                            sb.setLength(0);
13086                            sb.append("    Intent: ");
13087                            intents.get(i).toShortString(sb, false, true, false, false);
13088                            pw.println(sb.toString());
13089                            Bundle bundle = intents.get(i).getExtras();
13090                            if (bundle != null) {
13091                                pw.print("      ");
13092                                pw.println(bundle.toString());
13093                            }
13094                        }
13095                    } else {
13096                        pw.println("");
13097                    }
13098                }
13099            }
13100        }
13101
13102        if (!onlyHistory && dumpAll) {
13103            pw.println();
13104            for (BroadcastQueue queue : mBroadcastQueues) {
13105                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13106                        + queue.mBroadcastsScheduled);
13107            }
13108            pw.println("  mHandler:");
13109            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13110            needSep = true;
13111            printedAnything = true;
13112        }
13113
13114        if (!printedAnything) {
13115            pw.println("  (nothing)");
13116        }
13117    }
13118
13119    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13120            int opti, boolean dumpAll, String dumpPackage) {
13121        boolean needSep;
13122        boolean printedAnything = false;
13123
13124        ItemMatcher matcher = new ItemMatcher();
13125        matcher.build(args, opti);
13126
13127        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13128
13129        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13130        printedAnything |= needSep;
13131
13132        if (mLaunchingProviders.size() > 0) {
13133            boolean printed = false;
13134            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13135                ContentProviderRecord r = mLaunchingProviders.get(i);
13136                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13137                    continue;
13138                }
13139                if (!printed) {
13140                    if (needSep) pw.println();
13141                    needSep = true;
13142                    pw.println("  Launching content providers:");
13143                    printed = true;
13144                    printedAnything = true;
13145                }
13146                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13147                        pw.println(r);
13148            }
13149        }
13150
13151        if (mGrantedUriPermissions.size() > 0) {
13152            boolean printed = false;
13153            int dumpUid = -2;
13154            if (dumpPackage != null) {
13155                try {
13156                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13157                } catch (NameNotFoundException e) {
13158                    dumpUid = -1;
13159                }
13160            }
13161            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13162                int uid = mGrantedUriPermissions.keyAt(i);
13163                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13164                    continue;
13165                }
13166                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13167                if (!printed) {
13168                    if (needSep) pw.println();
13169                    needSep = true;
13170                    pw.println("  Granted Uri Permissions:");
13171                    printed = true;
13172                    printedAnything = true;
13173                }
13174                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13175                for (UriPermission perm : perms.values()) {
13176                    pw.print("    "); pw.println(perm);
13177                    if (dumpAll) {
13178                        perm.dump(pw, "      ");
13179                    }
13180                }
13181            }
13182        }
13183
13184        if (!printedAnything) {
13185            pw.println("  (nothing)");
13186        }
13187    }
13188
13189    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13190            int opti, boolean dumpAll, String dumpPackage) {
13191        boolean printed = false;
13192
13193        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13194
13195        if (mIntentSenderRecords.size() > 0) {
13196            Iterator<WeakReference<PendingIntentRecord>> it
13197                    = mIntentSenderRecords.values().iterator();
13198            while (it.hasNext()) {
13199                WeakReference<PendingIntentRecord> ref = it.next();
13200                PendingIntentRecord rec = ref != null ? ref.get(): null;
13201                if (dumpPackage != null && (rec == null
13202                        || !dumpPackage.equals(rec.key.packageName))) {
13203                    continue;
13204                }
13205                printed = true;
13206                if (rec != null) {
13207                    pw.print("  * "); pw.println(rec);
13208                    if (dumpAll) {
13209                        rec.dump(pw, "    ");
13210                    }
13211                } else {
13212                    pw.print("  * "); pw.println(ref);
13213                }
13214            }
13215        }
13216
13217        if (!printed) {
13218            pw.println("  (nothing)");
13219        }
13220    }
13221
13222    private static final int dumpProcessList(PrintWriter pw,
13223            ActivityManagerService service, List list,
13224            String prefix, String normalLabel, String persistentLabel,
13225            String dumpPackage) {
13226        int numPers = 0;
13227        final int N = list.size()-1;
13228        for (int i=N; i>=0; i--) {
13229            ProcessRecord r = (ProcessRecord)list.get(i);
13230            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13231                continue;
13232            }
13233            pw.println(String.format("%s%s #%2d: %s",
13234                    prefix, (r.persistent ? persistentLabel : normalLabel),
13235                    i, r.toString()));
13236            if (r.persistent) {
13237                numPers++;
13238            }
13239        }
13240        return numPers;
13241    }
13242
13243    private static final boolean dumpProcessOomList(PrintWriter pw,
13244            ActivityManagerService service, List<ProcessRecord> origList,
13245            String prefix, String normalLabel, String persistentLabel,
13246            boolean inclDetails, String dumpPackage) {
13247
13248        ArrayList<Pair<ProcessRecord, Integer>> list
13249                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13250        for (int i=0; i<origList.size(); i++) {
13251            ProcessRecord r = origList.get(i);
13252            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13253                continue;
13254            }
13255            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13256        }
13257
13258        if (list.size() <= 0) {
13259            return false;
13260        }
13261
13262        Comparator<Pair<ProcessRecord, Integer>> comparator
13263                = new Comparator<Pair<ProcessRecord, Integer>>() {
13264            @Override
13265            public int compare(Pair<ProcessRecord, Integer> object1,
13266                    Pair<ProcessRecord, Integer> object2) {
13267                if (object1.first.setAdj != object2.first.setAdj) {
13268                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13269                }
13270                if (object1.second.intValue() != object2.second.intValue()) {
13271                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13272                }
13273                return 0;
13274            }
13275        };
13276
13277        Collections.sort(list, comparator);
13278
13279        final long curRealtime = SystemClock.elapsedRealtime();
13280        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13281        final long curUptime = SystemClock.uptimeMillis();
13282        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13283
13284        for (int i=list.size()-1; i>=0; i--) {
13285            ProcessRecord r = list.get(i).first;
13286            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13287            char schedGroup;
13288            switch (r.setSchedGroup) {
13289                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13290                    schedGroup = 'B';
13291                    break;
13292                case Process.THREAD_GROUP_DEFAULT:
13293                    schedGroup = 'F';
13294                    break;
13295                default:
13296                    schedGroup = '?';
13297                    break;
13298            }
13299            char foreground;
13300            if (r.foregroundActivities) {
13301                foreground = 'A';
13302            } else if (r.foregroundServices) {
13303                foreground = 'S';
13304            } else {
13305                foreground = ' ';
13306            }
13307            String procState = ProcessList.makeProcStateString(r.curProcState);
13308            pw.print(prefix);
13309            pw.print(r.persistent ? persistentLabel : normalLabel);
13310            pw.print(" #");
13311            int num = (origList.size()-1)-list.get(i).second;
13312            if (num < 10) pw.print(' ');
13313            pw.print(num);
13314            pw.print(": ");
13315            pw.print(oomAdj);
13316            pw.print(' ');
13317            pw.print(schedGroup);
13318            pw.print('/');
13319            pw.print(foreground);
13320            pw.print('/');
13321            pw.print(procState);
13322            pw.print(" trm:");
13323            if (r.trimMemoryLevel < 10) pw.print(' ');
13324            pw.print(r.trimMemoryLevel);
13325            pw.print(' ');
13326            pw.print(r.toShortString());
13327            pw.print(" (");
13328            pw.print(r.adjType);
13329            pw.println(')');
13330            if (r.adjSource != null || r.adjTarget != null) {
13331                pw.print(prefix);
13332                pw.print("    ");
13333                if (r.adjTarget instanceof ComponentName) {
13334                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13335                } else if (r.adjTarget != null) {
13336                    pw.print(r.adjTarget.toString());
13337                } else {
13338                    pw.print("{null}");
13339                }
13340                pw.print("<=");
13341                if (r.adjSource instanceof ProcessRecord) {
13342                    pw.print("Proc{");
13343                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13344                    pw.println("}");
13345                } else if (r.adjSource != null) {
13346                    pw.println(r.adjSource.toString());
13347                } else {
13348                    pw.println("{null}");
13349                }
13350            }
13351            if (inclDetails) {
13352                pw.print(prefix);
13353                pw.print("    ");
13354                pw.print("oom: max="); pw.print(r.maxAdj);
13355                pw.print(" curRaw="); pw.print(r.curRawAdj);
13356                pw.print(" setRaw="); pw.print(r.setRawAdj);
13357                pw.print(" cur="); pw.print(r.curAdj);
13358                pw.print(" set="); pw.println(r.setAdj);
13359                pw.print(prefix);
13360                pw.print("    ");
13361                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13362                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13363                pw.print(" lastPss="); pw.print(r.lastPss);
13364                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13365                pw.print(prefix);
13366                pw.print("    ");
13367                pw.print("cached="); pw.print(r.cached);
13368                pw.print(" empty="); pw.print(r.empty);
13369                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13370
13371                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13372                    if (r.lastWakeTime != 0) {
13373                        long wtime;
13374                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13375                        synchronized (stats) {
13376                            wtime = stats.getProcessWakeTime(r.info.uid,
13377                                    r.pid, curRealtime);
13378                        }
13379                        long timeUsed = wtime - r.lastWakeTime;
13380                        pw.print(prefix);
13381                        pw.print("    ");
13382                        pw.print("keep awake over ");
13383                        TimeUtils.formatDuration(realtimeSince, pw);
13384                        pw.print(" used ");
13385                        TimeUtils.formatDuration(timeUsed, pw);
13386                        pw.print(" (");
13387                        pw.print((timeUsed*100)/realtimeSince);
13388                        pw.println("%)");
13389                    }
13390                    if (r.lastCpuTime != 0) {
13391                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13392                        pw.print(prefix);
13393                        pw.print("    ");
13394                        pw.print("run cpu over ");
13395                        TimeUtils.formatDuration(uptimeSince, pw);
13396                        pw.print(" used ");
13397                        TimeUtils.formatDuration(timeUsed, pw);
13398                        pw.print(" (");
13399                        pw.print((timeUsed*100)/uptimeSince);
13400                        pw.println("%)");
13401                    }
13402                }
13403            }
13404        }
13405        return true;
13406    }
13407
13408    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13409        ArrayList<ProcessRecord> procs;
13410        synchronized (this) {
13411            if (args != null && args.length > start
13412                    && args[start].charAt(0) != '-') {
13413                procs = new ArrayList<ProcessRecord>();
13414                int pid = -1;
13415                try {
13416                    pid = Integer.parseInt(args[start]);
13417                } catch (NumberFormatException e) {
13418                }
13419                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13420                    ProcessRecord proc = mLruProcesses.get(i);
13421                    if (proc.pid == pid) {
13422                        procs.add(proc);
13423                    } else if (proc.processName.equals(args[start])) {
13424                        procs.add(proc);
13425                    }
13426                }
13427                if (procs.size() <= 0) {
13428                    return null;
13429                }
13430            } else {
13431                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13432            }
13433        }
13434        return procs;
13435    }
13436
13437    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13438            PrintWriter pw, String[] args) {
13439        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13440        if (procs == null) {
13441            pw.println("No process found for: " + args[0]);
13442            return;
13443        }
13444
13445        long uptime = SystemClock.uptimeMillis();
13446        long realtime = SystemClock.elapsedRealtime();
13447        pw.println("Applications Graphics Acceleration Info:");
13448        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13449
13450        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13451            ProcessRecord r = procs.get(i);
13452            if (r.thread != null) {
13453                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13454                pw.flush();
13455                try {
13456                    TransferPipe tp = new TransferPipe();
13457                    try {
13458                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13459                        tp.go(fd);
13460                    } finally {
13461                        tp.kill();
13462                    }
13463                } catch (IOException e) {
13464                    pw.println("Failure while dumping the app: " + r);
13465                    pw.flush();
13466                } catch (RemoteException e) {
13467                    pw.println("Got a RemoteException while dumping the app " + r);
13468                    pw.flush();
13469                }
13470            }
13471        }
13472    }
13473
13474    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13475        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13476        if (procs == null) {
13477            pw.println("No process found for: " + args[0]);
13478            return;
13479        }
13480
13481        pw.println("Applications Database Info:");
13482
13483        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13484            ProcessRecord r = procs.get(i);
13485            if (r.thread != null) {
13486                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13487                pw.flush();
13488                try {
13489                    TransferPipe tp = new TransferPipe();
13490                    try {
13491                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13492                        tp.go(fd);
13493                    } finally {
13494                        tp.kill();
13495                    }
13496                } catch (IOException e) {
13497                    pw.println("Failure while dumping the app: " + r);
13498                    pw.flush();
13499                } catch (RemoteException e) {
13500                    pw.println("Got a RemoteException while dumping the app " + r);
13501                    pw.flush();
13502                }
13503            }
13504        }
13505    }
13506
13507    final static class MemItem {
13508        final boolean isProc;
13509        final String label;
13510        final String shortLabel;
13511        final long pss;
13512        final int id;
13513        final boolean hasActivities;
13514        ArrayList<MemItem> subitems;
13515
13516        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13517                boolean _hasActivities) {
13518            isProc = true;
13519            label = _label;
13520            shortLabel = _shortLabel;
13521            pss = _pss;
13522            id = _id;
13523            hasActivities = _hasActivities;
13524        }
13525
13526        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13527            isProc = false;
13528            label = _label;
13529            shortLabel = _shortLabel;
13530            pss = _pss;
13531            id = _id;
13532            hasActivities = false;
13533        }
13534    }
13535
13536    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13537            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13538        if (sort && !isCompact) {
13539            Collections.sort(items, new Comparator<MemItem>() {
13540                @Override
13541                public int compare(MemItem lhs, MemItem rhs) {
13542                    if (lhs.pss < rhs.pss) {
13543                        return 1;
13544                    } else if (lhs.pss > rhs.pss) {
13545                        return -1;
13546                    }
13547                    return 0;
13548                }
13549            });
13550        }
13551
13552        for (int i=0; i<items.size(); i++) {
13553            MemItem mi = items.get(i);
13554            if (!isCompact) {
13555                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13556            } else if (mi.isProc) {
13557                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13558                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13559                pw.println(mi.hasActivities ? ",a" : ",e");
13560            } else {
13561                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13562                pw.println(mi.pss);
13563            }
13564            if (mi.subitems != null) {
13565                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13566                        true, isCompact);
13567            }
13568        }
13569    }
13570
13571    // These are in KB.
13572    static final long[] DUMP_MEM_BUCKETS = new long[] {
13573        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13574        120*1024, 160*1024, 200*1024,
13575        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13576        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13577    };
13578
13579    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13580            boolean stackLike) {
13581        int start = label.lastIndexOf('.');
13582        if (start >= 0) start++;
13583        else start = 0;
13584        int end = label.length();
13585        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13586            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13587                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13588                out.append(bucket);
13589                out.append(stackLike ? "MB." : "MB ");
13590                out.append(label, start, end);
13591                return;
13592            }
13593        }
13594        out.append(memKB/1024);
13595        out.append(stackLike ? "MB." : "MB ");
13596        out.append(label, start, end);
13597    }
13598
13599    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13600            ProcessList.NATIVE_ADJ,
13601            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13602            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13603            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13604            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13605            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13606    };
13607    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13608            "Native",
13609            "System", "Persistent", "Foreground",
13610            "Visible", "Perceptible",
13611            "Heavy Weight", "Backup",
13612            "A Services", "Home",
13613            "Previous", "B Services", "Cached"
13614    };
13615    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13616            "native",
13617            "sys", "pers", "fore",
13618            "vis", "percept",
13619            "heavy", "backup",
13620            "servicea", "home",
13621            "prev", "serviceb", "cached"
13622    };
13623
13624    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13625            long realtime, boolean isCheckinRequest, boolean isCompact) {
13626        if (isCheckinRequest || isCompact) {
13627            // short checkin version
13628            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13629        } else {
13630            pw.println("Applications Memory Usage (kB):");
13631            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13632        }
13633    }
13634
13635    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13636            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13637        boolean dumpDetails = false;
13638        boolean dumpFullDetails = false;
13639        boolean dumpDalvik = false;
13640        boolean oomOnly = false;
13641        boolean isCompact = false;
13642        boolean localOnly = false;
13643
13644        int opti = 0;
13645        while (opti < args.length) {
13646            String opt = args[opti];
13647            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13648                break;
13649            }
13650            opti++;
13651            if ("-a".equals(opt)) {
13652                dumpDetails = true;
13653                dumpFullDetails = true;
13654                dumpDalvik = true;
13655            } else if ("-d".equals(opt)) {
13656                dumpDalvik = true;
13657            } else if ("-c".equals(opt)) {
13658                isCompact = true;
13659            } else if ("--oom".equals(opt)) {
13660                oomOnly = true;
13661            } else if ("--local".equals(opt)) {
13662                localOnly = true;
13663            } else if ("-h".equals(opt)) {
13664                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13665                pw.println("  -a: include all available information for each process.");
13666                pw.println("  -d: include dalvik details when dumping process details.");
13667                pw.println("  -c: dump in a compact machine-parseable representation.");
13668                pw.println("  --oom: only show processes organized by oom adj.");
13669                pw.println("  --local: only collect details locally, don't call process.");
13670                pw.println("If [process] is specified it can be the name or ");
13671                pw.println("pid of a specific process to dump.");
13672                return;
13673            } else {
13674                pw.println("Unknown argument: " + opt + "; use -h for help");
13675            }
13676        }
13677
13678        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13679        long uptime = SystemClock.uptimeMillis();
13680        long realtime = SystemClock.elapsedRealtime();
13681        final long[] tmpLong = new long[1];
13682
13683        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13684        if (procs == null) {
13685            // No Java processes.  Maybe they want to print a native process.
13686            if (args != null && args.length > opti
13687                    && args[opti].charAt(0) != '-') {
13688                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13689                        = new ArrayList<ProcessCpuTracker.Stats>();
13690                updateCpuStatsNow();
13691                int findPid = -1;
13692                try {
13693                    findPid = Integer.parseInt(args[opti]);
13694                } catch (NumberFormatException e) {
13695                }
13696                synchronized (mProcessCpuThread) {
13697                    final int N = mProcessCpuTracker.countStats();
13698                    for (int i=0; i<N; i++) {
13699                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13700                        if (st.pid == findPid || (st.baseName != null
13701                                && st.baseName.equals(args[opti]))) {
13702                            nativeProcs.add(st);
13703                        }
13704                    }
13705                }
13706                if (nativeProcs.size() > 0) {
13707                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13708                            isCompact);
13709                    Debug.MemoryInfo mi = null;
13710                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13711                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13712                        final int pid = r.pid;
13713                        if (!isCheckinRequest && dumpDetails) {
13714                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13715                        }
13716                        if (mi == null) {
13717                            mi = new Debug.MemoryInfo();
13718                        }
13719                        if (dumpDetails || (!brief && !oomOnly)) {
13720                            Debug.getMemoryInfo(pid, mi);
13721                        } else {
13722                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13723                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13724                        }
13725                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13726                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13727                        if (isCheckinRequest) {
13728                            pw.println();
13729                        }
13730                    }
13731                    return;
13732                }
13733            }
13734            pw.println("No process found for: " + args[opti]);
13735            return;
13736        }
13737
13738        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13739            dumpDetails = true;
13740        }
13741
13742        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13743
13744        String[] innerArgs = new String[args.length-opti];
13745        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13746
13747        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13748        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13749        long nativePss=0, dalvikPss=0, otherPss=0;
13750        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13751
13752        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13753        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13754                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13755
13756        long totalPss = 0;
13757        long cachedPss = 0;
13758
13759        Debug.MemoryInfo mi = null;
13760        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13761            final ProcessRecord r = procs.get(i);
13762            final IApplicationThread thread;
13763            final int pid;
13764            final int oomAdj;
13765            final boolean hasActivities;
13766            synchronized (this) {
13767                thread = r.thread;
13768                pid = r.pid;
13769                oomAdj = r.getSetAdjWithServices();
13770                hasActivities = r.activities.size() > 0;
13771            }
13772            if (thread != null) {
13773                if (!isCheckinRequest && dumpDetails) {
13774                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13775                }
13776                if (mi == null) {
13777                    mi = new Debug.MemoryInfo();
13778                }
13779                if (dumpDetails || (!brief && !oomOnly)) {
13780                    Debug.getMemoryInfo(pid, mi);
13781                } else {
13782                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13783                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13784                }
13785                if (dumpDetails) {
13786                    if (localOnly) {
13787                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13788                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13789                        if (isCheckinRequest) {
13790                            pw.println();
13791                        }
13792                    } else {
13793                        try {
13794                            pw.flush();
13795                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13796                                    dumpDalvik, innerArgs);
13797                        } catch (RemoteException e) {
13798                            if (!isCheckinRequest) {
13799                                pw.println("Got RemoteException!");
13800                                pw.flush();
13801                            }
13802                        }
13803                    }
13804                }
13805
13806                final long myTotalPss = mi.getTotalPss();
13807                final long myTotalUss = mi.getTotalUss();
13808
13809                synchronized (this) {
13810                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13811                        // Record this for posterity if the process has been stable.
13812                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13813                    }
13814                }
13815
13816                if (!isCheckinRequest && mi != null) {
13817                    totalPss += myTotalPss;
13818                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13819                            (hasActivities ? " / activities)" : ")"),
13820                            r.processName, myTotalPss, pid, hasActivities);
13821                    procMems.add(pssItem);
13822                    procMemsMap.put(pid, pssItem);
13823
13824                    nativePss += mi.nativePss;
13825                    dalvikPss += mi.dalvikPss;
13826                    otherPss += mi.otherPss;
13827                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13828                        long mem = mi.getOtherPss(j);
13829                        miscPss[j] += mem;
13830                        otherPss -= mem;
13831                    }
13832
13833                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13834                        cachedPss += myTotalPss;
13835                    }
13836
13837                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13838                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13839                                || oomIndex == (oomPss.length-1)) {
13840                            oomPss[oomIndex] += myTotalPss;
13841                            if (oomProcs[oomIndex] == null) {
13842                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13843                            }
13844                            oomProcs[oomIndex].add(pssItem);
13845                            break;
13846                        }
13847                    }
13848                }
13849            }
13850        }
13851
13852        long nativeProcTotalPss = 0;
13853
13854        if (!isCheckinRequest && procs.size() > 1) {
13855            // If we are showing aggregations, also look for native processes to
13856            // include so that our aggregations are more accurate.
13857            updateCpuStatsNow();
13858            synchronized (mProcessCpuThread) {
13859                final int N = mProcessCpuTracker.countStats();
13860                for (int i=0; i<N; i++) {
13861                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13862                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13863                        if (mi == null) {
13864                            mi = new Debug.MemoryInfo();
13865                        }
13866                        if (!brief && !oomOnly) {
13867                            Debug.getMemoryInfo(st.pid, mi);
13868                        } else {
13869                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13870                            mi.nativePrivateDirty = (int)tmpLong[0];
13871                        }
13872
13873                        final long myTotalPss = mi.getTotalPss();
13874                        totalPss += myTotalPss;
13875                        nativeProcTotalPss += myTotalPss;
13876
13877                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13878                                st.name, myTotalPss, st.pid, false);
13879                        procMems.add(pssItem);
13880
13881                        nativePss += mi.nativePss;
13882                        dalvikPss += mi.dalvikPss;
13883                        otherPss += mi.otherPss;
13884                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13885                            long mem = mi.getOtherPss(j);
13886                            miscPss[j] += mem;
13887                            otherPss -= mem;
13888                        }
13889                        oomPss[0] += myTotalPss;
13890                        if (oomProcs[0] == null) {
13891                            oomProcs[0] = new ArrayList<MemItem>();
13892                        }
13893                        oomProcs[0].add(pssItem);
13894                    }
13895                }
13896            }
13897
13898            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13899
13900            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13901            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13902            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13903            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13904                String label = Debug.MemoryInfo.getOtherLabel(j);
13905                catMems.add(new MemItem(label, label, miscPss[j], j));
13906            }
13907
13908            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13909            for (int j=0; j<oomPss.length; j++) {
13910                if (oomPss[j] != 0) {
13911                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13912                            : DUMP_MEM_OOM_LABEL[j];
13913                    MemItem item = new MemItem(label, label, oomPss[j],
13914                            DUMP_MEM_OOM_ADJ[j]);
13915                    item.subitems = oomProcs[j];
13916                    oomMems.add(item);
13917                }
13918            }
13919
13920            if (!brief && !oomOnly && !isCompact) {
13921                pw.println();
13922                pw.println("Total PSS by process:");
13923                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13924                pw.println();
13925            }
13926            if (!isCompact) {
13927                pw.println("Total PSS by OOM adjustment:");
13928            }
13929            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13930            if (!brief && !oomOnly) {
13931                PrintWriter out = categoryPw != null ? categoryPw : pw;
13932                if (!isCompact) {
13933                    out.println();
13934                    out.println("Total PSS by category:");
13935                }
13936                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13937            }
13938            if (!isCompact) {
13939                pw.println();
13940            }
13941            MemInfoReader memInfo = new MemInfoReader();
13942            memInfo.readMemInfo();
13943            if (nativeProcTotalPss > 0) {
13944                synchronized (this) {
13945                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13946                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13947                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13948                            nativeProcTotalPss);
13949                }
13950            }
13951            if (!brief) {
13952                if (!isCompact) {
13953                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13954                    pw.print(" kB (status ");
13955                    switch (mLastMemoryLevel) {
13956                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13957                            pw.println("normal)");
13958                            break;
13959                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13960                            pw.println("moderate)");
13961                            break;
13962                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13963                            pw.println("low)");
13964                            break;
13965                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13966                            pw.println("critical)");
13967                            break;
13968                        default:
13969                            pw.print(mLastMemoryLevel);
13970                            pw.println(")");
13971                            break;
13972                    }
13973                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13974                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13975                            pw.print(cachedPss); pw.print(" cached pss + ");
13976                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13977                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13978                } else {
13979                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13980                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13981                            + memInfo.getFreeSizeKb()); pw.print(",");
13982                    pw.println(totalPss - cachedPss);
13983                }
13984            }
13985            if (!isCompact) {
13986                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13987                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13988                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13989                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13990                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13991                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13992                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13993                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13994                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13995                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13996                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13997            }
13998            if (!brief) {
13999                if (memInfo.getZramTotalSizeKb() != 0) {
14000                    if (!isCompact) {
14001                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14002                                pw.print(" kB physical used for ");
14003                                pw.print(memInfo.getSwapTotalSizeKb()
14004                                        - memInfo.getSwapFreeSizeKb());
14005                                pw.print(" kB in swap (");
14006                                pw.print(memInfo.getSwapTotalSizeKb());
14007                                pw.println(" kB total swap)");
14008                    } else {
14009                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14010                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14011                                pw.println(memInfo.getSwapFreeSizeKb());
14012                    }
14013                }
14014                final int[] SINGLE_LONG_FORMAT = new int[] {
14015                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14016                };
14017                long[] longOut = new long[1];
14018                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14019                        SINGLE_LONG_FORMAT, null, longOut, null);
14020                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14021                longOut[0] = 0;
14022                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14023                        SINGLE_LONG_FORMAT, null, longOut, null);
14024                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14025                longOut[0] = 0;
14026                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14027                        SINGLE_LONG_FORMAT, null, longOut, null);
14028                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14029                longOut[0] = 0;
14030                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14031                        SINGLE_LONG_FORMAT, null, longOut, null);
14032                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14033                if (!isCompact) {
14034                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14035                        pw.print("      KSM: "); pw.print(sharing);
14036                                pw.print(" kB saved from shared ");
14037                                pw.print(shared); pw.println(" kB");
14038                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14039                                pw.print(voltile); pw.println(" kB volatile");
14040                    }
14041                    pw.print("   Tuning: ");
14042                    pw.print(ActivityManager.staticGetMemoryClass());
14043                    pw.print(" (large ");
14044                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14045                    pw.print("), oom ");
14046                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14047                    pw.print(" kB");
14048                    pw.print(", restore limit ");
14049                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14050                    pw.print(" kB");
14051                    if (ActivityManager.isLowRamDeviceStatic()) {
14052                        pw.print(" (low-ram)");
14053                    }
14054                    if (ActivityManager.isHighEndGfx()) {
14055                        pw.print(" (high-end-gfx)");
14056                    }
14057                    pw.println();
14058                } else {
14059                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14060                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14061                    pw.println(voltile);
14062                    pw.print("tuning,");
14063                    pw.print(ActivityManager.staticGetMemoryClass());
14064                    pw.print(',');
14065                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14066                    pw.print(',');
14067                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14068                    if (ActivityManager.isLowRamDeviceStatic()) {
14069                        pw.print(",low-ram");
14070                    }
14071                    if (ActivityManager.isHighEndGfx()) {
14072                        pw.print(",high-end-gfx");
14073                    }
14074                    pw.println();
14075                }
14076            }
14077        }
14078    }
14079
14080    /**
14081     * Searches array of arguments for the specified string
14082     * @param args array of argument strings
14083     * @param value value to search for
14084     * @return true if the value is contained in the array
14085     */
14086    private static boolean scanArgs(String[] args, String value) {
14087        if (args != null) {
14088            for (String arg : args) {
14089                if (value.equals(arg)) {
14090                    return true;
14091                }
14092            }
14093        }
14094        return false;
14095    }
14096
14097    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14098            ContentProviderRecord cpr, boolean always) {
14099        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14100
14101        if (!inLaunching || always) {
14102            synchronized (cpr) {
14103                cpr.launchingApp = null;
14104                cpr.notifyAll();
14105            }
14106            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14107            String names[] = cpr.info.authority.split(";");
14108            for (int j = 0; j < names.length; j++) {
14109                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14110            }
14111        }
14112
14113        for (int i=0; i<cpr.connections.size(); i++) {
14114            ContentProviderConnection conn = cpr.connections.get(i);
14115            if (conn.waiting) {
14116                // If this connection is waiting for the provider, then we don't
14117                // need to mess with its process unless we are always removing
14118                // or for some reason the provider is not currently launching.
14119                if (inLaunching && !always) {
14120                    continue;
14121                }
14122            }
14123            ProcessRecord capp = conn.client;
14124            conn.dead = true;
14125            if (conn.stableCount > 0) {
14126                if (!capp.persistent && capp.thread != null
14127                        && capp.pid != 0
14128                        && capp.pid != MY_PID) {
14129                    capp.kill("depends on provider "
14130                            + cpr.name.flattenToShortString()
14131                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14132                }
14133            } else if (capp.thread != null && conn.provider.provider != null) {
14134                try {
14135                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14136                } catch (RemoteException e) {
14137                }
14138                // In the protocol here, we don't expect the client to correctly
14139                // clean up this connection, we'll just remove it.
14140                cpr.connections.remove(i);
14141                conn.client.conProviders.remove(conn);
14142            }
14143        }
14144
14145        if (inLaunching && always) {
14146            mLaunchingProviders.remove(cpr);
14147        }
14148        return inLaunching;
14149    }
14150
14151    /**
14152     * Main code for cleaning up a process when it has gone away.  This is
14153     * called both as a result of the process dying, or directly when stopping
14154     * a process when running in single process mode.
14155     */
14156    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14157            boolean restarting, boolean allowRestart, int index) {
14158        if (index >= 0) {
14159            removeLruProcessLocked(app);
14160            ProcessList.remove(app.pid);
14161        }
14162
14163        mProcessesToGc.remove(app);
14164        mPendingPssProcesses.remove(app);
14165
14166        // Dismiss any open dialogs.
14167        if (app.crashDialog != null && !app.forceCrashReport) {
14168            app.crashDialog.dismiss();
14169            app.crashDialog = null;
14170        }
14171        if (app.anrDialog != null) {
14172            app.anrDialog.dismiss();
14173            app.anrDialog = null;
14174        }
14175        if (app.waitDialog != null) {
14176            app.waitDialog.dismiss();
14177            app.waitDialog = null;
14178        }
14179
14180        app.crashing = false;
14181        app.notResponding = false;
14182
14183        app.resetPackageList(mProcessStats);
14184        app.unlinkDeathRecipient();
14185        app.makeInactive(mProcessStats);
14186        app.waitingToKill = null;
14187        app.forcingToForeground = null;
14188        updateProcessForegroundLocked(app, false, false);
14189        app.foregroundActivities = false;
14190        app.hasShownUi = false;
14191        app.treatLikeActivity = false;
14192        app.hasAboveClient = false;
14193        app.hasClientActivities = false;
14194
14195        mServices.killServicesLocked(app, allowRestart);
14196
14197        boolean restart = false;
14198
14199        // Remove published content providers.
14200        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14201            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14202            final boolean always = app.bad || !allowRestart;
14203            if (removeDyingProviderLocked(app, cpr, always) || always) {
14204                // We left the provider in the launching list, need to
14205                // restart it.
14206                restart = true;
14207            }
14208
14209            cpr.provider = null;
14210            cpr.proc = null;
14211        }
14212        app.pubProviders.clear();
14213
14214        // Take care of any launching providers waiting for this process.
14215        if (checkAppInLaunchingProvidersLocked(app, false)) {
14216            restart = true;
14217        }
14218
14219        // Unregister from connected content providers.
14220        if (!app.conProviders.isEmpty()) {
14221            for (int i=0; i<app.conProviders.size(); i++) {
14222                ContentProviderConnection conn = app.conProviders.get(i);
14223                conn.provider.connections.remove(conn);
14224            }
14225            app.conProviders.clear();
14226        }
14227
14228        // At this point there may be remaining entries in mLaunchingProviders
14229        // where we were the only one waiting, so they are no longer of use.
14230        // Look for these and clean up if found.
14231        // XXX Commented out for now.  Trying to figure out a way to reproduce
14232        // the actual situation to identify what is actually going on.
14233        if (false) {
14234            for (int i=0; i<mLaunchingProviders.size(); i++) {
14235                ContentProviderRecord cpr = (ContentProviderRecord)
14236                        mLaunchingProviders.get(i);
14237                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14238                    synchronized (cpr) {
14239                        cpr.launchingApp = null;
14240                        cpr.notifyAll();
14241                    }
14242                }
14243            }
14244        }
14245
14246        skipCurrentReceiverLocked(app);
14247
14248        // Unregister any receivers.
14249        for (int i=app.receivers.size()-1; i>=0; i--) {
14250            removeReceiverLocked(app.receivers.valueAt(i));
14251        }
14252        app.receivers.clear();
14253
14254        // If the app is undergoing backup, tell the backup manager about it
14255        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14256            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14257                    + mBackupTarget.appInfo + " died during backup");
14258            try {
14259                IBackupManager bm = IBackupManager.Stub.asInterface(
14260                        ServiceManager.getService(Context.BACKUP_SERVICE));
14261                bm.agentDisconnected(app.info.packageName);
14262            } catch (RemoteException e) {
14263                // can't happen; backup manager is local
14264            }
14265        }
14266
14267        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14268            ProcessChangeItem item = mPendingProcessChanges.get(i);
14269            if (item.pid == app.pid) {
14270                mPendingProcessChanges.remove(i);
14271                mAvailProcessChanges.add(item);
14272            }
14273        }
14274        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14275
14276        // If the caller is restarting this app, then leave it in its
14277        // current lists and let the caller take care of it.
14278        if (restarting) {
14279            return;
14280        }
14281
14282        if (!app.persistent || app.isolated) {
14283            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14284                    "Removing non-persistent process during cleanup: " + app);
14285            mProcessNames.remove(app.processName, app.uid);
14286            mIsolatedProcesses.remove(app.uid);
14287            if (mHeavyWeightProcess == app) {
14288                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14289                        mHeavyWeightProcess.userId, 0));
14290                mHeavyWeightProcess = null;
14291            }
14292        } else if (!app.removed) {
14293            // This app is persistent, so we need to keep its record around.
14294            // If it is not already on the pending app list, add it there
14295            // and start a new process for it.
14296            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14297                mPersistentStartingProcesses.add(app);
14298                restart = true;
14299            }
14300        }
14301        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14302                "Clean-up removing on hold: " + app);
14303        mProcessesOnHold.remove(app);
14304
14305        if (app == mHomeProcess) {
14306            mHomeProcess = null;
14307        }
14308        if (app == mPreviousProcess) {
14309            mPreviousProcess = null;
14310        }
14311
14312        if (restart && !app.isolated) {
14313            // We have components that still need to be running in the
14314            // process, so re-launch it.
14315            mProcessNames.put(app.processName, app.uid, app);
14316            startProcessLocked(app, "restart", app.processName);
14317        } else if (app.pid > 0 && app.pid != MY_PID) {
14318            // Goodbye!
14319            boolean removed;
14320            synchronized (mPidsSelfLocked) {
14321                mPidsSelfLocked.remove(app.pid);
14322                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14323            }
14324            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14325            if (app.isolated) {
14326                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14327            }
14328            app.setPid(0);
14329        }
14330    }
14331
14332    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14333        // Look through the content providers we are waiting to have launched,
14334        // and if any run in this process then either schedule a restart of
14335        // the process or kill the client waiting for it if this process has
14336        // gone bad.
14337        int NL = mLaunchingProviders.size();
14338        boolean restart = false;
14339        for (int i=0; i<NL; i++) {
14340            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14341            if (cpr.launchingApp == app) {
14342                if (!alwaysBad && !app.bad) {
14343                    restart = true;
14344                } else {
14345                    removeDyingProviderLocked(app, cpr, true);
14346                    // cpr should have been removed from mLaunchingProviders
14347                    NL = mLaunchingProviders.size();
14348                    i--;
14349                }
14350            }
14351        }
14352        return restart;
14353    }
14354
14355    // =========================================================
14356    // SERVICES
14357    // =========================================================
14358
14359    @Override
14360    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14361            int flags) {
14362        enforceNotIsolatedCaller("getServices");
14363        synchronized (this) {
14364            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14365        }
14366    }
14367
14368    @Override
14369    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14370        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14371        synchronized (this) {
14372            return mServices.getRunningServiceControlPanelLocked(name);
14373        }
14374    }
14375
14376    @Override
14377    public ComponentName startService(IApplicationThread caller, Intent service,
14378            String resolvedType, int userId) {
14379        enforceNotIsolatedCaller("startService");
14380        // Refuse possible leaked file descriptors
14381        if (service != null && service.hasFileDescriptors() == true) {
14382            throw new IllegalArgumentException("File descriptors passed in Intent");
14383        }
14384
14385        if (DEBUG_SERVICE)
14386            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14387        synchronized(this) {
14388            final int callingPid = Binder.getCallingPid();
14389            final int callingUid = Binder.getCallingUid();
14390            final long origId = Binder.clearCallingIdentity();
14391            ComponentName res = mServices.startServiceLocked(caller, service,
14392                    resolvedType, callingPid, callingUid, userId);
14393            Binder.restoreCallingIdentity(origId);
14394            return res;
14395        }
14396    }
14397
14398    ComponentName startServiceInPackage(int uid,
14399            Intent service, String resolvedType, int userId) {
14400        synchronized(this) {
14401            if (DEBUG_SERVICE)
14402                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14403            final long origId = Binder.clearCallingIdentity();
14404            ComponentName res = mServices.startServiceLocked(null, service,
14405                    resolvedType, -1, uid, userId);
14406            Binder.restoreCallingIdentity(origId);
14407            return res;
14408        }
14409    }
14410
14411    @Override
14412    public int stopService(IApplicationThread caller, Intent service,
14413            String resolvedType, int userId) {
14414        enforceNotIsolatedCaller("stopService");
14415        // Refuse possible leaked file descriptors
14416        if (service != null && service.hasFileDescriptors() == true) {
14417            throw new IllegalArgumentException("File descriptors passed in Intent");
14418        }
14419
14420        synchronized(this) {
14421            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14422        }
14423    }
14424
14425    @Override
14426    public IBinder peekService(Intent service, String resolvedType) {
14427        enforceNotIsolatedCaller("peekService");
14428        // Refuse possible leaked file descriptors
14429        if (service != null && service.hasFileDescriptors() == true) {
14430            throw new IllegalArgumentException("File descriptors passed in Intent");
14431        }
14432        synchronized(this) {
14433            return mServices.peekServiceLocked(service, resolvedType);
14434        }
14435    }
14436
14437    @Override
14438    public boolean stopServiceToken(ComponentName className, IBinder token,
14439            int startId) {
14440        synchronized(this) {
14441            return mServices.stopServiceTokenLocked(className, token, startId);
14442        }
14443    }
14444
14445    @Override
14446    public void setServiceForeground(ComponentName className, IBinder token,
14447            int id, Notification notification, boolean removeNotification) {
14448        synchronized(this) {
14449            mServices.setServiceForegroundLocked(className, token, id, notification,
14450                    removeNotification);
14451        }
14452    }
14453
14454    @Override
14455    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14456            boolean requireFull, String name, String callerPackage) {
14457        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14458                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14459    }
14460
14461    int unsafeConvertIncomingUser(int userId) {
14462        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14463                ? mCurrentUserId : userId;
14464    }
14465
14466    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14467            int allowMode, String name, String callerPackage) {
14468        final int callingUserId = UserHandle.getUserId(callingUid);
14469        if (callingUserId == userId) {
14470            return userId;
14471        }
14472
14473        // Note that we may be accessing mCurrentUserId outside of a lock...
14474        // shouldn't be a big deal, if this is being called outside
14475        // of a locked context there is intrinsically a race with
14476        // the value the caller will receive and someone else changing it.
14477        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14478        // we will switch to the calling user if access to the current user fails.
14479        int targetUserId = unsafeConvertIncomingUser(userId);
14480
14481        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14482            final boolean allow;
14483            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14484                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14485                // If the caller has this permission, they always pass go.  And collect $200.
14486                allow = true;
14487            } else if (allowMode == ALLOW_FULL_ONLY) {
14488                // We require full access, sucks to be you.
14489                allow = false;
14490            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14491                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14492                // If the caller does not have either permission, they are always doomed.
14493                allow = false;
14494            } else if (allowMode == ALLOW_NON_FULL) {
14495                // We are blanket allowing non-full access, you lucky caller!
14496                allow = true;
14497            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14498                // We may or may not allow this depending on whether the two users are
14499                // in the same profile.
14500                synchronized (mUserProfileGroupIdsSelfLocked) {
14501                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14502                            UserInfo.NO_PROFILE_GROUP_ID);
14503                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14504                            UserInfo.NO_PROFILE_GROUP_ID);
14505                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14506                            && callingProfile == targetProfile;
14507                }
14508            } else {
14509                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14510            }
14511            if (!allow) {
14512                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14513                    // In this case, they would like to just execute as their
14514                    // owner user instead of failing.
14515                    targetUserId = callingUserId;
14516                } else {
14517                    StringBuilder builder = new StringBuilder(128);
14518                    builder.append("Permission Denial: ");
14519                    builder.append(name);
14520                    if (callerPackage != null) {
14521                        builder.append(" from ");
14522                        builder.append(callerPackage);
14523                    }
14524                    builder.append(" asks to run as user ");
14525                    builder.append(userId);
14526                    builder.append(" but is calling from user ");
14527                    builder.append(UserHandle.getUserId(callingUid));
14528                    builder.append("; this requires ");
14529                    builder.append(INTERACT_ACROSS_USERS_FULL);
14530                    if (allowMode != ALLOW_FULL_ONLY) {
14531                        builder.append(" or ");
14532                        builder.append(INTERACT_ACROSS_USERS);
14533                    }
14534                    String msg = builder.toString();
14535                    Slog.w(TAG, msg);
14536                    throw new SecurityException(msg);
14537                }
14538            }
14539        }
14540        if (!allowAll && targetUserId < 0) {
14541            throw new IllegalArgumentException(
14542                    "Call does not support special user #" + targetUserId);
14543        }
14544        return targetUserId;
14545    }
14546
14547    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14548            String className, int flags) {
14549        boolean result = false;
14550        // For apps that don't have pre-defined UIDs, check for permission
14551        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14552            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14553                if (ActivityManager.checkUidPermission(
14554                        INTERACT_ACROSS_USERS,
14555                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14556                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14557                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14558                            + " requests FLAG_SINGLE_USER, but app does not hold "
14559                            + INTERACT_ACROSS_USERS;
14560                    Slog.w(TAG, msg);
14561                    throw new SecurityException(msg);
14562                }
14563                // Permission passed
14564                result = true;
14565            }
14566        } else if ("system".equals(componentProcessName)) {
14567            result = true;
14568        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14569                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14570            // Phone app is allowed to export singleuser providers.
14571            result = true;
14572        } else {
14573            // App with pre-defined UID, check if it's a persistent app
14574            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14575        }
14576        if (DEBUG_MU) {
14577            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14578                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14579        }
14580        return result;
14581    }
14582
14583    /**
14584     * Checks to see if the caller is in the same app as the singleton
14585     * component, or the component is in a special app. It allows special apps
14586     * to export singleton components but prevents exporting singleton
14587     * components for regular apps.
14588     */
14589    boolean isValidSingletonCall(int callingUid, int componentUid) {
14590        int componentAppId = UserHandle.getAppId(componentUid);
14591        return UserHandle.isSameApp(callingUid, componentUid)
14592                || componentAppId == Process.SYSTEM_UID
14593                || componentAppId == Process.PHONE_UID
14594                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14595                        == PackageManager.PERMISSION_GRANTED;
14596    }
14597
14598    public int bindService(IApplicationThread caller, IBinder token,
14599            Intent service, String resolvedType,
14600            IServiceConnection connection, int flags, int userId) {
14601        enforceNotIsolatedCaller("bindService");
14602        // Refuse possible leaked file descriptors
14603        if (service != null && service.hasFileDescriptors() == true) {
14604            throw new IllegalArgumentException("File descriptors passed in Intent");
14605        }
14606
14607        synchronized(this) {
14608            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14609                    connection, flags, userId);
14610        }
14611    }
14612
14613    public boolean unbindService(IServiceConnection connection) {
14614        synchronized (this) {
14615            return mServices.unbindServiceLocked(connection);
14616        }
14617    }
14618
14619    public void publishService(IBinder token, Intent intent, IBinder service) {
14620        // Refuse possible leaked file descriptors
14621        if (intent != null && intent.hasFileDescriptors() == true) {
14622            throw new IllegalArgumentException("File descriptors passed in Intent");
14623        }
14624
14625        synchronized(this) {
14626            if (!(token instanceof ServiceRecord)) {
14627                throw new IllegalArgumentException("Invalid service token");
14628            }
14629            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14630        }
14631    }
14632
14633    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14634        // Refuse possible leaked file descriptors
14635        if (intent != null && intent.hasFileDescriptors() == true) {
14636            throw new IllegalArgumentException("File descriptors passed in Intent");
14637        }
14638
14639        synchronized(this) {
14640            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14641        }
14642    }
14643
14644    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14645        synchronized(this) {
14646            if (!(token instanceof ServiceRecord)) {
14647                throw new IllegalArgumentException("Invalid service token");
14648            }
14649            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14650        }
14651    }
14652
14653    // =========================================================
14654    // BACKUP AND RESTORE
14655    // =========================================================
14656
14657    // Cause the target app to be launched if necessary and its backup agent
14658    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14659    // activity manager to announce its creation.
14660    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14661        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14662        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14663
14664        synchronized(this) {
14665            // !!! TODO: currently no check here that we're already bound
14666            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14667            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14668            synchronized (stats) {
14669                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14670            }
14671
14672            // Backup agent is now in use, its package can't be stopped.
14673            try {
14674                AppGlobals.getPackageManager().setPackageStoppedState(
14675                        app.packageName, false, UserHandle.getUserId(app.uid));
14676            } catch (RemoteException e) {
14677            } catch (IllegalArgumentException e) {
14678                Slog.w(TAG, "Failed trying to unstop package "
14679                        + app.packageName + ": " + e);
14680            }
14681
14682            BackupRecord r = new BackupRecord(ss, app, backupMode);
14683            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14684                    ? new ComponentName(app.packageName, app.backupAgentName)
14685                    : new ComponentName("android", "FullBackupAgent");
14686            // startProcessLocked() returns existing proc's record if it's already running
14687            ProcessRecord proc = startProcessLocked(app.processName, app,
14688                    false, 0, "backup", hostingName, false, false, false);
14689            if (proc == null) {
14690                Slog.e(TAG, "Unable to start backup agent process " + r);
14691                return false;
14692            }
14693
14694            r.app = proc;
14695            mBackupTarget = r;
14696            mBackupAppName = app.packageName;
14697
14698            // Try not to kill the process during backup
14699            updateOomAdjLocked(proc);
14700
14701            // If the process is already attached, schedule the creation of the backup agent now.
14702            // If it is not yet live, this will be done when it attaches to the framework.
14703            if (proc.thread != null) {
14704                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14705                try {
14706                    proc.thread.scheduleCreateBackupAgent(app,
14707                            compatibilityInfoForPackageLocked(app), backupMode);
14708                } catch (RemoteException e) {
14709                    // Will time out on the backup manager side
14710                }
14711            } else {
14712                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14713            }
14714            // Invariants: at this point, the target app process exists and the application
14715            // is either already running or in the process of coming up.  mBackupTarget and
14716            // mBackupAppName describe the app, so that when it binds back to the AM we
14717            // know that it's scheduled for a backup-agent operation.
14718        }
14719
14720        return true;
14721    }
14722
14723    @Override
14724    public void clearPendingBackup() {
14725        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14726        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14727
14728        synchronized (this) {
14729            mBackupTarget = null;
14730            mBackupAppName = null;
14731        }
14732    }
14733
14734    // A backup agent has just come up
14735    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14736        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14737                + " = " + agent);
14738
14739        synchronized(this) {
14740            if (!agentPackageName.equals(mBackupAppName)) {
14741                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14742                return;
14743            }
14744        }
14745
14746        long oldIdent = Binder.clearCallingIdentity();
14747        try {
14748            IBackupManager bm = IBackupManager.Stub.asInterface(
14749                    ServiceManager.getService(Context.BACKUP_SERVICE));
14750            bm.agentConnected(agentPackageName, agent);
14751        } catch (RemoteException e) {
14752            // can't happen; the backup manager service is local
14753        } catch (Exception e) {
14754            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14755            e.printStackTrace();
14756        } finally {
14757            Binder.restoreCallingIdentity(oldIdent);
14758        }
14759    }
14760
14761    // done with this agent
14762    public void unbindBackupAgent(ApplicationInfo appInfo) {
14763        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14764        if (appInfo == null) {
14765            Slog.w(TAG, "unbind backup agent for null app");
14766            return;
14767        }
14768
14769        synchronized(this) {
14770            try {
14771                if (mBackupAppName == null) {
14772                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14773                    return;
14774                }
14775
14776                if (!mBackupAppName.equals(appInfo.packageName)) {
14777                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14778                    return;
14779                }
14780
14781                // Not backing this app up any more; reset its OOM adjustment
14782                final ProcessRecord proc = mBackupTarget.app;
14783                updateOomAdjLocked(proc);
14784
14785                // If the app crashed during backup, 'thread' will be null here
14786                if (proc.thread != null) {
14787                    try {
14788                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14789                                compatibilityInfoForPackageLocked(appInfo));
14790                    } catch (Exception e) {
14791                        Slog.e(TAG, "Exception when unbinding backup agent:");
14792                        e.printStackTrace();
14793                    }
14794                }
14795            } finally {
14796                mBackupTarget = null;
14797                mBackupAppName = null;
14798            }
14799        }
14800    }
14801    // =========================================================
14802    // BROADCASTS
14803    // =========================================================
14804
14805    private final List getStickiesLocked(String action, IntentFilter filter,
14806            List cur, int userId) {
14807        final ContentResolver resolver = mContext.getContentResolver();
14808        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14809        if (stickies == null) {
14810            return cur;
14811        }
14812        final ArrayList<Intent> list = stickies.get(action);
14813        if (list == null) {
14814            return cur;
14815        }
14816        int N = list.size();
14817        for (int i=0; i<N; i++) {
14818            Intent intent = list.get(i);
14819            if (filter.match(resolver, intent, true, TAG) >= 0) {
14820                if (cur == null) {
14821                    cur = new ArrayList<Intent>();
14822                }
14823                cur.add(intent);
14824            }
14825        }
14826        return cur;
14827    }
14828
14829    boolean isPendingBroadcastProcessLocked(int pid) {
14830        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14831                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14832    }
14833
14834    void skipPendingBroadcastLocked(int pid) {
14835            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14836            for (BroadcastQueue queue : mBroadcastQueues) {
14837                queue.skipPendingBroadcastLocked(pid);
14838            }
14839    }
14840
14841    // The app just attached; send any pending broadcasts that it should receive
14842    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14843        boolean didSomething = false;
14844        for (BroadcastQueue queue : mBroadcastQueues) {
14845            didSomething |= queue.sendPendingBroadcastsLocked(app);
14846        }
14847        return didSomething;
14848    }
14849
14850    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14851            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14852        enforceNotIsolatedCaller("registerReceiver");
14853        int callingUid;
14854        int callingPid;
14855        synchronized(this) {
14856            ProcessRecord callerApp = null;
14857            if (caller != null) {
14858                callerApp = getRecordForAppLocked(caller);
14859                if (callerApp == null) {
14860                    throw new SecurityException(
14861                            "Unable to find app for caller " + caller
14862                            + " (pid=" + Binder.getCallingPid()
14863                            + ") when registering receiver " + receiver);
14864                }
14865                if (callerApp.info.uid != Process.SYSTEM_UID &&
14866                        !callerApp.pkgList.containsKey(callerPackage) &&
14867                        !"android".equals(callerPackage)) {
14868                    throw new SecurityException("Given caller package " + callerPackage
14869                            + " is not running in process " + callerApp);
14870                }
14871                callingUid = callerApp.info.uid;
14872                callingPid = callerApp.pid;
14873            } else {
14874                callerPackage = null;
14875                callingUid = Binder.getCallingUid();
14876                callingPid = Binder.getCallingPid();
14877            }
14878
14879            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14880                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14881
14882            List allSticky = null;
14883
14884            // Look for any matching sticky broadcasts...
14885            Iterator actions = filter.actionsIterator();
14886            if (actions != null) {
14887                while (actions.hasNext()) {
14888                    String action = (String)actions.next();
14889                    allSticky = getStickiesLocked(action, filter, allSticky,
14890                            UserHandle.USER_ALL);
14891                    allSticky = getStickiesLocked(action, filter, allSticky,
14892                            UserHandle.getUserId(callingUid));
14893                }
14894            } else {
14895                allSticky = getStickiesLocked(null, filter, allSticky,
14896                        UserHandle.USER_ALL);
14897                allSticky = getStickiesLocked(null, filter, allSticky,
14898                        UserHandle.getUserId(callingUid));
14899            }
14900
14901            // The first sticky in the list is returned directly back to
14902            // the client.
14903            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14904
14905            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14906                    + ": " + sticky);
14907
14908            if (receiver == null) {
14909                return sticky;
14910            }
14911
14912            ReceiverList rl
14913                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14914            if (rl == null) {
14915                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14916                        userId, receiver);
14917                if (rl.app != null) {
14918                    rl.app.receivers.add(rl);
14919                } else {
14920                    try {
14921                        receiver.asBinder().linkToDeath(rl, 0);
14922                    } catch (RemoteException e) {
14923                        return sticky;
14924                    }
14925                    rl.linkedToDeath = true;
14926                }
14927                mRegisteredReceivers.put(receiver.asBinder(), rl);
14928            } else if (rl.uid != callingUid) {
14929                throw new IllegalArgumentException(
14930                        "Receiver requested to register for uid " + callingUid
14931                        + " was previously registered for uid " + rl.uid);
14932            } else if (rl.pid != callingPid) {
14933                throw new IllegalArgumentException(
14934                        "Receiver requested to register for pid " + callingPid
14935                        + " was previously registered for pid " + rl.pid);
14936            } else if (rl.userId != userId) {
14937                throw new IllegalArgumentException(
14938                        "Receiver requested to register for user " + userId
14939                        + " was previously registered for user " + rl.userId);
14940            }
14941            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14942                    permission, callingUid, userId);
14943            rl.add(bf);
14944            if (!bf.debugCheck()) {
14945                Slog.w(TAG, "==> For Dynamic broadast");
14946            }
14947            mReceiverResolver.addFilter(bf);
14948
14949            // Enqueue broadcasts for all existing stickies that match
14950            // this filter.
14951            if (allSticky != null) {
14952                ArrayList receivers = new ArrayList();
14953                receivers.add(bf);
14954
14955                int N = allSticky.size();
14956                for (int i=0; i<N; i++) {
14957                    Intent intent = (Intent)allSticky.get(i);
14958                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14959                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14960                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14961                            null, null, false, true, true, -1);
14962                    queue.enqueueParallelBroadcastLocked(r);
14963                    queue.scheduleBroadcastsLocked();
14964                }
14965            }
14966
14967            return sticky;
14968        }
14969    }
14970
14971    public void unregisterReceiver(IIntentReceiver receiver) {
14972        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14973
14974        final long origId = Binder.clearCallingIdentity();
14975        try {
14976            boolean doTrim = false;
14977
14978            synchronized(this) {
14979                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14980                if (rl != null) {
14981                    if (rl.curBroadcast != null) {
14982                        BroadcastRecord r = rl.curBroadcast;
14983                        final boolean doNext = finishReceiverLocked(
14984                                receiver.asBinder(), r.resultCode, r.resultData,
14985                                r.resultExtras, r.resultAbort);
14986                        if (doNext) {
14987                            doTrim = true;
14988                            r.queue.processNextBroadcast(false);
14989                        }
14990                    }
14991
14992                    if (rl.app != null) {
14993                        rl.app.receivers.remove(rl);
14994                    }
14995                    removeReceiverLocked(rl);
14996                    if (rl.linkedToDeath) {
14997                        rl.linkedToDeath = false;
14998                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14999                    }
15000                }
15001            }
15002
15003            // If we actually concluded any broadcasts, we might now be able
15004            // to trim the recipients' apps from our working set
15005            if (doTrim) {
15006                trimApplications();
15007                return;
15008            }
15009
15010        } finally {
15011            Binder.restoreCallingIdentity(origId);
15012        }
15013    }
15014
15015    void removeReceiverLocked(ReceiverList rl) {
15016        mRegisteredReceivers.remove(rl.receiver.asBinder());
15017        int N = rl.size();
15018        for (int i=0; i<N; i++) {
15019            mReceiverResolver.removeFilter(rl.get(i));
15020        }
15021    }
15022
15023    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15024        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15025            ProcessRecord r = mLruProcesses.get(i);
15026            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15027                try {
15028                    r.thread.dispatchPackageBroadcast(cmd, packages);
15029                } catch (RemoteException ex) {
15030                }
15031            }
15032        }
15033    }
15034
15035    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15036            int[] users) {
15037        List<ResolveInfo> receivers = null;
15038        try {
15039            HashSet<ComponentName> singleUserReceivers = null;
15040            boolean scannedFirstReceivers = false;
15041            for (int user : users) {
15042                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15043                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15044                if (user != 0 && newReceivers != null) {
15045                    // If this is not the primary user, we need to check for
15046                    // any receivers that should be filtered out.
15047                    for (int i=0; i<newReceivers.size(); i++) {
15048                        ResolveInfo ri = newReceivers.get(i);
15049                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15050                            newReceivers.remove(i);
15051                            i--;
15052                        }
15053                    }
15054                }
15055                if (newReceivers != null && newReceivers.size() == 0) {
15056                    newReceivers = null;
15057                }
15058                if (receivers == null) {
15059                    receivers = newReceivers;
15060                } else if (newReceivers != null) {
15061                    // We need to concatenate the additional receivers
15062                    // found with what we have do far.  This would be easy,
15063                    // but we also need to de-dup any receivers that are
15064                    // singleUser.
15065                    if (!scannedFirstReceivers) {
15066                        // Collect any single user receivers we had already retrieved.
15067                        scannedFirstReceivers = true;
15068                        for (int i=0; i<receivers.size(); i++) {
15069                            ResolveInfo ri = receivers.get(i);
15070                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15071                                ComponentName cn = new ComponentName(
15072                                        ri.activityInfo.packageName, ri.activityInfo.name);
15073                                if (singleUserReceivers == null) {
15074                                    singleUserReceivers = new HashSet<ComponentName>();
15075                                }
15076                                singleUserReceivers.add(cn);
15077                            }
15078                        }
15079                    }
15080                    // Add the new results to the existing results, tracking
15081                    // and de-dupping single user receivers.
15082                    for (int i=0; i<newReceivers.size(); i++) {
15083                        ResolveInfo ri = newReceivers.get(i);
15084                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15085                            ComponentName cn = new ComponentName(
15086                                    ri.activityInfo.packageName, ri.activityInfo.name);
15087                            if (singleUserReceivers == null) {
15088                                singleUserReceivers = new HashSet<ComponentName>();
15089                            }
15090                            if (!singleUserReceivers.contains(cn)) {
15091                                singleUserReceivers.add(cn);
15092                                receivers.add(ri);
15093                            }
15094                        } else {
15095                            receivers.add(ri);
15096                        }
15097                    }
15098                }
15099            }
15100        } catch (RemoteException ex) {
15101            // pm is in same process, this will never happen.
15102        }
15103        return receivers;
15104    }
15105
15106    private final int broadcastIntentLocked(ProcessRecord callerApp,
15107            String callerPackage, Intent intent, String resolvedType,
15108            IIntentReceiver resultTo, int resultCode, String resultData,
15109            Bundle map, String requiredPermission, int appOp,
15110            boolean ordered, boolean sticky, int callingPid, int callingUid,
15111            int userId) {
15112        intent = new Intent(intent);
15113
15114        // By default broadcasts do not go to stopped apps.
15115        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15116
15117        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15118            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15119            + " ordered=" + ordered + " userid=" + userId);
15120        if ((resultTo != null) && !ordered) {
15121            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15122        }
15123
15124        userId = handleIncomingUser(callingPid, callingUid, userId,
15125                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15126
15127        // Make sure that the user who is receiving this broadcast is started.
15128        // If not, we will just skip it.
15129
15130
15131        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15132            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15133                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15134                Slog.w(TAG, "Skipping broadcast of " + intent
15135                        + ": user " + userId + " is stopped");
15136                return ActivityManager.BROADCAST_SUCCESS;
15137            }
15138        }
15139
15140        /*
15141         * Prevent non-system code (defined here to be non-persistent
15142         * processes) from sending protected broadcasts.
15143         */
15144        int callingAppId = UserHandle.getAppId(callingUid);
15145        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15146            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15147            || callingAppId == Process.NFC_UID || callingUid == 0) {
15148            // Always okay.
15149        } else if (callerApp == null || !callerApp.persistent) {
15150            try {
15151                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15152                        intent.getAction())) {
15153                    String msg = "Permission Denial: not allowed to send broadcast "
15154                            + intent.getAction() + " from pid="
15155                            + callingPid + ", uid=" + callingUid;
15156                    Slog.w(TAG, msg);
15157                    throw new SecurityException(msg);
15158                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15159                    // Special case for compatibility: we don't want apps to send this,
15160                    // but historically it has not been protected and apps may be using it
15161                    // to poke their own app widget.  So, instead of making it protected,
15162                    // just limit it to the caller.
15163                    if (callerApp == null) {
15164                        String msg = "Permission Denial: not allowed to send broadcast "
15165                                + intent.getAction() + " from unknown caller.";
15166                        Slog.w(TAG, msg);
15167                        throw new SecurityException(msg);
15168                    } else if (intent.getComponent() != null) {
15169                        // They are good enough to send to an explicit component...  verify
15170                        // it is being sent to the calling app.
15171                        if (!intent.getComponent().getPackageName().equals(
15172                                callerApp.info.packageName)) {
15173                            String msg = "Permission Denial: not allowed to send broadcast "
15174                                    + intent.getAction() + " to "
15175                                    + intent.getComponent().getPackageName() + " from "
15176                                    + callerApp.info.packageName;
15177                            Slog.w(TAG, msg);
15178                            throw new SecurityException(msg);
15179                        }
15180                    } else {
15181                        // Limit broadcast to their own package.
15182                        intent.setPackage(callerApp.info.packageName);
15183                    }
15184                }
15185            } catch (RemoteException e) {
15186                Slog.w(TAG, "Remote exception", e);
15187                return ActivityManager.BROADCAST_SUCCESS;
15188            }
15189        }
15190
15191        // Handle special intents: if this broadcast is from the package
15192        // manager about a package being removed, we need to remove all of
15193        // its activities from the history stack.
15194        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15195                intent.getAction());
15196        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15197                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15198                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15199                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15200                || uidRemoved) {
15201            if (checkComponentPermission(
15202                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15203                    callingPid, callingUid, -1, true)
15204                    == PackageManager.PERMISSION_GRANTED) {
15205                if (uidRemoved) {
15206                    final Bundle intentExtras = intent.getExtras();
15207                    final int uid = intentExtras != null
15208                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15209                    if (uid >= 0) {
15210                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15211                        synchronized (bs) {
15212                            bs.removeUidStatsLocked(uid);
15213                        }
15214                        mAppOpsService.uidRemoved(uid);
15215                    }
15216                } else {
15217                    // If resources are unavailable just force stop all
15218                    // those packages and flush the attribute cache as well.
15219                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15220                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15221                        if (list != null && (list.length > 0)) {
15222                            for (String pkg : list) {
15223                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15224                                        "storage unmount");
15225                            }
15226                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15227                            sendPackageBroadcastLocked(
15228                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15229                        }
15230                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15231                            intent.getAction())) {
15232                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15233                    } else {
15234                        Uri data = intent.getData();
15235                        String ssp;
15236                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15237                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15238                                    intent.getAction());
15239                            boolean fullUninstall = removed &&
15240                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15241                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15242                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15243                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15244                                        false, fullUninstall, userId,
15245                                        removed ? "pkg removed" : "pkg changed");
15246                            }
15247                            if (removed) {
15248                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15249                                        new String[] {ssp}, userId);
15250                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15251                                    mAppOpsService.packageRemoved(
15252                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15253
15254                                    // Remove all permissions granted from/to this package
15255                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15256                                }
15257                            }
15258                        }
15259                    }
15260                }
15261            } else {
15262                String msg = "Permission Denial: " + intent.getAction()
15263                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15264                        + ", uid=" + callingUid + ")"
15265                        + " requires "
15266                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15267                Slog.w(TAG, msg);
15268                throw new SecurityException(msg);
15269            }
15270
15271        // Special case for adding a package: by default turn on compatibility
15272        // mode.
15273        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15274            Uri data = intent.getData();
15275            String ssp;
15276            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15277                mCompatModePackages.handlePackageAddedLocked(ssp,
15278                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15279            }
15280        }
15281
15282        /*
15283         * If this is the time zone changed action, queue up a message that will reset the timezone
15284         * of all currently running processes. This message will get queued up before the broadcast
15285         * happens.
15286         */
15287        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15288            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15289        }
15290
15291        /*
15292         * If the user set the time, let all running processes know.
15293         */
15294        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15295            final int is24Hour = intent.getBooleanExtra(
15296                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15297            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15298            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15299            synchronized (stats) {
15300                stats.noteCurrentTimeChangedLocked();
15301            }
15302        }
15303
15304        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15305            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15306        }
15307
15308        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15309            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15310            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15311        }
15312
15313        // Add to the sticky list if requested.
15314        if (sticky) {
15315            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15316                    callingPid, callingUid)
15317                    != PackageManager.PERMISSION_GRANTED) {
15318                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15319                        + callingPid + ", uid=" + callingUid
15320                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15321                Slog.w(TAG, msg);
15322                throw new SecurityException(msg);
15323            }
15324            if (requiredPermission != null) {
15325                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15326                        + " and enforce permission " + requiredPermission);
15327                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15328            }
15329            if (intent.getComponent() != null) {
15330                throw new SecurityException(
15331                        "Sticky broadcasts can't target a specific component");
15332            }
15333            // We use userId directly here, since the "all" target is maintained
15334            // as a separate set of sticky broadcasts.
15335            if (userId != UserHandle.USER_ALL) {
15336                // But first, if this is not a broadcast to all users, then
15337                // make sure it doesn't conflict with an existing broadcast to
15338                // all users.
15339                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15340                        UserHandle.USER_ALL);
15341                if (stickies != null) {
15342                    ArrayList<Intent> list = stickies.get(intent.getAction());
15343                    if (list != null) {
15344                        int N = list.size();
15345                        int i;
15346                        for (i=0; i<N; i++) {
15347                            if (intent.filterEquals(list.get(i))) {
15348                                throw new IllegalArgumentException(
15349                                        "Sticky broadcast " + intent + " for user "
15350                                        + userId + " conflicts with existing global broadcast");
15351                            }
15352                        }
15353                    }
15354                }
15355            }
15356            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15357            if (stickies == null) {
15358                stickies = new ArrayMap<String, ArrayList<Intent>>();
15359                mStickyBroadcasts.put(userId, stickies);
15360            }
15361            ArrayList<Intent> list = stickies.get(intent.getAction());
15362            if (list == null) {
15363                list = new ArrayList<Intent>();
15364                stickies.put(intent.getAction(), list);
15365            }
15366            int N = list.size();
15367            int i;
15368            for (i=0; i<N; i++) {
15369                if (intent.filterEquals(list.get(i))) {
15370                    // This sticky already exists, replace it.
15371                    list.set(i, new Intent(intent));
15372                    break;
15373                }
15374            }
15375            if (i >= N) {
15376                list.add(new Intent(intent));
15377            }
15378        }
15379
15380        int[] users;
15381        if (userId == UserHandle.USER_ALL) {
15382            // Caller wants broadcast to go to all started users.
15383            users = mStartedUserArray;
15384        } else {
15385            // Caller wants broadcast to go to one specific user.
15386            users = new int[] {userId};
15387        }
15388
15389        // Figure out who all will receive this broadcast.
15390        List receivers = null;
15391        List<BroadcastFilter> registeredReceivers = null;
15392        // Need to resolve the intent to interested receivers...
15393        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15394                 == 0) {
15395            receivers = collectReceiverComponents(intent, resolvedType, users);
15396        }
15397        if (intent.getComponent() == null) {
15398            registeredReceivers = mReceiverResolver.queryIntent(intent,
15399                    resolvedType, false, userId);
15400        }
15401
15402        final boolean replacePending =
15403                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15404
15405        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15406                + " replacePending=" + replacePending);
15407
15408        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15409        if (!ordered && NR > 0) {
15410            // If we are not serializing this broadcast, then send the
15411            // registered receivers separately so they don't wait for the
15412            // components to be launched.
15413            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15414            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15415                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15416                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15417                    ordered, sticky, false, userId);
15418            if (DEBUG_BROADCAST) Slog.v(
15419                    TAG, "Enqueueing parallel broadcast " + r);
15420            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15421            if (!replaced) {
15422                queue.enqueueParallelBroadcastLocked(r);
15423                queue.scheduleBroadcastsLocked();
15424            }
15425            registeredReceivers = null;
15426            NR = 0;
15427        }
15428
15429        // Merge into one list.
15430        int ir = 0;
15431        if (receivers != null) {
15432            // A special case for PACKAGE_ADDED: do not allow the package
15433            // being added to see this broadcast.  This prevents them from
15434            // using this as a back door to get run as soon as they are
15435            // installed.  Maybe in the future we want to have a special install
15436            // broadcast or such for apps, but we'd like to deliberately make
15437            // this decision.
15438            String skipPackages[] = null;
15439            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15440                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15441                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15442                Uri data = intent.getData();
15443                if (data != null) {
15444                    String pkgName = data.getSchemeSpecificPart();
15445                    if (pkgName != null) {
15446                        skipPackages = new String[] { pkgName };
15447                    }
15448                }
15449            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15450                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15451            }
15452            if (skipPackages != null && (skipPackages.length > 0)) {
15453                for (String skipPackage : skipPackages) {
15454                    if (skipPackage != null) {
15455                        int NT = receivers.size();
15456                        for (int it=0; it<NT; it++) {
15457                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15458                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15459                                receivers.remove(it);
15460                                it--;
15461                                NT--;
15462                            }
15463                        }
15464                    }
15465                }
15466            }
15467
15468            int NT = receivers != null ? receivers.size() : 0;
15469            int it = 0;
15470            ResolveInfo curt = null;
15471            BroadcastFilter curr = null;
15472            while (it < NT && ir < NR) {
15473                if (curt == null) {
15474                    curt = (ResolveInfo)receivers.get(it);
15475                }
15476                if (curr == null) {
15477                    curr = registeredReceivers.get(ir);
15478                }
15479                if (curr.getPriority() >= curt.priority) {
15480                    // Insert this broadcast record into the final list.
15481                    receivers.add(it, curr);
15482                    ir++;
15483                    curr = null;
15484                    it++;
15485                    NT++;
15486                } else {
15487                    // Skip to the next ResolveInfo in the final list.
15488                    it++;
15489                    curt = null;
15490                }
15491            }
15492        }
15493        while (ir < NR) {
15494            if (receivers == null) {
15495                receivers = new ArrayList();
15496            }
15497            receivers.add(registeredReceivers.get(ir));
15498            ir++;
15499        }
15500
15501        if ((receivers != null && receivers.size() > 0)
15502                || resultTo != null) {
15503            BroadcastQueue queue = broadcastQueueForIntent(intent);
15504            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15505                    callerPackage, callingPid, callingUid, resolvedType,
15506                    requiredPermission, appOp, receivers, resultTo, resultCode,
15507                    resultData, map, ordered, sticky, false, userId);
15508            if (DEBUG_BROADCAST) Slog.v(
15509                    TAG, "Enqueueing ordered broadcast " + r
15510                    + ": prev had " + queue.mOrderedBroadcasts.size());
15511            if (DEBUG_BROADCAST) {
15512                int seq = r.intent.getIntExtra("seq", -1);
15513                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15514            }
15515            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15516            if (!replaced) {
15517                queue.enqueueOrderedBroadcastLocked(r);
15518                queue.scheduleBroadcastsLocked();
15519            }
15520        }
15521
15522        return ActivityManager.BROADCAST_SUCCESS;
15523    }
15524
15525    final Intent verifyBroadcastLocked(Intent intent) {
15526        // Refuse possible leaked file descriptors
15527        if (intent != null && intent.hasFileDescriptors() == true) {
15528            throw new IllegalArgumentException("File descriptors passed in Intent");
15529        }
15530
15531        int flags = intent.getFlags();
15532
15533        if (!mProcessesReady) {
15534            // if the caller really truly claims to know what they're doing, go
15535            // ahead and allow the broadcast without launching any receivers
15536            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15537                intent = new Intent(intent);
15538                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15539            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15540                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15541                        + " before boot completion");
15542                throw new IllegalStateException("Cannot broadcast before boot completed");
15543            }
15544        }
15545
15546        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15547            throw new IllegalArgumentException(
15548                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15549        }
15550
15551        return intent;
15552    }
15553
15554    public final int broadcastIntent(IApplicationThread caller,
15555            Intent intent, String resolvedType, IIntentReceiver resultTo,
15556            int resultCode, String resultData, Bundle map,
15557            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15558        enforceNotIsolatedCaller("broadcastIntent");
15559        synchronized(this) {
15560            intent = verifyBroadcastLocked(intent);
15561
15562            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15563            final int callingPid = Binder.getCallingPid();
15564            final int callingUid = Binder.getCallingUid();
15565            final long origId = Binder.clearCallingIdentity();
15566            int res = broadcastIntentLocked(callerApp,
15567                    callerApp != null ? callerApp.info.packageName : null,
15568                    intent, resolvedType, resultTo,
15569                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15570                    callingPid, callingUid, userId);
15571            Binder.restoreCallingIdentity(origId);
15572            return res;
15573        }
15574    }
15575
15576    int broadcastIntentInPackage(String packageName, int uid,
15577            Intent intent, String resolvedType, IIntentReceiver resultTo,
15578            int resultCode, String resultData, Bundle map,
15579            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15580        synchronized(this) {
15581            intent = verifyBroadcastLocked(intent);
15582
15583            final long origId = Binder.clearCallingIdentity();
15584            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15585                    resultTo, resultCode, resultData, map, requiredPermission,
15586                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15587            Binder.restoreCallingIdentity(origId);
15588            return res;
15589        }
15590    }
15591
15592    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15593        // Refuse possible leaked file descriptors
15594        if (intent != null && intent.hasFileDescriptors() == true) {
15595            throw new IllegalArgumentException("File descriptors passed in Intent");
15596        }
15597
15598        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15599                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15600
15601        synchronized(this) {
15602            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15603                    != PackageManager.PERMISSION_GRANTED) {
15604                String msg = "Permission Denial: unbroadcastIntent() from pid="
15605                        + Binder.getCallingPid()
15606                        + ", uid=" + Binder.getCallingUid()
15607                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15608                Slog.w(TAG, msg);
15609                throw new SecurityException(msg);
15610            }
15611            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15612            if (stickies != null) {
15613                ArrayList<Intent> list = stickies.get(intent.getAction());
15614                if (list != null) {
15615                    int N = list.size();
15616                    int i;
15617                    for (i=0; i<N; i++) {
15618                        if (intent.filterEquals(list.get(i))) {
15619                            list.remove(i);
15620                            break;
15621                        }
15622                    }
15623                    if (list.size() <= 0) {
15624                        stickies.remove(intent.getAction());
15625                    }
15626                }
15627                if (stickies.size() <= 0) {
15628                    mStickyBroadcasts.remove(userId);
15629                }
15630            }
15631        }
15632    }
15633
15634    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15635            String resultData, Bundle resultExtras, boolean resultAbort) {
15636        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15637        if (r == null) {
15638            Slog.w(TAG, "finishReceiver called but not found on queue");
15639            return false;
15640        }
15641
15642        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15643    }
15644
15645    void backgroundServicesFinishedLocked(int userId) {
15646        for (BroadcastQueue queue : mBroadcastQueues) {
15647            queue.backgroundServicesFinishedLocked(userId);
15648        }
15649    }
15650
15651    public void finishReceiver(IBinder who, int resultCode, String resultData,
15652            Bundle resultExtras, boolean resultAbort) {
15653        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15654
15655        // Refuse possible leaked file descriptors
15656        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15657            throw new IllegalArgumentException("File descriptors passed in Bundle");
15658        }
15659
15660        final long origId = Binder.clearCallingIdentity();
15661        try {
15662            boolean doNext = false;
15663            BroadcastRecord r;
15664
15665            synchronized(this) {
15666                r = broadcastRecordForReceiverLocked(who);
15667                if (r != null) {
15668                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15669                        resultData, resultExtras, resultAbort, true);
15670                }
15671            }
15672
15673            if (doNext) {
15674                r.queue.processNextBroadcast(false);
15675            }
15676            trimApplications();
15677        } finally {
15678            Binder.restoreCallingIdentity(origId);
15679        }
15680    }
15681
15682    // =========================================================
15683    // INSTRUMENTATION
15684    // =========================================================
15685
15686    public boolean startInstrumentation(ComponentName className,
15687            String profileFile, int flags, Bundle arguments,
15688            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15689            int userId, String abiOverride) {
15690        enforceNotIsolatedCaller("startInstrumentation");
15691        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15692                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15693        // Refuse possible leaked file descriptors
15694        if (arguments != null && arguments.hasFileDescriptors()) {
15695            throw new IllegalArgumentException("File descriptors passed in Bundle");
15696        }
15697
15698        synchronized(this) {
15699            InstrumentationInfo ii = null;
15700            ApplicationInfo ai = null;
15701            try {
15702                ii = mContext.getPackageManager().getInstrumentationInfo(
15703                    className, STOCK_PM_FLAGS);
15704                ai = AppGlobals.getPackageManager().getApplicationInfo(
15705                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15706            } catch (PackageManager.NameNotFoundException e) {
15707            } catch (RemoteException e) {
15708            }
15709            if (ii == null) {
15710                reportStartInstrumentationFailure(watcher, className,
15711                        "Unable to find instrumentation info for: " + className);
15712                return false;
15713            }
15714            if (ai == null) {
15715                reportStartInstrumentationFailure(watcher, className,
15716                        "Unable to find instrumentation target package: " + ii.targetPackage);
15717                return false;
15718            }
15719
15720            int match = mContext.getPackageManager().checkSignatures(
15721                    ii.targetPackage, ii.packageName);
15722            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15723                String msg = "Permission Denial: starting instrumentation "
15724                        + className + " from pid="
15725                        + Binder.getCallingPid()
15726                        + ", uid=" + Binder.getCallingPid()
15727                        + " not allowed because package " + ii.packageName
15728                        + " does not have a signature matching the target "
15729                        + ii.targetPackage;
15730                reportStartInstrumentationFailure(watcher, className, msg);
15731                throw new SecurityException(msg);
15732            }
15733
15734            final long origId = Binder.clearCallingIdentity();
15735            // Instrumentation can kill and relaunch even persistent processes
15736            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15737                    "start instr");
15738            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15739            app.instrumentationClass = className;
15740            app.instrumentationInfo = ai;
15741            app.instrumentationProfileFile = profileFile;
15742            app.instrumentationArguments = arguments;
15743            app.instrumentationWatcher = watcher;
15744            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15745            app.instrumentationResultClass = className;
15746            Binder.restoreCallingIdentity(origId);
15747        }
15748
15749        return true;
15750    }
15751
15752    /**
15753     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15754     * error to the logs, but if somebody is watching, send the report there too.  This enables
15755     * the "am" command to report errors with more information.
15756     *
15757     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15758     * @param cn The component name of the instrumentation.
15759     * @param report The error report.
15760     */
15761    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15762            ComponentName cn, String report) {
15763        Slog.w(TAG, report);
15764        try {
15765            if (watcher != null) {
15766                Bundle results = new Bundle();
15767                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15768                results.putString("Error", report);
15769                watcher.instrumentationStatus(cn, -1, results);
15770            }
15771        } catch (RemoteException e) {
15772            Slog.w(TAG, e);
15773        }
15774    }
15775
15776    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15777        if (app.instrumentationWatcher != null) {
15778            try {
15779                // NOTE:  IInstrumentationWatcher *must* be oneway here
15780                app.instrumentationWatcher.instrumentationFinished(
15781                    app.instrumentationClass,
15782                    resultCode,
15783                    results);
15784            } catch (RemoteException e) {
15785            }
15786        }
15787        if (app.instrumentationUiAutomationConnection != null) {
15788            try {
15789                app.instrumentationUiAutomationConnection.shutdown();
15790            } catch (RemoteException re) {
15791                /* ignore */
15792            }
15793            // Only a UiAutomation can set this flag and now that
15794            // it is finished we make sure it is reset to its default.
15795            mUserIsMonkey = false;
15796        }
15797        app.instrumentationWatcher = null;
15798        app.instrumentationUiAutomationConnection = null;
15799        app.instrumentationClass = null;
15800        app.instrumentationInfo = null;
15801        app.instrumentationProfileFile = null;
15802        app.instrumentationArguments = null;
15803
15804        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15805                "finished inst");
15806    }
15807
15808    public void finishInstrumentation(IApplicationThread target,
15809            int resultCode, Bundle results) {
15810        int userId = UserHandle.getCallingUserId();
15811        // Refuse possible leaked file descriptors
15812        if (results != null && results.hasFileDescriptors()) {
15813            throw new IllegalArgumentException("File descriptors passed in Intent");
15814        }
15815
15816        synchronized(this) {
15817            ProcessRecord app = getRecordForAppLocked(target);
15818            if (app == null) {
15819                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15820                return;
15821            }
15822            final long origId = Binder.clearCallingIdentity();
15823            finishInstrumentationLocked(app, resultCode, results);
15824            Binder.restoreCallingIdentity(origId);
15825        }
15826    }
15827
15828    // =========================================================
15829    // CONFIGURATION
15830    // =========================================================
15831
15832    public ConfigurationInfo getDeviceConfigurationInfo() {
15833        ConfigurationInfo config = new ConfigurationInfo();
15834        synchronized (this) {
15835            config.reqTouchScreen = mConfiguration.touchscreen;
15836            config.reqKeyboardType = mConfiguration.keyboard;
15837            config.reqNavigation = mConfiguration.navigation;
15838            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15839                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15840                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15841            }
15842            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15843                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15844                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15845            }
15846            config.reqGlEsVersion = GL_ES_VERSION;
15847        }
15848        return config;
15849    }
15850
15851    ActivityStack getFocusedStack() {
15852        return mStackSupervisor.getFocusedStack();
15853    }
15854
15855    public Configuration getConfiguration() {
15856        Configuration ci;
15857        synchronized(this) {
15858            ci = new Configuration(mConfiguration);
15859        }
15860        return ci;
15861    }
15862
15863    public void updatePersistentConfiguration(Configuration values) {
15864        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15865                "updateConfiguration()");
15866        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15867                "updateConfiguration()");
15868        if (values == null) {
15869            throw new NullPointerException("Configuration must not be null");
15870        }
15871
15872        synchronized(this) {
15873            final long origId = Binder.clearCallingIdentity();
15874            updateConfigurationLocked(values, null, true, false);
15875            Binder.restoreCallingIdentity(origId);
15876        }
15877    }
15878
15879    public void updateConfiguration(Configuration values) {
15880        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15881                "updateConfiguration()");
15882
15883        synchronized(this) {
15884            if (values == null && mWindowManager != null) {
15885                // sentinel: fetch the current configuration from the window manager
15886                values = mWindowManager.computeNewConfiguration();
15887            }
15888
15889            if (mWindowManager != null) {
15890                mProcessList.applyDisplaySize(mWindowManager);
15891            }
15892
15893            final long origId = Binder.clearCallingIdentity();
15894            if (values != null) {
15895                Settings.System.clearConfiguration(values);
15896            }
15897            updateConfigurationLocked(values, null, false, false);
15898            Binder.restoreCallingIdentity(origId);
15899        }
15900    }
15901
15902    /**
15903     * Do either or both things: (1) change the current configuration, and (2)
15904     * make sure the given activity is running with the (now) current
15905     * configuration.  Returns true if the activity has been left running, or
15906     * false if <var>starting</var> is being destroyed to match the new
15907     * configuration.
15908     * @param persistent TODO
15909     */
15910    boolean updateConfigurationLocked(Configuration values,
15911            ActivityRecord starting, boolean persistent, boolean initLocale) {
15912        int changes = 0;
15913
15914        if (values != null) {
15915            Configuration newConfig = new Configuration(mConfiguration);
15916            changes = newConfig.updateFrom(values);
15917            if (changes != 0) {
15918                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15919                    Slog.i(TAG, "Updating configuration to: " + values);
15920                }
15921
15922                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15923
15924                if (values.locale != null && !initLocale) {
15925                    saveLocaleLocked(values.locale,
15926                                     !values.locale.equals(mConfiguration.locale),
15927                                     values.userSetLocale);
15928                }
15929
15930                mConfigurationSeq++;
15931                if (mConfigurationSeq <= 0) {
15932                    mConfigurationSeq = 1;
15933                }
15934                newConfig.seq = mConfigurationSeq;
15935                mConfiguration = newConfig;
15936                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15937                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
15938                //mUsageStatsService.noteStartConfig(newConfig);
15939
15940                final Configuration configCopy = new Configuration(mConfiguration);
15941
15942                // TODO: If our config changes, should we auto dismiss any currently
15943                // showing dialogs?
15944                mShowDialogs = shouldShowDialogs(newConfig);
15945
15946                AttributeCache ac = AttributeCache.instance();
15947                if (ac != null) {
15948                    ac.updateConfiguration(configCopy);
15949                }
15950
15951                // Make sure all resources in our process are updated
15952                // right now, so that anyone who is going to retrieve
15953                // resource values after we return will be sure to get
15954                // the new ones.  This is especially important during
15955                // boot, where the first config change needs to guarantee
15956                // all resources have that config before following boot
15957                // code is executed.
15958                mSystemThread.applyConfigurationToResources(configCopy);
15959
15960                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15961                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15962                    msg.obj = new Configuration(configCopy);
15963                    mHandler.sendMessage(msg);
15964                }
15965
15966                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15967                    ProcessRecord app = mLruProcesses.get(i);
15968                    try {
15969                        if (app.thread != null) {
15970                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15971                                    + app.processName + " new config " + mConfiguration);
15972                            app.thread.scheduleConfigurationChanged(configCopy);
15973                        }
15974                    } catch (Exception e) {
15975                    }
15976                }
15977                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15978                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15979                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15980                        | Intent.FLAG_RECEIVER_FOREGROUND);
15981                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15982                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15983                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15984                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15985                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15986                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15987                    broadcastIntentLocked(null, null, intent,
15988                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15989                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15990                }
15991            }
15992        }
15993
15994        boolean kept = true;
15995        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15996        // mainStack is null during startup.
15997        if (mainStack != null) {
15998            if (changes != 0 && starting == null) {
15999                // If the configuration changed, and the caller is not already
16000                // in the process of starting an activity, then find the top
16001                // activity to check if its configuration needs to change.
16002                starting = mainStack.topRunningActivityLocked(null);
16003            }
16004
16005            if (starting != null) {
16006                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16007                // And we need to make sure at this point that all other activities
16008                // are made visible with the correct configuration.
16009                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16010            }
16011        }
16012
16013        if (values != null && mWindowManager != null) {
16014            mWindowManager.setNewConfiguration(mConfiguration);
16015        }
16016
16017        return kept;
16018    }
16019
16020    /**
16021     * Decide based on the configuration whether we should shouw the ANR,
16022     * crash, etc dialogs.  The idea is that if there is no affordnace to
16023     * press the on-screen buttons, we shouldn't show the dialog.
16024     *
16025     * A thought: SystemUI might also want to get told about this, the Power
16026     * dialog / global actions also might want different behaviors.
16027     */
16028    private static final boolean shouldShowDialogs(Configuration config) {
16029        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16030                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16031    }
16032
16033    /**
16034     * Save the locale.  You must be inside a synchronized (this) block.
16035     */
16036    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16037        if(isDiff) {
16038            SystemProperties.set("user.language", l.getLanguage());
16039            SystemProperties.set("user.region", l.getCountry());
16040        }
16041
16042        if(isPersist) {
16043            SystemProperties.set("persist.sys.language", l.getLanguage());
16044            SystemProperties.set("persist.sys.country", l.getCountry());
16045            SystemProperties.set("persist.sys.localevar", l.getVariant());
16046        }
16047    }
16048
16049    @Override
16050    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16051        synchronized (this) {
16052            ActivityRecord srec = ActivityRecord.forToken(token);
16053            if (srec.task != null && srec.task.stack != null) {
16054                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16055            }
16056        }
16057        return false;
16058    }
16059
16060    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16061            Intent resultData) {
16062
16063        synchronized (this) {
16064            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16065            if (stack != null) {
16066                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16067            }
16068            return false;
16069        }
16070    }
16071
16072    public int getLaunchedFromUid(IBinder activityToken) {
16073        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16074        if (srec == null) {
16075            return -1;
16076        }
16077        return srec.launchedFromUid;
16078    }
16079
16080    public String getLaunchedFromPackage(IBinder activityToken) {
16081        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16082        if (srec == null) {
16083            return null;
16084        }
16085        return srec.launchedFromPackage;
16086    }
16087
16088    // =========================================================
16089    // LIFETIME MANAGEMENT
16090    // =========================================================
16091
16092    // Returns which broadcast queue the app is the current [or imminent] receiver
16093    // on, or 'null' if the app is not an active broadcast recipient.
16094    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16095        BroadcastRecord r = app.curReceiver;
16096        if (r != null) {
16097            return r.queue;
16098        }
16099
16100        // It's not the current receiver, but it might be starting up to become one
16101        synchronized (this) {
16102            for (BroadcastQueue queue : mBroadcastQueues) {
16103                r = queue.mPendingBroadcast;
16104                if (r != null && r.curApp == app) {
16105                    // found it; report which queue it's in
16106                    return queue;
16107                }
16108            }
16109        }
16110
16111        return null;
16112    }
16113
16114    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16115            boolean doingAll, long now) {
16116        if (mAdjSeq == app.adjSeq) {
16117            // This adjustment has already been computed.
16118            return app.curRawAdj;
16119        }
16120
16121        if (app.thread == null) {
16122            app.adjSeq = mAdjSeq;
16123            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16124            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16125            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16126        }
16127
16128        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16129        app.adjSource = null;
16130        app.adjTarget = null;
16131        app.empty = false;
16132        app.cached = false;
16133
16134        final int activitiesSize = app.activities.size();
16135
16136        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16137            // The max adjustment doesn't allow this app to be anything
16138            // below foreground, so it is not worth doing work for it.
16139            app.adjType = "fixed";
16140            app.adjSeq = mAdjSeq;
16141            app.curRawAdj = app.maxAdj;
16142            app.foregroundActivities = false;
16143            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16144            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16145            // System processes can do UI, and when they do we want to have
16146            // them trim their memory after the user leaves the UI.  To
16147            // facilitate this, here we need to determine whether or not it
16148            // is currently showing UI.
16149            app.systemNoUi = true;
16150            if (app == TOP_APP) {
16151                app.systemNoUi = false;
16152            } else if (activitiesSize > 0) {
16153                for (int j = 0; j < activitiesSize; j++) {
16154                    final ActivityRecord r = app.activities.get(j);
16155                    if (r.visible) {
16156                        app.systemNoUi = false;
16157                    }
16158                }
16159            }
16160            if (!app.systemNoUi) {
16161                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16162            }
16163            return (app.curAdj=app.maxAdj);
16164        }
16165
16166        app.systemNoUi = false;
16167
16168        // Determine the importance of the process, starting with most
16169        // important to least, and assign an appropriate OOM adjustment.
16170        int adj;
16171        int schedGroup;
16172        int procState;
16173        boolean foregroundActivities = false;
16174        BroadcastQueue queue;
16175        if (app == TOP_APP) {
16176            // The last app on the list is the foreground app.
16177            adj = ProcessList.FOREGROUND_APP_ADJ;
16178            schedGroup = Process.THREAD_GROUP_DEFAULT;
16179            app.adjType = "top-activity";
16180            foregroundActivities = true;
16181            procState = ActivityManager.PROCESS_STATE_TOP;
16182        } else if (app.instrumentationClass != null) {
16183            // Don't want to kill running instrumentation.
16184            adj = ProcessList.FOREGROUND_APP_ADJ;
16185            schedGroup = Process.THREAD_GROUP_DEFAULT;
16186            app.adjType = "instrumentation";
16187            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16188        } else if ((queue = isReceivingBroadcast(app)) != null) {
16189            // An app that is currently receiving a broadcast also
16190            // counts as being in the foreground for OOM killer purposes.
16191            // It's placed in a sched group based on the nature of the
16192            // broadcast as reflected by which queue it's active in.
16193            adj = ProcessList.FOREGROUND_APP_ADJ;
16194            schedGroup = (queue == mFgBroadcastQueue)
16195                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16196            app.adjType = "broadcast";
16197            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16198        } else if (app.executingServices.size() > 0) {
16199            // An app that is currently executing a service callback also
16200            // counts as being in the foreground.
16201            adj = ProcessList.FOREGROUND_APP_ADJ;
16202            schedGroup = app.execServicesFg ?
16203                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16204            app.adjType = "exec-service";
16205            procState = ActivityManager.PROCESS_STATE_SERVICE;
16206            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16207        } else {
16208            // As far as we know the process is empty.  We may change our mind later.
16209            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16210            // At this point we don't actually know the adjustment.  Use the cached adj
16211            // value that the caller wants us to.
16212            adj = cachedAdj;
16213            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16214            app.cached = true;
16215            app.empty = true;
16216            app.adjType = "cch-empty";
16217        }
16218
16219        // Examine all activities if not already foreground.
16220        if (!foregroundActivities && activitiesSize > 0) {
16221            for (int j = 0; j < activitiesSize; j++) {
16222                final ActivityRecord r = app.activities.get(j);
16223                if (r.app != app) {
16224                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16225                            + app + "?!?");
16226                    continue;
16227                }
16228                if (r.visible) {
16229                    // App has a visible activity; only upgrade adjustment.
16230                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16231                        adj = ProcessList.VISIBLE_APP_ADJ;
16232                        app.adjType = "visible";
16233                    }
16234                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16235                        procState = ActivityManager.PROCESS_STATE_TOP;
16236                    }
16237                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16238                    app.cached = false;
16239                    app.empty = false;
16240                    foregroundActivities = true;
16241                    break;
16242                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16243                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16244                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16245                        app.adjType = "pausing";
16246                    }
16247                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16248                        procState = ActivityManager.PROCESS_STATE_TOP;
16249                    }
16250                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16251                    app.cached = false;
16252                    app.empty = false;
16253                    foregroundActivities = true;
16254                } else if (r.state == ActivityState.STOPPING) {
16255                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16256                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16257                        app.adjType = "stopping";
16258                    }
16259                    // For the process state, we will at this point consider the
16260                    // process to be cached.  It will be cached either as an activity
16261                    // or empty depending on whether the activity is finishing.  We do
16262                    // this so that we can treat the process as cached for purposes of
16263                    // memory trimming (determing current memory level, trim command to
16264                    // send to process) since there can be an arbitrary number of stopping
16265                    // processes and they should soon all go into the cached state.
16266                    if (!r.finishing) {
16267                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16268                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16269                        }
16270                    }
16271                    app.cached = false;
16272                    app.empty = false;
16273                    foregroundActivities = true;
16274                } else {
16275                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16276                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16277                        app.adjType = "cch-act";
16278                    }
16279                }
16280            }
16281        }
16282
16283        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16284            if (app.foregroundServices) {
16285                // The user is aware of this app, so make it visible.
16286                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16287                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16288                app.cached = false;
16289                app.adjType = "fg-service";
16290                schedGroup = Process.THREAD_GROUP_DEFAULT;
16291            } else if (app.forcingToForeground != null) {
16292                // The user is aware of this app, so make it visible.
16293                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16294                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16295                app.cached = false;
16296                app.adjType = "force-fg";
16297                app.adjSource = app.forcingToForeground;
16298                schedGroup = Process.THREAD_GROUP_DEFAULT;
16299            }
16300        }
16301
16302        if (app == mHeavyWeightProcess) {
16303            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16304                // We don't want to kill the current heavy-weight process.
16305                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16306                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16307                app.cached = false;
16308                app.adjType = "heavy";
16309            }
16310            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16311                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16312            }
16313        }
16314
16315        if (app == mHomeProcess) {
16316            if (adj > ProcessList.HOME_APP_ADJ) {
16317                // This process is hosting what we currently consider to be the
16318                // home app, so we don't want to let it go into the background.
16319                adj = ProcessList.HOME_APP_ADJ;
16320                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16321                app.cached = false;
16322                app.adjType = "home";
16323            }
16324            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16325                procState = ActivityManager.PROCESS_STATE_HOME;
16326            }
16327        }
16328
16329        if (app == mPreviousProcess && app.activities.size() > 0) {
16330            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16331                // This was the previous process that showed UI to the user.
16332                // We want to try to keep it around more aggressively, to give
16333                // a good experience around switching between two apps.
16334                adj = ProcessList.PREVIOUS_APP_ADJ;
16335                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16336                app.cached = false;
16337                app.adjType = "previous";
16338            }
16339            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16340                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16341            }
16342        }
16343
16344        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16345                + " reason=" + app.adjType);
16346
16347        // By default, we use the computed adjustment.  It may be changed if
16348        // there are applications dependent on our services or providers, but
16349        // this gives us a baseline and makes sure we don't get into an
16350        // infinite recursion.
16351        app.adjSeq = mAdjSeq;
16352        app.curRawAdj = adj;
16353        app.hasStartedServices = false;
16354
16355        if (mBackupTarget != null && app == mBackupTarget.app) {
16356            // If possible we want to avoid killing apps while they're being backed up
16357            if (adj > ProcessList.BACKUP_APP_ADJ) {
16358                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16359                adj = ProcessList.BACKUP_APP_ADJ;
16360                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16361                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16362                }
16363                app.adjType = "backup";
16364                app.cached = false;
16365            }
16366            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16367                procState = ActivityManager.PROCESS_STATE_BACKUP;
16368            }
16369        }
16370
16371        boolean mayBeTop = false;
16372
16373        for (int is = app.services.size()-1;
16374                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16375                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16376                        || procState > ActivityManager.PROCESS_STATE_TOP);
16377                is--) {
16378            ServiceRecord s = app.services.valueAt(is);
16379            if (s.startRequested) {
16380                app.hasStartedServices = true;
16381                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16382                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16383                }
16384                if (app.hasShownUi && app != mHomeProcess) {
16385                    // If this process has shown some UI, let it immediately
16386                    // go to the LRU list because it may be pretty heavy with
16387                    // UI stuff.  We'll tag it with a label just to help
16388                    // debug and understand what is going on.
16389                    if (adj > ProcessList.SERVICE_ADJ) {
16390                        app.adjType = "cch-started-ui-services";
16391                    }
16392                } else {
16393                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16394                        // This service has seen some activity within
16395                        // recent memory, so we will keep its process ahead
16396                        // of the background processes.
16397                        if (adj > ProcessList.SERVICE_ADJ) {
16398                            adj = ProcessList.SERVICE_ADJ;
16399                            app.adjType = "started-services";
16400                            app.cached = false;
16401                        }
16402                    }
16403                    // If we have let the service slide into the background
16404                    // state, still have some text describing what it is doing
16405                    // even though the service no longer has an impact.
16406                    if (adj > ProcessList.SERVICE_ADJ) {
16407                        app.adjType = "cch-started-services";
16408                    }
16409                }
16410            }
16411            for (int conni = s.connections.size()-1;
16412                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16413                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16414                            || procState > ActivityManager.PROCESS_STATE_TOP);
16415                    conni--) {
16416                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16417                for (int i = 0;
16418                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16419                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16420                                || procState > ActivityManager.PROCESS_STATE_TOP);
16421                        i++) {
16422                    // XXX should compute this based on the max of
16423                    // all connected clients.
16424                    ConnectionRecord cr = clist.get(i);
16425                    if (cr.binding.client == app) {
16426                        // Binding to ourself is not interesting.
16427                        continue;
16428                    }
16429                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16430                        ProcessRecord client = cr.binding.client;
16431                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16432                                TOP_APP, doingAll, now);
16433                        int clientProcState = client.curProcState;
16434                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16435                            // If the other app is cached for any reason, for purposes here
16436                            // we are going to consider it empty.  The specific cached state
16437                            // doesn't propagate except under certain conditions.
16438                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16439                        }
16440                        String adjType = null;
16441                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16442                            // Not doing bind OOM management, so treat
16443                            // this guy more like a started service.
16444                            if (app.hasShownUi && app != mHomeProcess) {
16445                                // If this process has shown some UI, let it immediately
16446                                // go to the LRU list because it may be pretty heavy with
16447                                // UI stuff.  We'll tag it with a label just to help
16448                                // debug and understand what is going on.
16449                                if (adj > clientAdj) {
16450                                    adjType = "cch-bound-ui-services";
16451                                }
16452                                app.cached = false;
16453                                clientAdj = adj;
16454                                clientProcState = procState;
16455                            } else {
16456                                if (now >= (s.lastActivity
16457                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16458                                    // This service has not seen activity within
16459                                    // recent memory, so allow it to drop to the
16460                                    // LRU list if there is no other reason to keep
16461                                    // it around.  We'll also tag it with a label just
16462                                    // to help debug and undertand what is going on.
16463                                    if (adj > clientAdj) {
16464                                        adjType = "cch-bound-services";
16465                                    }
16466                                    clientAdj = adj;
16467                                }
16468                            }
16469                        }
16470                        if (adj > clientAdj) {
16471                            // If this process has recently shown UI, and
16472                            // the process that is binding to it is less
16473                            // important than being visible, then we don't
16474                            // care about the binding as much as we care
16475                            // about letting this process get into the LRU
16476                            // list to be killed and restarted if needed for
16477                            // memory.
16478                            if (app.hasShownUi && app != mHomeProcess
16479                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16480                                adjType = "cch-bound-ui-services";
16481                            } else {
16482                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16483                                        |Context.BIND_IMPORTANT)) != 0) {
16484                                    adj = clientAdj;
16485                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16486                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16487                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16488                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16489                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16490                                    adj = clientAdj;
16491                                } else {
16492                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16493                                        adj = ProcessList.VISIBLE_APP_ADJ;
16494                                    }
16495                                }
16496                                if (!client.cached) {
16497                                    app.cached = false;
16498                                }
16499                                adjType = "service";
16500                            }
16501                        }
16502                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16503                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16504                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16505                            }
16506                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16507                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16508                                    // Special handling of clients who are in the top state.
16509                                    // We *may* want to consider this process to be in the
16510                                    // top state as well, but only if there is not another
16511                                    // reason for it to be running.  Being on the top is a
16512                                    // special state, meaning you are specifically running
16513                                    // for the current top app.  If the process is already
16514                                    // running in the background for some other reason, it
16515                                    // is more important to continue considering it to be
16516                                    // in the background state.
16517                                    mayBeTop = true;
16518                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16519                                } else {
16520                                    // Special handling for above-top states (persistent
16521                                    // processes).  These should not bring the current process
16522                                    // into the top state, since they are not on top.  Instead
16523                                    // give them the best state after that.
16524                                    clientProcState =
16525                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16526                                }
16527                            }
16528                        } else {
16529                            if (clientProcState <
16530                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16531                                clientProcState =
16532                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16533                            }
16534                        }
16535                        if (procState > clientProcState) {
16536                            procState = clientProcState;
16537                        }
16538                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16539                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16540                            app.pendingUiClean = true;
16541                        }
16542                        if (adjType != null) {
16543                            app.adjType = adjType;
16544                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16545                                    .REASON_SERVICE_IN_USE;
16546                            app.adjSource = cr.binding.client;
16547                            app.adjSourceProcState = clientProcState;
16548                            app.adjTarget = s.name;
16549                        }
16550                    }
16551                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16552                        app.treatLikeActivity = true;
16553                    }
16554                    final ActivityRecord a = cr.activity;
16555                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16556                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16557                                (a.visible || a.state == ActivityState.RESUMED
16558                                 || a.state == ActivityState.PAUSING)) {
16559                            adj = ProcessList.FOREGROUND_APP_ADJ;
16560                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16561                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16562                            }
16563                            app.cached = false;
16564                            app.adjType = "service";
16565                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16566                                    .REASON_SERVICE_IN_USE;
16567                            app.adjSource = a;
16568                            app.adjSourceProcState = procState;
16569                            app.adjTarget = s.name;
16570                        }
16571                    }
16572                }
16573            }
16574        }
16575
16576        for (int provi = app.pubProviders.size()-1;
16577                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16578                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16579                        || procState > ActivityManager.PROCESS_STATE_TOP);
16580                provi--) {
16581            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16582            for (int i = cpr.connections.size()-1;
16583                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16584                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16585                            || procState > ActivityManager.PROCESS_STATE_TOP);
16586                    i--) {
16587                ContentProviderConnection conn = cpr.connections.get(i);
16588                ProcessRecord client = conn.client;
16589                if (client == app) {
16590                    // Being our own client is not interesting.
16591                    continue;
16592                }
16593                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16594                int clientProcState = client.curProcState;
16595                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16596                    // If the other app is cached for any reason, for purposes here
16597                    // we are going to consider it empty.
16598                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16599                }
16600                if (adj > clientAdj) {
16601                    if (app.hasShownUi && app != mHomeProcess
16602                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16603                        app.adjType = "cch-ui-provider";
16604                    } else {
16605                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16606                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16607                        app.adjType = "provider";
16608                    }
16609                    app.cached &= client.cached;
16610                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16611                            .REASON_PROVIDER_IN_USE;
16612                    app.adjSource = client;
16613                    app.adjSourceProcState = clientProcState;
16614                    app.adjTarget = cpr.name;
16615                }
16616                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16617                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16618                        // Special handling of clients who are in the top state.
16619                        // We *may* want to consider this process to be in the
16620                        // top state as well, but only if there is not another
16621                        // reason for it to be running.  Being on the top is a
16622                        // special state, meaning you are specifically running
16623                        // for the current top app.  If the process is already
16624                        // running in the background for some other reason, it
16625                        // is more important to continue considering it to be
16626                        // in the background state.
16627                        mayBeTop = true;
16628                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16629                    } else {
16630                        // Special handling for above-top states (persistent
16631                        // processes).  These should not bring the current process
16632                        // into the top state, since they are not on top.  Instead
16633                        // give them the best state after that.
16634                        clientProcState =
16635                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16636                    }
16637                }
16638                if (procState > clientProcState) {
16639                    procState = clientProcState;
16640                }
16641                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16642                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16643                }
16644            }
16645            // If the provider has external (non-framework) process
16646            // dependencies, ensure that its adjustment is at least
16647            // FOREGROUND_APP_ADJ.
16648            if (cpr.hasExternalProcessHandles()) {
16649                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16650                    adj = ProcessList.FOREGROUND_APP_ADJ;
16651                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16652                    app.cached = false;
16653                    app.adjType = "provider";
16654                    app.adjTarget = cpr.name;
16655                }
16656                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16657                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16658                }
16659            }
16660        }
16661
16662        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16663            // A client of one of our services or providers is in the top state.  We
16664            // *may* want to be in the top state, but not if we are already running in
16665            // the background for some other reason.  For the decision here, we are going
16666            // to pick out a few specific states that we want to remain in when a client
16667            // is top (states that tend to be longer-term) and otherwise allow it to go
16668            // to the top state.
16669            switch (procState) {
16670                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16671                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16672                case ActivityManager.PROCESS_STATE_SERVICE:
16673                    // These all are longer-term states, so pull them up to the top
16674                    // of the background states, but not all the way to the top state.
16675                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16676                    break;
16677                default:
16678                    // Otherwise, top is a better choice, so take it.
16679                    procState = ActivityManager.PROCESS_STATE_TOP;
16680                    break;
16681            }
16682        }
16683
16684        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16685            if (app.hasClientActivities) {
16686                // This is a cached process, but with client activities.  Mark it so.
16687                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16688                app.adjType = "cch-client-act";
16689            } else if (app.treatLikeActivity) {
16690                // This is a cached process, but somebody wants us to treat it like it has
16691                // an activity, okay!
16692                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16693                app.adjType = "cch-as-act";
16694            }
16695        }
16696
16697        if (adj == ProcessList.SERVICE_ADJ) {
16698            if (doingAll) {
16699                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16700                mNewNumServiceProcs++;
16701                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16702                if (!app.serviceb) {
16703                    // This service isn't far enough down on the LRU list to
16704                    // normally be a B service, but if we are low on RAM and it
16705                    // is large we want to force it down since we would prefer to
16706                    // keep launcher over it.
16707                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16708                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16709                        app.serviceHighRam = true;
16710                        app.serviceb = true;
16711                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16712                    } else {
16713                        mNewNumAServiceProcs++;
16714                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16715                    }
16716                } else {
16717                    app.serviceHighRam = false;
16718                }
16719            }
16720            if (app.serviceb) {
16721                adj = ProcessList.SERVICE_B_ADJ;
16722            }
16723        }
16724
16725        app.curRawAdj = adj;
16726
16727        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16728        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16729        if (adj > app.maxAdj) {
16730            adj = app.maxAdj;
16731            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16732                schedGroup = Process.THREAD_GROUP_DEFAULT;
16733            }
16734        }
16735
16736        // Do final modification to adj.  Everything we do between here and applying
16737        // the final setAdj must be done in this function, because we will also use
16738        // it when computing the final cached adj later.  Note that we don't need to
16739        // worry about this for max adj above, since max adj will always be used to
16740        // keep it out of the cached vaues.
16741        app.curAdj = app.modifyRawOomAdj(adj);
16742        app.curSchedGroup = schedGroup;
16743        app.curProcState = procState;
16744        app.foregroundActivities = foregroundActivities;
16745
16746        return app.curRawAdj;
16747    }
16748
16749    /**
16750     * Schedule PSS collection of a process.
16751     */
16752    void requestPssLocked(ProcessRecord proc, int procState) {
16753        if (mPendingPssProcesses.contains(proc)) {
16754            return;
16755        }
16756        if (mPendingPssProcesses.size() == 0) {
16757            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16758        }
16759        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16760        proc.pssProcState = procState;
16761        mPendingPssProcesses.add(proc);
16762    }
16763
16764    /**
16765     * Schedule PSS collection of all processes.
16766     */
16767    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16768        if (!always) {
16769            if (now < (mLastFullPssTime +
16770                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16771                return;
16772            }
16773        }
16774        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16775        mLastFullPssTime = now;
16776        mFullPssPending = true;
16777        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16778        mPendingPssProcesses.clear();
16779        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16780            ProcessRecord app = mLruProcesses.get(i);
16781            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16782                app.pssProcState = app.setProcState;
16783                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16784                        isSleeping(), now);
16785                mPendingPssProcesses.add(app);
16786            }
16787        }
16788        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16789    }
16790
16791    /**
16792     * Ask a given process to GC right now.
16793     */
16794    final void performAppGcLocked(ProcessRecord app) {
16795        try {
16796            app.lastRequestedGc = SystemClock.uptimeMillis();
16797            if (app.thread != null) {
16798                if (app.reportLowMemory) {
16799                    app.reportLowMemory = false;
16800                    app.thread.scheduleLowMemory();
16801                } else {
16802                    app.thread.processInBackground();
16803                }
16804            }
16805        } catch (Exception e) {
16806            // whatever.
16807        }
16808    }
16809
16810    /**
16811     * Returns true if things are idle enough to perform GCs.
16812     */
16813    private final boolean canGcNowLocked() {
16814        boolean processingBroadcasts = false;
16815        for (BroadcastQueue q : mBroadcastQueues) {
16816            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16817                processingBroadcasts = true;
16818            }
16819        }
16820        return !processingBroadcasts
16821                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16822    }
16823
16824    /**
16825     * Perform GCs on all processes that are waiting for it, but only
16826     * if things are idle.
16827     */
16828    final void performAppGcsLocked() {
16829        final int N = mProcessesToGc.size();
16830        if (N <= 0) {
16831            return;
16832        }
16833        if (canGcNowLocked()) {
16834            while (mProcessesToGc.size() > 0) {
16835                ProcessRecord proc = mProcessesToGc.remove(0);
16836                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16837                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16838                            <= SystemClock.uptimeMillis()) {
16839                        // To avoid spamming the system, we will GC processes one
16840                        // at a time, waiting a few seconds between each.
16841                        performAppGcLocked(proc);
16842                        scheduleAppGcsLocked();
16843                        return;
16844                    } else {
16845                        // It hasn't been long enough since we last GCed this
16846                        // process...  put it in the list to wait for its time.
16847                        addProcessToGcListLocked(proc);
16848                        break;
16849                    }
16850                }
16851            }
16852
16853            scheduleAppGcsLocked();
16854        }
16855    }
16856
16857    /**
16858     * If all looks good, perform GCs on all processes waiting for them.
16859     */
16860    final void performAppGcsIfAppropriateLocked() {
16861        if (canGcNowLocked()) {
16862            performAppGcsLocked();
16863            return;
16864        }
16865        // Still not idle, wait some more.
16866        scheduleAppGcsLocked();
16867    }
16868
16869    /**
16870     * Schedule the execution of all pending app GCs.
16871     */
16872    final void scheduleAppGcsLocked() {
16873        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16874
16875        if (mProcessesToGc.size() > 0) {
16876            // Schedule a GC for the time to the next process.
16877            ProcessRecord proc = mProcessesToGc.get(0);
16878            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16879
16880            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16881            long now = SystemClock.uptimeMillis();
16882            if (when < (now+GC_TIMEOUT)) {
16883                when = now + GC_TIMEOUT;
16884            }
16885            mHandler.sendMessageAtTime(msg, when);
16886        }
16887    }
16888
16889    /**
16890     * Add a process to the array of processes waiting to be GCed.  Keeps the
16891     * list in sorted order by the last GC time.  The process can't already be
16892     * on the list.
16893     */
16894    final void addProcessToGcListLocked(ProcessRecord proc) {
16895        boolean added = false;
16896        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16897            if (mProcessesToGc.get(i).lastRequestedGc <
16898                    proc.lastRequestedGc) {
16899                added = true;
16900                mProcessesToGc.add(i+1, proc);
16901                break;
16902            }
16903        }
16904        if (!added) {
16905            mProcessesToGc.add(0, proc);
16906        }
16907    }
16908
16909    /**
16910     * Set up to ask a process to GC itself.  This will either do it
16911     * immediately, or put it on the list of processes to gc the next
16912     * time things are idle.
16913     */
16914    final void scheduleAppGcLocked(ProcessRecord app) {
16915        long now = SystemClock.uptimeMillis();
16916        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16917            return;
16918        }
16919        if (!mProcessesToGc.contains(app)) {
16920            addProcessToGcListLocked(app);
16921            scheduleAppGcsLocked();
16922        }
16923    }
16924
16925    final void checkExcessivePowerUsageLocked(boolean doKills) {
16926        updateCpuStatsNow();
16927
16928        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16929        boolean doWakeKills = doKills;
16930        boolean doCpuKills = doKills;
16931        if (mLastPowerCheckRealtime == 0) {
16932            doWakeKills = false;
16933        }
16934        if (mLastPowerCheckUptime == 0) {
16935            doCpuKills = false;
16936        }
16937        if (stats.isScreenOn()) {
16938            doWakeKills = false;
16939        }
16940        final long curRealtime = SystemClock.elapsedRealtime();
16941        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16942        final long curUptime = SystemClock.uptimeMillis();
16943        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16944        mLastPowerCheckRealtime = curRealtime;
16945        mLastPowerCheckUptime = curUptime;
16946        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16947            doWakeKills = false;
16948        }
16949        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16950            doCpuKills = false;
16951        }
16952        int i = mLruProcesses.size();
16953        while (i > 0) {
16954            i--;
16955            ProcessRecord app = mLruProcesses.get(i);
16956            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16957                long wtime;
16958                synchronized (stats) {
16959                    wtime = stats.getProcessWakeTime(app.info.uid,
16960                            app.pid, curRealtime);
16961                }
16962                long wtimeUsed = wtime - app.lastWakeTime;
16963                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16964                if (DEBUG_POWER) {
16965                    StringBuilder sb = new StringBuilder(128);
16966                    sb.append("Wake for ");
16967                    app.toShortString(sb);
16968                    sb.append(": over ");
16969                    TimeUtils.formatDuration(realtimeSince, sb);
16970                    sb.append(" used ");
16971                    TimeUtils.formatDuration(wtimeUsed, sb);
16972                    sb.append(" (");
16973                    sb.append((wtimeUsed*100)/realtimeSince);
16974                    sb.append("%)");
16975                    Slog.i(TAG, sb.toString());
16976                    sb.setLength(0);
16977                    sb.append("CPU for ");
16978                    app.toShortString(sb);
16979                    sb.append(": over ");
16980                    TimeUtils.formatDuration(uptimeSince, sb);
16981                    sb.append(" used ");
16982                    TimeUtils.formatDuration(cputimeUsed, sb);
16983                    sb.append(" (");
16984                    sb.append((cputimeUsed*100)/uptimeSince);
16985                    sb.append("%)");
16986                    Slog.i(TAG, sb.toString());
16987                }
16988                // If a process has held a wake lock for more
16989                // than 50% of the time during this period,
16990                // that sounds bad.  Kill!
16991                if (doWakeKills && realtimeSince > 0
16992                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16993                    synchronized (stats) {
16994                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16995                                realtimeSince, wtimeUsed);
16996                    }
16997                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16998                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16999                } else if (doCpuKills && uptimeSince > 0
17000                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17001                    synchronized (stats) {
17002                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17003                                uptimeSince, cputimeUsed);
17004                    }
17005                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17006                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17007                } else {
17008                    app.lastWakeTime = wtime;
17009                    app.lastCpuTime = app.curCpuTime;
17010                }
17011            }
17012        }
17013    }
17014
17015    private final boolean applyOomAdjLocked(ProcessRecord app,
17016            ProcessRecord TOP_APP, boolean doingAll, long now) {
17017        boolean success = true;
17018
17019        if (app.curRawAdj != app.setRawAdj) {
17020            app.setRawAdj = app.curRawAdj;
17021        }
17022
17023        int changes = 0;
17024
17025        if (app.curAdj != app.setAdj) {
17026            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17027            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17028                TAG, "Set " + app.pid + " " + app.processName +
17029                " adj " + app.curAdj + ": " + app.adjType);
17030            app.setAdj = app.curAdj;
17031        }
17032
17033        if (app.setSchedGroup != app.curSchedGroup) {
17034            app.setSchedGroup = app.curSchedGroup;
17035            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17036                    "Setting process group of " + app.processName
17037                    + " to " + app.curSchedGroup);
17038            if (app.waitingToKill != null &&
17039                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17040                app.kill(app.waitingToKill, true);
17041                success = false;
17042            } else {
17043                if (true) {
17044                    long oldId = Binder.clearCallingIdentity();
17045                    try {
17046                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17047                    } catch (Exception e) {
17048                        Slog.w(TAG, "Failed setting process group of " + app.pid
17049                                + " to " + app.curSchedGroup);
17050                        e.printStackTrace();
17051                    } finally {
17052                        Binder.restoreCallingIdentity(oldId);
17053                    }
17054                } else {
17055                    if (app.thread != null) {
17056                        try {
17057                            app.thread.setSchedulingGroup(app.curSchedGroup);
17058                        } catch (RemoteException e) {
17059                        }
17060                    }
17061                }
17062                Process.setSwappiness(app.pid,
17063                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17064            }
17065        }
17066        if (app.repForegroundActivities != app.foregroundActivities) {
17067            app.repForegroundActivities = app.foregroundActivities;
17068            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17069        }
17070        if (app.repProcState != app.curProcState) {
17071            app.repProcState = app.curProcState;
17072            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17073            if (app.thread != null) {
17074                try {
17075                    if (false) {
17076                        //RuntimeException h = new RuntimeException("here");
17077                        Slog.i(TAG, "Sending new process state " + app.repProcState
17078                                + " to " + app /*, h*/);
17079                    }
17080                    app.thread.setProcessState(app.repProcState);
17081                } catch (RemoteException e) {
17082                }
17083            }
17084        }
17085        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17086                app.setProcState)) {
17087            app.lastStateTime = now;
17088            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17089                    isSleeping(), now);
17090            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17091                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17092                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17093                    + (app.nextPssTime-now) + ": " + app);
17094        } else {
17095            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17096                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17097                requestPssLocked(app, app.setProcState);
17098                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17099                        isSleeping(), now);
17100            } else if (false && DEBUG_PSS) {
17101                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17102            }
17103        }
17104        if (app.setProcState != app.curProcState) {
17105            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17106                    "Proc state change of " + app.processName
17107                    + " to " + app.curProcState);
17108            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17109            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17110            if (setImportant && !curImportant) {
17111                // This app is no longer something we consider important enough to allow to
17112                // use arbitrary amounts of battery power.  Note
17113                // its current wake lock time to later know to kill it if
17114                // it is not behaving well.
17115                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17116                synchronized (stats) {
17117                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17118                            app.pid, SystemClock.elapsedRealtime());
17119                }
17120                app.lastCpuTime = app.curCpuTime;
17121
17122            }
17123            app.setProcState = app.curProcState;
17124            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17125                app.notCachedSinceIdle = false;
17126            }
17127            if (!doingAll) {
17128                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17129            } else {
17130                app.procStateChanged = true;
17131            }
17132        }
17133
17134        if (changes != 0) {
17135            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17136            int i = mPendingProcessChanges.size()-1;
17137            ProcessChangeItem item = null;
17138            while (i >= 0) {
17139                item = mPendingProcessChanges.get(i);
17140                if (item.pid == app.pid) {
17141                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17142                    break;
17143                }
17144                i--;
17145            }
17146            if (i < 0) {
17147                // No existing item in pending changes; need a new one.
17148                final int NA = mAvailProcessChanges.size();
17149                if (NA > 0) {
17150                    item = mAvailProcessChanges.remove(NA-1);
17151                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17152                } else {
17153                    item = new ProcessChangeItem();
17154                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17155                }
17156                item.changes = 0;
17157                item.pid = app.pid;
17158                item.uid = app.info.uid;
17159                if (mPendingProcessChanges.size() == 0) {
17160                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17161                            "*** Enqueueing dispatch processes changed!");
17162                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17163                }
17164                mPendingProcessChanges.add(item);
17165            }
17166            item.changes |= changes;
17167            item.processState = app.repProcState;
17168            item.foregroundActivities = app.repForegroundActivities;
17169            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17170                    + Integer.toHexString(System.identityHashCode(item))
17171                    + " " + app.toShortString() + ": changes=" + item.changes
17172                    + " procState=" + item.processState
17173                    + " foreground=" + item.foregroundActivities
17174                    + " type=" + app.adjType + " source=" + app.adjSource
17175                    + " target=" + app.adjTarget);
17176        }
17177
17178        return success;
17179    }
17180
17181    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17182        if (proc.thread != null) {
17183            if (proc.baseProcessTracker != null) {
17184                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17185            }
17186            if (proc.repProcState >= 0) {
17187                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17188                        proc.repProcState);
17189            }
17190        }
17191    }
17192
17193    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17194            ProcessRecord TOP_APP, boolean doingAll, long now) {
17195        if (app.thread == null) {
17196            return false;
17197        }
17198
17199        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17200
17201        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17202    }
17203
17204    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17205            boolean oomAdj) {
17206        if (isForeground != proc.foregroundServices) {
17207            proc.foregroundServices = isForeground;
17208            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17209                    proc.info.uid);
17210            if (isForeground) {
17211                if (curProcs == null) {
17212                    curProcs = new ArrayList<ProcessRecord>();
17213                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17214                }
17215                if (!curProcs.contains(proc)) {
17216                    curProcs.add(proc);
17217                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17218                            proc.info.packageName, proc.info.uid);
17219                }
17220            } else {
17221                if (curProcs != null) {
17222                    if (curProcs.remove(proc)) {
17223                        mBatteryStatsService.noteEvent(
17224                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17225                                proc.info.packageName, proc.info.uid);
17226                        if (curProcs.size() <= 0) {
17227                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17228                        }
17229                    }
17230                }
17231            }
17232            if (oomAdj) {
17233                updateOomAdjLocked();
17234            }
17235        }
17236    }
17237
17238    private final ActivityRecord resumedAppLocked() {
17239        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17240        String pkg;
17241        int uid;
17242        if (act != null) {
17243            pkg = act.packageName;
17244            uid = act.info.applicationInfo.uid;
17245        } else {
17246            pkg = null;
17247            uid = -1;
17248        }
17249        // Has the UID or resumed package name changed?
17250        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17251                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17252            if (mCurResumedPackage != null) {
17253                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17254                        mCurResumedPackage, mCurResumedUid);
17255            }
17256            mCurResumedPackage = pkg;
17257            mCurResumedUid = uid;
17258            if (mCurResumedPackage != null) {
17259                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17260                        mCurResumedPackage, mCurResumedUid);
17261            }
17262        }
17263        return act;
17264    }
17265
17266    final boolean updateOomAdjLocked(ProcessRecord app) {
17267        final ActivityRecord TOP_ACT = resumedAppLocked();
17268        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17269        final boolean wasCached = app.cached;
17270
17271        mAdjSeq++;
17272
17273        // This is the desired cached adjusment we want to tell it to use.
17274        // If our app is currently cached, we know it, and that is it.  Otherwise,
17275        // we don't know it yet, and it needs to now be cached we will then
17276        // need to do a complete oom adj.
17277        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17278                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17279        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17280                SystemClock.uptimeMillis());
17281        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17282            // Changed to/from cached state, so apps after it in the LRU
17283            // list may also be changed.
17284            updateOomAdjLocked();
17285        }
17286        return success;
17287    }
17288
17289    final void updateOomAdjLocked() {
17290        final ActivityRecord TOP_ACT = resumedAppLocked();
17291        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17292        final long now = SystemClock.uptimeMillis();
17293        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17294        final int N = mLruProcesses.size();
17295
17296        if (false) {
17297            RuntimeException e = new RuntimeException();
17298            e.fillInStackTrace();
17299            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17300        }
17301
17302        mAdjSeq++;
17303        mNewNumServiceProcs = 0;
17304        mNewNumAServiceProcs = 0;
17305
17306        final int emptyProcessLimit;
17307        final int cachedProcessLimit;
17308        if (mProcessLimit <= 0) {
17309            emptyProcessLimit = cachedProcessLimit = 0;
17310        } else if (mProcessLimit == 1) {
17311            emptyProcessLimit = 1;
17312            cachedProcessLimit = 0;
17313        } else {
17314            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17315            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17316        }
17317
17318        // Let's determine how many processes we have running vs.
17319        // how many slots we have for background processes; we may want
17320        // to put multiple processes in a slot of there are enough of
17321        // them.
17322        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17323                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17324        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17325        if (numEmptyProcs > cachedProcessLimit) {
17326            // If there are more empty processes than our limit on cached
17327            // processes, then use the cached process limit for the factor.
17328            // This ensures that the really old empty processes get pushed
17329            // down to the bottom, so if we are running low on memory we will
17330            // have a better chance at keeping around more cached processes
17331            // instead of a gazillion empty processes.
17332            numEmptyProcs = cachedProcessLimit;
17333        }
17334        int emptyFactor = numEmptyProcs/numSlots;
17335        if (emptyFactor < 1) emptyFactor = 1;
17336        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17337        if (cachedFactor < 1) cachedFactor = 1;
17338        int stepCached = 0;
17339        int stepEmpty = 0;
17340        int numCached = 0;
17341        int numEmpty = 0;
17342        int numTrimming = 0;
17343
17344        mNumNonCachedProcs = 0;
17345        mNumCachedHiddenProcs = 0;
17346
17347        // First update the OOM adjustment for each of the
17348        // application processes based on their current state.
17349        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17350        int nextCachedAdj = curCachedAdj+1;
17351        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17352        int nextEmptyAdj = curEmptyAdj+2;
17353        for (int i=N-1; i>=0; i--) {
17354            ProcessRecord app = mLruProcesses.get(i);
17355            if (!app.killedByAm && app.thread != null) {
17356                app.procStateChanged = false;
17357                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17358
17359                // If we haven't yet assigned the final cached adj
17360                // to the process, do that now.
17361                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17362                    switch (app.curProcState) {
17363                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17364                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17365                            // This process is a cached process holding activities...
17366                            // assign it the next cached value for that type, and then
17367                            // step that cached level.
17368                            app.curRawAdj = curCachedAdj;
17369                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17370                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17371                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17372                                    + ")");
17373                            if (curCachedAdj != nextCachedAdj) {
17374                                stepCached++;
17375                                if (stepCached >= cachedFactor) {
17376                                    stepCached = 0;
17377                                    curCachedAdj = nextCachedAdj;
17378                                    nextCachedAdj += 2;
17379                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17380                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17381                                    }
17382                                }
17383                            }
17384                            break;
17385                        default:
17386                            // For everything else, assign next empty cached process
17387                            // level and bump that up.  Note that this means that
17388                            // long-running services that have dropped down to the
17389                            // cached level will be treated as empty (since their process
17390                            // state is still as a service), which is what we want.
17391                            app.curRawAdj = curEmptyAdj;
17392                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17393                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17394                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17395                                    + ")");
17396                            if (curEmptyAdj != nextEmptyAdj) {
17397                                stepEmpty++;
17398                                if (stepEmpty >= emptyFactor) {
17399                                    stepEmpty = 0;
17400                                    curEmptyAdj = nextEmptyAdj;
17401                                    nextEmptyAdj += 2;
17402                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17403                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17404                                    }
17405                                }
17406                            }
17407                            break;
17408                    }
17409                }
17410
17411                applyOomAdjLocked(app, TOP_APP, true, now);
17412
17413                // Count the number of process types.
17414                switch (app.curProcState) {
17415                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17416                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17417                        mNumCachedHiddenProcs++;
17418                        numCached++;
17419                        if (numCached > cachedProcessLimit) {
17420                            app.kill("cached #" + numCached, true);
17421                        }
17422                        break;
17423                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17424                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17425                                && app.lastActivityTime < oldTime) {
17426                            app.kill("empty for "
17427                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17428                                    / 1000) + "s", true);
17429                        } else {
17430                            numEmpty++;
17431                            if (numEmpty > emptyProcessLimit) {
17432                                app.kill("empty #" + numEmpty, true);
17433                            }
17434                        }
17435                        break;
17436                    default:
17437                        mNumNonCachedProcs++;
17438                        break;
17439                }
17440
17441                if (app.isolated && app.services.size() <= 0) {
17442                    // If this is an isolated process, and there are no
17443                    // services running in it, then the process is no longer
17444                    // needed.  We agressively kill these because we can by
17445                    // definition not re-use the same process again, and it is
17446                    // good to avoid having whatever code was running in them
17447                    // left sitting around after no longer needed.
17448                    app.kill("isolated not needed", true);
17449                }
17450
17451                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17452                        && !app.killedByAm) {
17453                    numTrimming++;
17454                }
17455            }
17456        }
17457
17458        mNumServiceProcs = mNewNumServiceProcs;
17459
17460        // Now determine the memory trimming level of background processes.
17461        // Unfortunately we need to start at the back of the list to do this
17462        // properly.  We only do this if the number of background apps we
17463        // are managing to keep around is less than half the maximum we desire;
17464        // if we are keeping a good number around, we'll let them use whatever
17465        // memory they want.
17466        final int numCachedAndEmpty = numCached + numEmpty;
17467        int memFactor;
17468        if (numCached <= ProcessList.TRIM_CACHED_APPS
17469                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17470            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17471                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17472            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17473                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17474            } else {
17475                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17476            }
17477        } else {
17478            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17479        }
17480        // We always allow the memory level to go up (better).  We only allow it to go
17481        // down if we are in a state where that is allowed, *and* the total number of processes
17482        // has gone down since last time.
17483        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17484                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17485                + " last=" + mLastNumProcesses);
17486        if (memFactor > mLastMemoryLevel) {
17487            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17488                memFactor = mLastMemoryLevel;
17489                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17490            }
17491        }
17492        mLastMemoryLevel = memFactor;
17493        mLastNumProcesses = mLruProcesses.size();
17494        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17495        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17496        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17497            if (mLowRamStartTime == 0) {
17498                mLowRamStartTime = now;
17499            }
17500            int step = 0;
17501            int fgTrimLevel;
17502            switch (memFactor) {
17503                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17504                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17505                    break;
17506                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17507                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17508                    break;
17509                default:
17510                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17511                    break;
17512            }
17513            int factor = numTrimming/3;
17514            int minFactor = 2;
17515            if (mHomeProcess != null) minFactor++;
17516            if (mPreviousProcess != null) minFactor++;
17517            if (factor < minFactor) factor = minFactor;
17518            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17519            for (int i=N-1; i>=0; i--) {
17520                ProcessRecord app = mLruProcesses.get(i);
17521                if (allChanged || app.procStateChanged) {
17522                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17523                    app.procStateChanged = false;
17524                }
17525                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17526                        && !app.killedByAm) {
17527                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17528                        try {
17529                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17530                                    "Trimming memory of " + app.processName
17531                                    + " to " + curLevel);
17532                            app.thread.scheduleTrimMemory(curLevel);
17533                        } catch (RemoteException e) {
17534                        }
17535                        if (false) {
17536                            // For now we won't do this; our memory trimming seems
17537                            // to be good enough at this point that destroying
17538                            // activities causes more harm than good.
17539                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17540                                    && app != mHomeProcess && app != mPreviousProcess) {
17541                                // Need to do this on its own message because the stack may not
17542                                // be in a consistent state at this point.
17543                                // For these apps we will also finish their activities
17544                                // to help them free memory.
17545                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17546                            }
17547                        }
17548                    }
17549                    app.trimMemoryLevel = curLevel;
17550                    step++;
17551                    if (step >= factor) {
17552                        step = 0;
17553                        switch (curLevel) {
17554                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17555                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17556                                break;
17557                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17558                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17559                                break;
17560                        }
17561                    }
17562                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17563                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17564                            && app.thread != null) {
17565                        try {
17566                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17567                                    "Trimming memory of heavy-weight " + app.processName
17568                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17569                            app.thread.scheduleTrimMemory(
17570                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17571                        } catch (RemoteException e) {
17572                        }
17573                    }
17574                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17575                } else {
17576                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17577                            || app.systemNoUi) && app.pendingUiClean) {
17578                        // If this application is now in the background and it
17579                        // had done UI, then give it the special trim level to
17580                        // have it free UI resources.
17581                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17582                        if (app.trimMemoryLevel < level && app.thread != null) {
17583                            try {
17584                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17585                                        "Trimming memory of bg-ui " + app.processName
17586                                        + " to " + level);
17587                                app.thread.scheduleTrimMemory(level);
17588                            } catch (RemoteException e) {
17589                            }
17590                        }
17591                        app.pendingUiClean = false;
17592                    }
17593                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17594                        try {
17595                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17596                                    "Trimming memory of fg " + app.processName
17597                                    + " to " + fgTrimLevel);
17598                            app.thread.scheduleTrimMemory(fgTrimLevel);
17599                        } catch (RemoteException e) {
17600                        }
17601                    }
17602                    app.trimMemoryLevel = fgTrimLevel;
17603                }
17604            }
17605        } else {
17606            if (mLowRamStartTime != 0) {
17607                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17608                mLowRamStartTime = 0;
17609            }
17610            for (int i=N-1; i>=0; i--) {
17611                ProcessRecord app = mLruProcesses.get(i);
17612                if (allChanged || app.procStateChanged) {
17613                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17614                    app.procStateChanged = false;
17615                }
17616                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17617                        || app.systemNoUi) && app.pendingUiClean) {
17618                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17619                            && app.thread != null) {
17620                        try {
17621                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17622                                    "Trimming memory of ui hidden " + app.processName
17623                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17624                            app.thread.scheduleTrimMemory(
17625                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17626                        } catch (RemoteException e) {
17627                        }
17628                    }
17629                    app.pendingUiClean = false;
17630                }
17631                app.trimMemoryLevel = 0;
17632            }
17633        }
17634
17635        if (mAlwaysFinishActivities) {
17636            // Need to do this on its own message because the stack may not
17637            // be in a consistent state at this point.
17638            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17639        }
17640
17641        if (allChanged) {
17642            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17643        }
17644
17645        if (mProcessStats.shouldWriteNowLocked(now)) {
17646            mHandler.post(new Runnable() {
17647                @Override public void run() {
17648                    synchronized (ActivityManagerService.this) {
17649                        mProcessStats.writeStateAsyncLocked();
17650                    }
17651                }
17652            });
17653        }
17654
17655        if (DEBUG_OOM_ADJ) {
17656            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17657        }
17658    }
17659
17660    final void trimApplications() {
17661        synchronized (this) {
17662            int i;
17663
17664            // First remove any unused application processes whose package
17665            // has been removed.
17666            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17667                final ProcessRecord app = mRemovedProcesses.get(i);
17668                if (app.activities.size() == 0
17669                        && app.curReceiver == null && app.services.size() == 0) {
17670                    Slog.i(
17671                        TAG, "Exiting empty application process "
17672                        + app.processName + " ("
17673                        + (app.thread != null ? app.thread.asBinder() : null)
17674                        + ")\n");
17675                    if (app.pid > 0 && app.pid != MY_PID) {
17676                        app.kill("empty", false);
17677                    } else {
17678                        try {
17679                            app.thread.scheduleExit();
17680                        } catch (Exception e) {
17681                            // Ignore exceptions.
17682                        }
17683                    }
17684                    cleanUpApplicationRecordLocked(app, false, true, -1);
17685                    mRemovedProcesses.remove(i);
17686
17687                    if (app.persistent) {
17688                        addAppLocked(app.info, false, null /* ABI override */);
17689                    }
17690                }
17691            }
17692
17693            // Now update the oom adj for all processes.
17694            updateOomAdjLocked();
17695        }
17696    }
17697
17698    /** This method sends the specified signal to each of the persistent apps */
17699    public void signalPersistentProcesses(int sig) throws RemoteException {
17700        if (sig != Process.SIGNAL_USR1) {
17701            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17702        }
17703
17704        synchronized (this) {
17705            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17706                    != PackageManager.PERMISSION_GRANTED) {
17707                throw new SecurityException("Requires permission "
17708                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17709            }
17710
17711            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17712                ProcessRecord r = mLruProcesses.get(i);
17713                if (r.thread != null && r.persistent) {
17714                    Process.sendSignal(r.pid, sig);
17715                }
17716            }
17717        }
17718    }
17719
17720    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17721        if (proc == null || proc == mProfileProc) {
17722            proc = mProfileProc;
17723            profileType = mProfileType;
17724            clearProfilerLocked();
17725        }
17726        if (proc == null) {
17727            return;
17728        }
17729        try {
17730            proc.thread.profilerControl(false, null, profileType);
17731        } catch (RemoteException e) {
17732            throw new IllegalStateException("Process disappeared");
17733        }
17734    }
17735
17736    private void clearProfilerLocked() {
17737        if (mProfileFd != null) {
17738            try {
17739                mProfileFd.close();
17740            } catch (IOException e) {
17741            }
17742        }
17743        mProfileApp = null;
17744        mProfileProc = null;
17745        mProfileFile = null;
17746        mProfileType = 0;
17747        mAutoStopProfiler = false;
17748        mSamplingInterval = 0;
17749    }
17750
17751    public boolean profileControl(String process, int userId, boolean start,
17752            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17753
17754        try {
17755            synchronized (this) {
17756                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17757                // its own permission.
17758                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17759                        != PackageManager.PERMISSION_GRANTED) {
17760                    throw new SecurityException("Requires permission "
17761                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17762                }
17763
17764                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17765                    throw new IllegalArgumentException("null profile info or fd");
17766                }
17767
17768                ProcessRecord proc = null;
17769                if (process != null) {
17770                    proc = findProcessLocked(process, userId, "profileControl");
17771                }
17772
17773                if (start && (proc == null || proc.thread == null)) {
17774                    throw new IllegalArgumentException("Unknown process: " + process);
17775                }
17776
17777                if (start) {
17778                    stopProfilerLocked(null, 0);
17779                    setProfileApp(proc.info, proc.processName, profilerInfo);
17780                    mProfileProc = proc;
17781                    mProfileType = profileType;
17782                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17783                    try {
17784                        fd = fd.dup();
17785                    } catch (IOException e) {
17786                        fd = null;
17787                    }
17788                    profilerInfo.profileFd = fd;
17789                    proc.thread.profilerControl(start, profilerInfo, profileType);
17790                    fd = null;
17791                    mProfileFd = null;
17792                } else {
17793                    stopProfilerLocked(proc, profileType);
17794                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17795                        try {
17796                            profilerInfo.profileFd.close();
17797                        } catch (IOException e) {
17798                        }
17799                    }
17800                }
17801
17802                return true;
17803            }
17804        } catch (RemoteException e) {
17805            throw new IllegalStateException("Process disappeared");
17806        } finally {
17807            if (profilerInfo != null && profilerInfo.profileFd != null) {
17808                try {
17809                    profilerInfo.profileFd.close();
17810                } catch (IOException e) {
17811                }
17812            }
17813        }
17814    }
17815
17816    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17817        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17818                userId, true, ALLOW_FULL_ONLY, callName, null);
17819        ProcessRecord proc = null;
17820        try {
17821            int pid = Integer.parseInt(process);
17822            synchronized (mPidsSelfLocked) {
17823                proc = mPidsSelfLocked.get(pid);
17824            }
17825        } catch (NumberFormatException e) {
17826        }
17827
17828        if (proc == null) {
17829            ArrayMap<String, SparseArray<ProcessRecord>> all
17830                    = mProcessNames.getMap();
17831            SparseArray<ProcessRecord> procs = all.get(process);
17832            if (procs != null && procs.size() > 0) {
17833                proc = procs.valueAt(0);
17834                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17835                    for (int i=1; i<procs.size(); i++) {
17836                        ProcessRecord thisProc = procs.valueAt(i);
17837                        if (thisProc.userId == userId) {
17838                            proc = thisProc;
17839                            break;
17840                        }
17841                    }
17842                }
17843            }
17844        }
17845
17846        return proc;
17847    }
17848
17849    public boolean dumpHeap(String process, int userId, boolean managed,
17850            String path, ParcelFileDescriptor fd) throws RemoteException {
17851
17852        try {
17853            synchronized (this) {
17854                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17855                // its own permission (same as profileControl).
17856                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17857                        != PackageManager.PERMISSION_GRANTED) {
17858                    throw new SecurityException("Requires permission "
17859                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17860                }
17861
17862                if (fd == null) {
17863                    throw new IllegalArgumentException("null fd");
17864                }
17865
17866                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17867                if (proc == null || proc.thread == null) {
17868                    throw new IllegalArgumentException("Unknown process: " + process);
17869                }
17870
17871                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17872                if (!isDebuggable) {
17873                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17874                        throw new SecurityException("Process not debuggable: " + proc);
17875                    }
17876                }
17877
17878                proc.thread.dumpHeap(managed, path, fd);
17879                fd = null;
17880                return true;
17881            }
17882        } catch (RemoteException e) {
17883            throw new IllegalStateException("Process disappeared");
17884        } finally {
17885            if (fd != null) {
17886                try {
17887                    fd.close();
17888                } catch (IOException e) {
17889                }
17890            }
17891        }
17892    }
17893
17894    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17895    public void monitor() {
17896        synchronized (this) { }
17897    }
17898
17899    void onCoreSettingsChange(Bundle settings) {
17900        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17901            ProcessRecord processRecord = mLruProcesses.get(i);
17902            try {
17903                if (processRecord.thread != null) {
17904                    processRecord.thread.setCoreSettings(settings);
17905                }
17906            } catch (RemoteException re) {
17907                /* ignore */
17908            }
17909        }
17910    }
17911
17912    // Multi-user methods
17913
17914    /**
17915     * Start user, if its not already running, but don't bring it to foreground.
17916     */
17917    @Override
17918    public boolean startUserInBackground(final int userId) {
17919        return startUser(userId, /* foreground */ false);
17920    }
17921
17922    /**
17923     * Start user, if its not already running, and bring it to foreground.
17924     */
17925    boolean startUserInForeground(final int userId, Dialog dlg) {
17926        boolean result = startUser(userId, /* foreground */ true);
17927        dlg.dismiss();
17928        return result;
17929    }
17930
17931    /**
17932     * Refreshes the list of users related to the current user when either a
17933     * user switch happens or when a new related user is started in the
17934     * background.
17935     */
17936    private void updateCurrentProfileIdsLocked() {
17937        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17938                mCurrentUserId, false /* enabledOnly */);
17939        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17940        for (int i = 0; i < currentProfileIds.length; i++) {
17941            currentProfileIds[i] = profiles.get(i).id;
17942        }
17943        mCurrentProfileIds = currentProfileIds;
17944
17945        synchronized (mUserProfileGroupIdsSelfLocked) {
17946            mUserProfileGroupIdsSelfLocked.clear();
17947            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17948            for (int i = 0; i < users.size(); i++) {
17949                UserInfo user = users.get(i);
17950                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17951                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17952                }
17953            }
17954        }
17955    }
17956
17957    private Set getProfileIdsLocked(int userId) {
17958        Set userIds = new HashSet<Integer>();
17959        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17960                userId, false /* enabledOnly */);
17961        for (UserInfo user : profiles) {
17962            userIds.add(Integer.valueOf(user.id));
17963        }
17964        return userIds;
17965    }
17966
17967    @Override
17968    public boolean switchUser(final int userId) {
17969        String userName;
17970        synchronized (this) {
17971            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17972            if (userInfo == null) {
17973                Slog.w(TAG, "No user info for user #" + userId);
17974                return false;
17975            }
17976            if (userInfo.isManagedProfile()) {
17977                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17978                return false;
17979            }
17980            userName = userInfo.name;
17981            mTargetUserId = userId;
17982        }
17983        mHandler.removeMessages(START_USER_SWITCH_MSG);
17984        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17985        return true;
17986    }
17987
17988    private void showUserSwitchDialog(int userId, String userName) {
17989        // The dialog will show and then initiate the user switch by calling startUserInForeground
17990        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17991                true /* above system */);
17992        d.show();
17993    }
17994
17995    private boolean startUser(final int userId, final boolean foreground) {
17996        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17997                != PackageManager.PERMISSION_GRANTED) {
17998            String msg = "Permission Denial: switchUser() from pid="
17999                    + Binder.getCallingPid()
18000                    + ", uid=" + Binder.getCallingUid()
18001                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18002            Slog.w(TAG, msg);
18003            throw new SecurityException(msg);
18004        }
18005
18006        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18007
18008        final long ident = Binder.clearCallingIdentity();
18009        try {
18010            synchronized (this) {
18011                final int oldUserId = mCurrentUserId;
18012                if (oldUserId == userId) {
18013                    return true;
18014                }
18015
18016                mStackSupervisor.setLockTaskModeLocked(null, false);
18017
18018                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18019                if (userInfo == null) {
18020                    Slog.w(TAG, "No user info for user #" + userId);
18021                    return false;
18022                }
18023                if (foreground && userInfo.isManagedProfile()) {
18024                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18025                    return false;
18026                }
18027
18028                if (foreground) {
18029                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18030                            R.anim.screen_user_enter);
18031                }
18032
18033                boolean needStart = false;
18034
18035                // If the user we are switching to is not currently started, then
18036                // we need to start it now.
18037                if (mStartedUsers.get(userId) == null) {
18038                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18039                    updateStartedUserArrayLocked();
18040                    needStart = true;
18041                }
18042
18043                final Integer userIdInt = Integer.valueOf(userId);
18044                mUserLru.remove(userIdInt);
18045                mUserLru.add(userIdInt);
18046
18047                if (foreground) {
18048                    mCurrentUserId = userId;
18049                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18050                    updateCurrentProfileIdsLocked();
18051                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18052                    // Once the internal notion of the active user has switched, we lock the device
18053                    // with the option to show the user switcher on the keyguard.
18054                    mWindowManager.lockNow(null);
18055                } else {
18056                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18057                    updateCurrentProfileIdsLocked();
18058                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18059                    mUserLru.remove(currentUserIdInt);
18060                    mUserLru.add(currentUserIdInt);
18061                }
18062
18063                final UserStartedState uss = mStartedUsers.get(userId);
18064
18065                // Make sure user is in the started state.  If it is currently
18066                // stopping, we need to knock that off.
18067                if (uss.mState == UserStartedState.STATE_STOPPING) {
18068                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18069                    // so we can just fairly silently bring the user back from
18070                    // the almost-dead.
18071                    uss.mState = UserStartedState.STATE_RUNNING;
18072                    updateStartedUserArrayLocked();
18073                    needStart = true;
18074                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18075                    // This means ACTION_SHUTDOWN has been sent, so we will
18076                    // need to treat this as a new boot of the user.
18077                    uss.mState = UserStartedState.STATE_BOOTING;
18078                    updateStartedUserArrayLocked();
18079                    needStart = true;
18080                }
18081
18082                if (uss.mState == UserStartedState.STATE_BOOTING) {
18083                    // Booting up a new user, need to tell system services about it.
18084                    // Note that this is on the same handler as scheduling of broadcasts,
18085                    // which is important because it needs to go first.
18086                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18087                }
18088
18089                if (foreground) {
18090                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18091                            oldUserId));
18092                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18093                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18094                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18095                            oldUserId, userId, uss));
18096                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18097                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18098                }
18099
18100                if (needStart) {
18101                    // Send USER_STARTED broadcast
18102                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18103                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18104                            | Intent.FLAG_RECEIVER_FOREGROUND);
18105                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18106                    broadcastIntentLocked(null, null, intent,
18107                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18108                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18109                }
18110
18111                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18112                    if (userId != UserHandle.USER_OWNER) {
18113                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18114                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18115                        broadcastIntentLocked(null, null, intent, null,
18116                                new IIntentReceiver.Stub() {
18117                                    public void performReceive(Intent intent, int resultCode,
18118                                            String data, Bundle extras, boolean ordered,
18119                                            boolean sticky, int sendingUser) {
18120                                        onUserInitialized(uss, foreground, oldUserId, userId);
18121                                    }
18122                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18123                                true, false, MY_PID, Process.SYSTEM_UID,
18124                                userId);
18125                        uss.initializing = true;
18126                    } else {
18127                        getUserManagerLocked().makeInitialized(userInfo.id);
18128                    }
18129                }
18130
18131                if (foreground) {
18132                    if (!uss.initializing) {
18133                        moveUserToForeground(uss, oldUserId, userId);
18134                    }
18135                } else {
18136                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18137                }
18138
18139                if (needStart) {
18140                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18141                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18142                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18143                    broadcastIntentLocked(null, null, intent,
18144                            null, new IIntentReceiver.Stub() {
18145                                @Override
18146                                public void performReceive(Intent intent, int resultCode, String data,
18147                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18148                                        throws RemoteException {
18149                                }
18150                            }, 0, null, null,
18151                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18152                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18153                }
18154            }
18155        } finally {
18156            Binder.restoreCallingIdentity(ident);
18157        }
18158
18159        return true;
18160    }
18161
18162    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18163        long ident = Binder.clearCallingIdentity();
18164        try {
18165            Intent intent;
18166            if (oldUserId >= 0) {
18167                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18168                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18169                int count = profiles.size();
18170                for (int i = 0; i < count; i++) {
18171                    int profileUserId = profiles.get(i).id;
18172                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18173                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18174                            | Intent.FLAG_RECEIVER_FOREGROUND);
18175                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18176                    broadcastIntentLocked(null, null, intent,
18177                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18178                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18179                }
18180            }
18181            if (newUserId >= 0) {
18182                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18183                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18184                int count = profiles.size();
18185                for (int i = 0; i < count; i++) {
18186                    int profileUserId = profiles.get(i).id;
18187                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18188                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18189                            | Intent.FLAG_RECEIVER_FOREGROUND);
18190                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18191                    broadcastIntentLocked(null, null, intent,
18192                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18193                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18194                }
18195                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18196                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18197                        | Intent.FLAG_RECEIVER_FOREGROUND);
18198                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18199                broadcastIntentLocked(null, null, intent,
18200                        null, null, 0, null, null,
18201                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18202                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18203            }
18204        } finally {
18205            Binder.restoreCallingIdentity(ident);
18206        }
18207    }
18208
18209    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18210            final int newUserId) {
18211        final int N = mUserSwitchObservers.beginBroadcast();
18212        if (N > 0) {
18213            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18214                int mCount = 0;
18215                @Override
18216                public void sendResult(Bundle data) throws RemoteException {
18217                    synchronized (ActivityManagerService.this) {
18218                        if (mCurUserSwitchCallback == this) {
18219                            mCount++;
18220                            if (mCount == N) {
18221                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18222                            }
18223                        }
18224                    }
18225                }
18226            };
18227            synchronized (this) {
18228                uss.switching = true;
18229                mCurUserSwitchCallback = callback;
18230            }
18231            for (int i=0; i<N; i++) {
18232                try {
18233                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18234                            newUserId, callback);
18235                } catch (RemoteException e) {
18236                }
18237            }
18238        } else {
18239            synchronized (this) {
18240                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18241            }
18242        }
18243        mUserSwitchObservers.finishBroadcast();
18244    }
18245
18246    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18247        synchronized (this) {
18248            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18249            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18250        }
18251    }
18252
18253    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18254        mCurUserSwitchCallback = null;
18255        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18256        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18257                oldUserId, newUserId, uss));
18258    }
18259
18260    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18261        synchronized (this) {
18262            if (foreground) {
18263                moveUserToForeground(uss, oldUserId, newUserId);
18264            }
18265        }
18266
18267        completeSwitchAndInitalize(uss, newUserId, true, false);
18268    }
18269
18270    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18271        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18272        if (homeInFront) {
18273            startHomeActivityLocked(newUserId);
18274        } else {
18275            mStackSupervisor.resumeTopActivitiesLocked();
18276        }
18277        EventLogTags.writeAmSwitchUser(newUserId);
18278        getUserManagerLocked().userForeground(newUserId);
18279        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18280    }
18281
18282    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18283        completeSwitchAndInitalize(uss, newUserId, false, true);
18284    }
18285
18286    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18287            boolean clearInitializing, boolean clearSwitching) {
18288        boolean unfrozen = false;
18289        synchronized (this) {
18290            if (clearInitializing) {
18291                uss.initializing = false;
18292                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18293            }
18294            if (clearSwitching) {
18295                uss.switching = false;
18296            }
18297            if (!uss.switching && !uss.initializing) {
18298                mWindowManager.stopFreezingScreen();
18299                unfrozen = true;
18300            }
18301        }
18302        if (unfrozen) {
18303            final int N = mUserSwitchObservers.beginBroadcast();
18304            for (int i=0; i<N; i++) {
18305                try {
18306                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18307                } catch (RemoteException e) {
18308                }
18309            }
18310            mUserSwitchObservers.finishBroadcast();
18311        }
18312    }
18313
18314    void scheduleStartProfilesLocked() {
18315        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18316            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18317                    DateUtils.SECOND_IN_MILLIS);
18318        }
18319    }
18320
18321    void startProfilesLocked() {
18322        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18323        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18324                mCurrentUserId, false /* enabledOnly */);
18325        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18326        for (UserInfo user : profiles) {
18327            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18328                    && user.id != mCurrentUserId) {
18329                toStart.add(user);
18330            }
18331        }
18332        final int n = toStart.size();
18333        int i = 0;
18334        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18335            startUserInBackground(toStart.get(i).id);
18336        }
18337        if (i < n) {
18338            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18339        }
18340    }
18341
18342    void finishUserBoot(UserStartedState uss) {
18343        synchronized (this) {
18344            if (uss.mState == UserStartedState.STATE_BOOTING
18345                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18346                uss.mState = UserStartedState.STATE_RUNNING;
18347                final int userId = uss.mHandle.getIdentifier();
18348                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18349                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18350                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18351                broadcastIntentLocked(null, null, intent,
18352                        null, null, 0, null, null,
18353                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18354                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18355            }
18356        }
18357    }
18358
18359    void finishUserSwitch(UserStartedState uss) {
18360        synchronized (this) {
18361            finishUserBoot(uss);
18362
18363            startProfilesLocked();
18364
18365            int num = mUserLru.size();
18366            int i = 0;
18367            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18368                Integer oldUserId = mUserLru.get(i);
18369                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18370                if (oldUss == null) {
18371                    // Shouldn't happen, but be sane if it does.
18372                    mUserLru.remove(i);
18373                    num--;
18374                    continue;
18375                }
18376                if (oldUss.mState == UserStartedState.STATE_STOPPING
18377                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18378                    // This user is already stopping, doesn't count.
18379                    num--;
18380                    i++;
18381                    continue;
18382                }
18383                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18384                    // Owner and current can't be stopped, but count as running.
18385                    i++;
18386                    continue;
18387                }
18388                // This is a user to be stopped.
18389                stopUserLocked(oldUserId, null);
18390                num--;
18391                i++;
18392            }
18393        }
18394    }
18395
18396    @Override
18397    public int stopUser(final int userId, final IStopUserCallback callback) {
18398        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18399                != PackageManager.PERMISSION_GRANTED) {
18400            String msg = "Permission Denial: switchUser() from pid="
18401                    + Binder.getCallingPid()
18402                    + ", uid=" + Binder.getCallingUid()
18403                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18404            Slog.w(TAG, msg);
18405            throw new SecurityException(msg);
18406        }
18407        if (userId <= 0) {
18408            throw new IllegalArgumentException("Can't stop primary user " + userId);
18409        }
18410        synchronized (this) {
18411            return stopUserLocked(userId, callback);
18412        }
18413    }
18414
18415    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18416        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18417        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18418            return ActivityManager.USER_OP_IS_CURRENT;
18419        }
18420
18421        final UserStartedState uss = mStartedUsers.get(userId);
18422        if (uss == null) {
18423            // User is not started, nothing to do...  but we do need to
18424            // callback if requested.
18425            if (callback != null) {
18426                mHandler.post(new Runnable() {
18427                    @Override
18428                    public void run() {
18429                        try {
18430                            callback.userStopped(userId);
18431                        } catch (RemoteException e) {
18432                        }
18433                    }
18434                });
18435            }
18436            return ActivityManager.USER_OP_SUCCESS;
18437        }
18438
18439        if (callback != null) {
18440            uss.mStopCallbacks.add(callback);
18441        }
18442
18443        if (uss.mState != UserStartedState.STATE_STOPPING
18444                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18445            uss.mState = UserStartedState.STATE_STOPPING;
18446            updateStartedUserArrayLocked();
18447
18448            long ident = Binder.clearCallingIdentity();
18449            try {
18450                // We are going to broadcast ACTION_USER_STOPPING and then
18451                // once that is done send a final ACTION_SHUTDOWN and then
18452                // stop the user.
18453                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18454                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18455                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18456                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18457                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18458                // This is the result receiver for the final shutdown broadcast.
18459                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18460                    @Override
18461                    public void performReceive(Intent intent, int resultCode, String data,
18462                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18463                        finishUserStop(uss);
18464                    }
18465                };
18466                // This is the result receiver for the initial stopping broadcast.
18467                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18468                    @Override
18469                    public void performReceive(Intent intent, int resultCode, String data,
18470                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18471                        // On to the next.
18472                        synchronized (ActivityManagerService.this) {
18473                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18474                                // Whoops, we are being started back up.  Abort, abort!
18475                                return;
18476                            }
18477                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18478                        }
18479                        mBatteryStatsService.noteEvent(
18480                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18481                                Integer.toString(userId), userId);
18482                        mSystemServiceManager.stopUser(userId);
18483                        broadcastIntentLocked(null, null, shutdownIntent,
18484                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18485                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18486                    }
18487                };
18488                // Kick things off.
18489                broadcastIntentLocked(null, null, stoppingIntent,
18490                        null, stoppingReceiver, 0, null, null,
18491                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18492                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18493            } finally {
18494                Binder.restoreCallingIdentity(ident);
18495            }
18496        }
18497
18498        return ActivityManager.USER_OP_SUCCESS;
18499    }
18500
18501    void finishUserStop(UserStartedState uss) {
18502        final int userId = uss.mHandle.getIdentifier();
18503        boolean stopped;
18504        ArrayList<IStopUserCallback> callbacks;
18505        synchronized (this) {
18506            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18507            if (mStartedUsers.get(userId) != uss) {
18508                stopped = false;
18509            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18510                stopped = false;
18511            } else {
18512                stopped = true;
18513                // User can no longer run.
18514                mStartedUsers.remove(userId);
18515                mUserLru.remove(Integer.valueOf(userId));
18516                updateStartedUserArrayLocked();
18517
18518                // Clean up all state and processes associated with the user.
18519                // Kill all the processes for the user.
18520                forceStopUserLocked(userId, "finish user");
18521            }
18522
18523            // Explicitly remove the old information in mRecentTasks.
18524            removeRecentTasksForUserLocked(userId);
18525        }
18526
18527        for (int i=0; i<callbacks.size(); i++) {
18528            try {
18529                if (stopped) callbacks.get(i).userStopped(userId);
18530                else callbacks.get(i).userStopAborted(userId);
18531            } catch (RemoteException e) {
18532            }
18533        }
18534
18535        if (stopped) {
18536            mSystemServiceManager.cleanupUser(userId);
18537            synchronized (this) {
18538                mStackSupervisor.removeUserLocked(userId);
18539            }
18540        }
18541    }
18542
18543    @Override
18544    public UserInfo getCurrentUser() {
18545        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18546                != PackageManager.PERMISSION_GRANTED) && (
18547                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18548                != PackageManager.PERMISSION_GRANTED)) {
18549            String msg = "Permission Denial: getCurrentUser() from pid="
18550                    + Binder.getCallingPid()
18551                    + ", uid=" + Binder.getCallingUid()
18552                    + " requires " + INTERACT_ACROSS_USERS;
18553            Slog.w(TAG, msg);
18554            throw new SecurityException(msg);
18555        }
18556        synchronized (this) {
18557            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18558            return getUserManagerLocked().getUserInfo(userId);
18559        }
18560    }
18561
18562    int getCurrentUserIdLocked() {
18563        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18564    }
18565
18566    @Override
18567    public boolean isUserRunning(int userId, boolean orStopped) {
18568        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18569                != PackageManager.PERMISSION_GRANTED) {
18570            String msg = "Permission Denial: isUserRunning() from pid="
18571                    + Binder.getCallingPid()
18572                    + ", uid=" + Binder.getCallingUid()
18573                    + " requires " + INTERACT_ACROSS_USERS;
18574            Slog.w(TAG, msg);
18575            throw new SecurityException(msg);
18576        }
18577        synchronized (this) {
18578            return isUserRunningLocked(userId, orStopped);
18579        }
18580    }
18581
18582    boolean isUserRunningLocked(int userId, boolean orStopped) {
18583        UserStartedState state = mStartedUsers.get(userId);
18584        if (state == null) {
18585            return false;
18586        }
18587        if (orStopped) {
18588            return true;
18589        }
18590        return state.mState != UserStartedState.STATE_STOPPING
18591                && state.mState != UserStartedState.STATE_SHUTDOWN;
18592    }
18593
18594    @Override
18595    public int[] getRunningUserIds() {
18596        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18597                != PackageManager.PERMISSION_GRANTED) {
18598            String msg = "Permission Denial: isUserRunning() from pid="
18599                    + Binder.getCallingPid()
18600                    + ", uid=" + Binder.getCallingUid()
18601                    + " requires " + INTERACT_ACROSS_USERS;
18602            Slog.w(TAG, msg);
18603            throw new SecurityException(msg);
18604        }
18605        synchronized (this) {
18606            return mStartedUserArray;
18607        }
18608    }
18609
18610    private void updateStartedUserArrayLocked() {
18611        int num = 0;
18612        for (int i=0; i<mStartedUsers.size();  i++) {
18613            UserStartedState uss = mStartedUsers.valueAt(i);
18614            // This list does not include stopping users.
18615            if (uss.mState != UserStartedState.STATE_STOPPING
18616                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18617                num++;
18618            }
18619        }
18620        mStartedUserArray = new int[num];
18621        num = 0;
18622        for (int i=0; i<mStartedUsers.size();  i++) {
18623            UserStartedState uss = mStartedUsers.valueAt(i);
18624            if (uss.mState != UserStartedState.STATE_STOPPING
18625                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18626                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18627                num++;
18628            }
18629        }
18630    }
18631
18632    @Override
18633    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18634        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18635                != PackageManager.PERMISSION_GRANTED) {
18636            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18637                    + Binder.getCallingPid()
18638                    + ", uid=" + Binder.getCallingUid()
18639                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18640            Slog.w(TAG, msg);
18641            throw new SecurityException(msg);
18642        }
18643
18644        mUserSwitchObservers.register(observer);
18645    }
18646
18647    @Override
18648    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18649        mUserSwitchObservers.unregister(observer);
18650    }
18651
18652    private boolean userExists(int userId) {
18653        if (userId == 0) {
18654            return true;
18655        }
18656        UserManagerService ums = getUserManagerLocked();
18657        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18658    }
18659
18660    int[] getUsersLocked() {
18661        UserManagerService ums = getUserManagerLocked();
18662        return ums != null ? ums.getUserIds() : new int[] { 0 };
18663    }
18664
18665    UserManagerService getUserManagerLocked() {
18666        if (mUserManager == null) {
18667            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18668            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18669        }
18670        return mUserManager;
18671    }
18672
18673    private int applyUserId(int uid, int userId) {
18674        return UserHandle.getUid(userId, uid);
18675    }
18676
18677    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18678        if (info == null) return null;
18679        ApplicationInfo newInfo = new ApplicationInfo(info);
18680        newInfo.uid = applyUserId(info.uid, userId);
18681        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18682                + info.packageName;
18683        return newInfo;
18684    }
18685
18686    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18687        if (aInfo == null
18688                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18689            return aInfo;
18690        }
18691
18692        ActivityInfo info = new ActivityInfo(aInfo);
18693        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18694        return info;
18695    }
18696
18697    private final class LocalService extends ActivityManagerInternal {
18698        @Override
18699        public void goingToSleep() {
18700            ActivityManagerService.this.goingToSleep();
18701        }
18702
18703        @Override
18704        public void wakingUp() {
18705            ActivityManagerService.this.wakingUp();
18706        }
18707
18708        @Override
18709        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18710                String processName, String abiOverride, int uid, Runnable crashHandler) {
18711            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18712                    processName, abiOverride, uid, crashHandler);
18713        }
18714    }
18715
18716    /**
18717     * An implementation of IAppTask, that allows an app to manage its own tasks via
18718     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18719     * only the process that calls getAppTasks() can call the AppTask methods.
18720     */
18721    class AppTaskImpl extends IAppTask.Stub {
18722        private int mTaskId;
18723        private int mCallingUid;
18724
18725        public AppTaskImpl(int taskId, int callingUid) {
18726            mTaskId = taskId;
18727            mCallingUid = callingUid;
18728        }
18729
18730        private void checkCaller() {
18731            if (mCallingUid != Binder.getCallingUid()) {
18732                throw new SecurityException("Caller " + mCallingUid
18733                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18734            }
18735        }
18736
18737        @Override
18738        public void finishAndRemoveTask() {
18739            checkCaller();
18740
18741            synchronized (ActivityManagerService.this) {
18742                long origId = Binder.clearCallingIdentity();
18743                try {
18744                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18745                    if (tr == null) {
18746                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18747                    }
18748                    // Only kill the process if we are not a new document
18749                    int flags = tr.getBaseIntent().getFlags();
18750                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18751                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18752                    removeTaskByIdLocked(mTaskId,
18753                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18754                } finally {
18755                    Binder.restoreCallingIdentity(origId);
18756                }
18757            }
18758        }
18759
18760        @Override
18761        public ActivityManager.RecentTaskInfo getTaskInfo() {
18762            checkCaller();
18763
18764            synchronized (ActivityManagerService.this) {
18765                long origId = Binder.clearCallingIdentity();
18766                try {
18767                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18768                    if (tr == null) {
18769                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18770                    }
18771                    return createRecentTaskInfoFromTaskRecord(tr);
18772                } finally {
18773                    Binder.restoreCallingIdentity(origId);
18774                }
18775            }
18776        }
18777
18778        @Override
18779        public void moveToFront() {
18780            checkCaller();
18781
18782            final TaskRecord tr;
18783            synchronized (ActivityManagerService.this) {
18784                tr = recentTaskForIdLocked(mTaskId);
18785                if (tr == null) {
18786                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18787                }
18788                if (tr.getRootActivity() != null) {
18789                    long origId = Binder.clearCallingIdentity();
18790                    try {
18791                        moveTaskToFrontLocked(tr.taskId, 0, null);
18792                        return;
18793                    } finally {
18794                        Binder.restoreCallingIdentity(origId);
18795                    }
18796                }
18797            }
18798
18799            startActivityFromRecentsInner(tr.taskId, null);
18800        }
18801
18802        @Override
18803        public int startActivity(IBinder whoThread, String callingPackage,
18804                Intent intent, String resolvedType, Bundle options) {
18805            checkCaller();
18806
18807            int callingUser = UserHandle.getCallingUserId();
18808            TaskRecord tr;
18809            IApplicationThread appThread;
18810            synchronized (ActivityManagerService.this) {
18811                tr = recentTaskForIdLocked(mTaskId);
18812                if (tr == null) {
18813                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18814                }
18815                appThread = ApplicationThreadNative.asInterface(whoThread);
18816                if (appThread == null) {
18817                    throw new IllegalArgumentException("Bad app thread " + appThread);
18818                }
18819            }
18820            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18821                    resolvedType, null, null, null, null, 0, 0, null, null,
18822                    null, options, callingUser, null, tr);
18823        }
18824
18825        @Override
18826        public void setExcludeFromRecents(boolean exclude) {
18827            checkCaller();
18828
18829            synchronized (ActivityManagerService.this) {
18830                long origId = Binder.clearCallingIdentity();
18831                try {
18832                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18833                    if (tr == null) {
18834                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18835                    }
18836                    Intent intent = tr.getBaseIntent();
18837                    if (exclude) {
18838                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18839                    } else {
18840                        intent.setFlags(intent.getFlags()
18841                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18842                    }
18843                } finally {
18844                    Binder.restoreCallingIdentity(origId);
18845                }
18846            }
18847        }
18848    }
18849}
18850