ActivityManagerService.java revision 1df1473008c24487701c5bc15f39ed9f9697f421
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        ProcessRecord app;
2907        if (!isolated) {
2908            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2909        } else {
2910            // If this is an isolated process, it can't re-use an existing process.
2911            app = null;
2912        }
2913        // We don't have to do anything more if:
2914        // (1) There is an existing application record; and
2915        // (2) The caller doesn't think it is dead, OR there is no thread
2916        //     object attached to it so we know it couldn't have crashed; and
2917        // (3) There is a pid assigned to it, so it is either starting or
2918        //     already running.
2919        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2920                + " app=" + app + " knownToBeDead=" + knownToBeDead
2921                + " thread=" + (app != null ? app.thread : null)
2922                + " pid=" + (app != null ? app.pid : -1));
2923        if (app != null && app.pid > 0) {
2924            if (!knownToBeDead || app.thread == null) {
2925                // We already have the app running, or are waiting for it to
2926                // come up (we have a pid but not yet its thread), so keep it.
2927                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2928                // If this is a new package in the process, add the package to the list
2929                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2930                return app;
2931            }
2932
2933            // An application record is attached to a previous process,
2934            // clean it up now.
2935            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2936            Process.killProcessGroup(app.info.uid, app.pid);
2937            handleAppDiedLocked(app, true, true);
2938        }
2939
2940        String hostingNameStr = hostingName != null
2941                ? hostingName.flattenToShortString() : null;
2942
2943        if (!isolated) {
2944            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2945                // If we are in the background, then check to see if this process
2946                // is bad.  If so, we will just silently fail.
2947                if (mBadProcesses.get(info.processName, info.uid) != null) {
2948                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2949                            + "/" + info.processName);
2950                    return null;
2951                }
2952            } else {
2953                // When the user is explicitly starting a process, then clear its
2954                // crash count so that we won't make it bad until they see at
2955                // least one crash dialog again, and make the process good again
2956                // if it had been bad.
2957                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2958                        + "/" + info.processName);
2959                mProcessCrashTimes.remove(info.processName, info.uid);
2960                if (mBadProcesses.get(info.processName, info.uid) != null) {
2961                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2962                            UserHandle.getUserId(info.uid), info.uid,
2963                            info.processName);
2964                    mBadProcesses.remove(info.processName, info.uid);
2965                    if (app != null) {
2966                        app.bad = false;
2967                    }
2968                }
2969            }
2970        }
2971
2972        if (app == null) {
2973            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2974            app.crashHandler = crashHandler;
2975            if (app == null) {
2976                Slog.w(TAG, "Failed making new process record for "
2977                        + processName + "/" + info.uid + " isolated=" + isolated);
2978                return null;
2979            }
2980            mProcessNames.put(processName, app.uid, app);
2981            if (isolated) {
2982                mIsolatedProcesses.put(app.uid, app);
2983            }
2984        } else {
2985            // If this is a new package in the process, add the package to the list
2986            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2987        }
2988
2989        // If the system is not ready yet, then hold off on starting this
2990        // process until it is.
2991        if (!mProcessesReady
2992                && !isAllowedWhileBooting(info)
2993                && !allowWhileBooting) {
2994            if (!mProcessesOnHold.contains(app)) {
2995                mProcessesOnHold.add(app);
2996            }
2997            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2998            return app;
2999        }
3000
3001        startProcessLocked(
3002                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3003        return (app.pid != 0) ? app : null;
3004    }
3005
3006    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3007        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3008    }
3009
3010    private final void startProcessLocked(ProcessRecord app,
3011            String hostingType, String hostingNameStr) {
3012        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3013                null /* entryPoint */, null /* entryPointArgs */);
3014    }
3015
3016    private final void startProcessLocked(ProcessRecord app, String hostingType,
3017            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3018        if (app.pid > 0 && app.pid != MY_PID) {
3019            synchronized (mPidsSelfLocked) {
3020                mPidsSelfLocked.remove(app.pid);
3021                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3022            }
3023            app.setPid(0);
3024        }
3025
3026        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3027                "startProcessLocked removing on hold: " + app);
3028        mProcessesOnHold.remove(app);
3029
3030        updateCpuStats();
3031
3032        try {
3033            int uid = app.uid;
3034
3035            int[] gids = null;
3036            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3037            if (!app.isolated) {
3038                int[] permGids = null;
3039                try {
3040                    final PackageManager pm = mContext.getPackageManager();
3041                    permGids = pm.getPackageGids(app.info.packageName);
3042
3043                    if (Environment.isExternalStorageEmulated()) {
3044                        if (pm.checkPermission(
3045                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3046                                app.info.packageName) == PERMISSION_GRANTED) {
3047                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3048                        } else {
3049                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3050                        }
3051                    }
3052                } catch (PackageManager.NameNotFoundException e) {
3053                    Slog.w(TAG, "Unable to retrieve gids", e);
3054                }
3055
3056                /*
3057                 * Add shared application and profile GIDs so applications can share some
3058                 * resources like shared libraries and access user-wide resources
3059                 */
3060                if (permGids == null) {
3061                    gids = new int[2];
3062                } else {
3063                    gids = new int[permGids.length + 2];
3064                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3065                }
3066                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3067                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3068            }
3069            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3070                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3071                        && mTopComponent != null
3072                        && app.processName.equals(mTopComponent.getPackageName())) {
3073                    uid = 0;
3074                }
3075                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3076                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3077                    uid = 0;
3078                }
3079            }
3080            int debugFlags = 0;
3081            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3082                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3083                // Also turn on CheckJNI for debuggable apps. It's quite
3084                // awkward to turn on otherwise.
3085                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3086            }
3087            // Run the app in safe mode if its manifest requests so or the
3088            // system is booted in safe mode.
3089            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3090                mSafeMode == true) {
3091                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3092            }
3093            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3094                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3095            }
3096            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3097                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3098            }
3099            if ("1".equals(SystemProperties.get("debug.assert"))) {
3100                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3101            }
3102
3103            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3104            if (requiredAbi == null) {
3105                requiredAbi = Build.SUPPORTED_ABIS[0];
3106            }
3107
3108            // Start the process.  It will either succeed and return a result containing
3109            // the PID of the new process, or else throw a RuntimeException.
3110            boolean isActivityProcess = (entryPoint == null);
3111            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3112            Process.ProcessStartResult startResult = Process.start(entryPoint,
3113                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3114                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3115
3116            if (app.isolated) {
3117                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3118            }
3119            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3120
3121            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3122                    UserHandle.getUserId(uid), startResult.pid, uid,
3123                    app.processName, hostingType,
3124                    hostingNameStr != null ? hostingNameStr : "");
3125
3126            if (app.persistent) {
3127                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3128            }
3129
3130            StringBuilder buf = mStringBuilder;
3131            buf.setLength(0);
3132            buf.append("Start proc ");
3133            buf.append(app.processName);
3134            if (!isActivityProcess) {
3135                buf.append(" [");
3136                buf.append(entryPoint);
3137                buf.append("]");
3138            }
3139            buf.append(" for ");
3140            buf.append(hostingType);
3141            if (hostingNameStr != null) {
3142                buf.append(" ");
3143                buf.append(hostingNameStr);
3144            }
3145            buf.append(": pid=");
3146            buf.append(startResult.pid);
3147            buf.append(" uid=");
3148            buf.append(uid);
3149            buf.append(" gids={");
3150            if (gids != null) {
3151                for (int gi=0; gi<gids.length; gi++) {
3152                    if (gi != 0) buf.append(", ");
3153                    buf.append(gids[gi]);
3154
3155                }
3156            }
3157            buf.append("}");
3158            if (requiredAbi != null) {
3159                buf.append(" abi=");
3160                buf.append(requiredAbi);
3161            }
3162            Slog.i(TAG, buf.toString());
3163            app.setPid(startResult.pid);
3164            app.usingWrapper = startResult.usingWrapper;
3165            app.removed = false;
3166            app.killedByAm = false;
3167            synchronized (mPidsSelfLocked) {
3168                this.mPidsSelfLocked.put(startResult.pid, app);
3169                if (isActivityProcess) {
3170                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3171                    msg.obj = app;
3172                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3173                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3174                }
3175            }
3176        } catch (RuntimeException e) {
3177            // XXX do better error recovery.
3178            app.setPid(0);
3179            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3180            if (app.isolated) {
3181                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3182            }
3183            Slog.e(TAG, "Failure starting process " + app.processName, e);
3184        }
3185    }
3186
3187    void updateUsageStats(ActivityRecord component, boolean resumed) {
3188        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3189        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3190        if (resumed) {
3191            if (mUsageStatsService != null) {
3192                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3193                        System.currentTimeMillis(),
3194                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3195            }
3196            synchronized (stats) {
3197                stats.noteActivityResumedLocked(component.app.uid);
3198            }
3199        } else {
3200            if (mUsageStatsService != null) {
3201                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3202                        System.currentTimeMillis(),
3203                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3204            }
3205            synchronized (stats) {
3206                stats.noteActivityPausedLocked(component.app.uid);
3207            }
3208        }
3209    }
3210
3211    Intent getHomeIntent() {
3212        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3213        intent.setComponent(mTopComponent);
3214        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3215            intent.addCategory(Intent.CATEGORY_HOME);
3216        }
3217        return intent;
3218    }
3219
3220    boolean startHomeActivityLocked(int userId) {
3221        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3222                && mTopAction == null) {
3223            // We are running in factory test mode, but unable to find
3224            // the factory test app, so just sit around displaying the
3225            // error message and don't try to start anything.
3226            return false;
3227        }
3228        Intent intent = getHomeIntent();
3229        ActivityInfo aInfo =
3230            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3231        if (aInfo != null) {
3232            intent.setComponent(new ComponentName(
3233                    aInfo.applicationInfo.packageName, aInfo.name));
3234            // Don't do this if the home app is currently being
3235            // instrumented.
3236            aInfo = new ActivityInfo(aInfo);
3237            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3238            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3239                    aInfo.applicationInfo.uid, true);
3240            if (app == null || app.instrumentationClass == null) {
3241                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3242                mStackSupervisor.startHomeActivity(intent, aInfo);
3243            }
3244        }
3245
3246        return true;
3247    }
3248
3249    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3250        ActivityInfo ai = null;
3251        ComponentName comp = intent.getComponent();
3252        try {
3253            if (comp != null) {
3254                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3255            } else {
3256                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3257                        intent,
3258                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3259                            flags, userId);
3260
3261                if (info != null) {
3262                    ai = info.activityInfo;
3263                }
3264            }
3265        } catch (RemoteException e) {
3266            // ignore
3267        }
3268
3269        return ai;
3270    }
3271
3272    /**
3273     * Starts the "new version setup screen" if appropriate.
3274     */
3275    void startSetupActivityLocked() {
3276        // Only do this once per boot.
3277        if (mCheckedForSetup) {
3278            return;
3279        }
3280
3281        // We will show this screen if the current one is a different
3282        // version than the last one shown, and we are not running in
3283        // low-level factory test mode.
3284        final ContentResolver resolver = mContext.getContentResolver();
3285        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3286                Settings.Global.getInt(resolver,
3287                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3288            mCheckedForSetup = true;
3289
3290            // See if we should be showing the platform update setup UI.
3291            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3292            List<ResolveInfo> ris = mContext.getPackageManager()
3293                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3294
3295            // We don't allow third party apps to replace this.
3296            ResolveInfo ri = null;
3297            for (int i=0; ris != null && i<ris.size(); i++) {
3298                if ((ris.get(i).activityInfo.applicationInfo.flags
3299                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3300                    ri = ris.get(i);
3301                    break;
3302                }
3303            }
3304
3305            if (ri != null) {
3306                String vers = ri.activityInfo.metaData != null
3307                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3308                        : null;
3309                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3310                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3311                            Intent.METADATA_SETUP_VERSION);
3312                }
3313                String lastVers = Settings.Secure.getString(
3314                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3315                if (vers != null && !vers.equals(lastVers)) {
3316                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3317                    intent.setComponent(new ComponentName(
3318                            ri.activityInfo.packageName, ri.activityInfo.name));
3319                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3320                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3321                            null);
3322                }
3323            }
3324        }
3325    }
3326
3327    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3328        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3329    }
3330
3331    void enforceNotIsolatedCaller(String caller) {
3332        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3333            throw new SecurityException("Isolated process not allowed to call " + caller);
3334        }
3335    }
3336
3337    @Override
3338    public int getFrontActivityScreenCompatMode() {
3339        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3340        synchronized (this) {
3341            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3342        }
3343    }
3344
3345    @Override
3346    public void setFrontActivityScreenCompatMode(int mode) {
3347        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3348                "setFrontActivityScreenCompatMode");
3349        synchronized (this) {
3350            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3351        }
3352    }
3353
3354    @Override
3355    public int getPackageScreenCompatMode(String packageName) {
3356        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3357        synchronized (this) {
3358            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3359        }
3360    }
3361
3362    @Override
3363    public void setPackageScreenCompatMode(String packageName, int mode) {
3364        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3365                "setPackageScreenCompatMode");
3366        synchronized (this) {
3367            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3368        }
3369    }
3370
3371    @Override
3372    public boolean getPackageAskScreenCompat(String packageName) {
3373        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3374        synchronized (this) {
3375            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3376        }
3377    }
3378
3379    @Override
3380    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3381        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3382                "setPackageAskScreenCompat");
3383        synchronized (this) {
3384            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3385        }
3386    }
3387
3388    private void dispatchProcessesChanged() {
3389        int N;
3390        synchronized (this) {
3391            N = mPendingProcessChanges.size();
3392            if (mActiveProcessChanges.length < N) {
3393                mActiveProcessChanges = new ProcessChangeItem[N];
3394            }
3395            mPendingProcessChanges.toArray(mActiveProcessChanges);
3396            mAvailProcessChanges.addAll(mPendingProcessChanges);
3397            mPendingProcessChanges.clear();
3398            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3399        }
3400
3401        int i = mProcessObservers.beginBroadcast();
3402        while (i > 0) {
3403            i--;
3404            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3405            if (observer != null) {
3406                try {
3407                    for (int j=0; j<N; j++) {
3408                        ProcessChangeItem item = mActiveProcessChanges[j];
3409                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3410                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3411                                    + item.pid + " uid=" + item.uid + ": "
3412                                    + item.foregroundActivities);
3413                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3414                                    item.foregroundActivities);
3415                        }
3416                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3417                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3418                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3419                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3420                        }
3421                    }
3422                } catch (RemoteException e) {
3423                }
3424            }
3425        }
3426        mProcessObservers.finishBroadcast();
3427    }
3428
3429    private void dispatchProcessDied(int pid, int uid) {
3430        int i = mProcessObservers.beginBroadcast();
3431        while (i > 0) {
3432            i--;
3433            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3434            if (observer != null) {
3435                try {
3436                    observer.onProcessDied(pid, uid);
3437                } catch (RemoteException e) {
3438                }
3439            }
3440        }
3441        mProcessObservers.finishBroadcast();
3442    }
3443
3444    @Override
3445    public final int startActivity(IApplicationThread caller, String callingPackage,
3446            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3447            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3448        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3449            resultWho, requestCode, startFlags, profilerInfo, options,
3450            UserHandle.getCallingUserId());
3451    }
3452
3453    @Override
3454    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3455            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3456            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3457        enforceNotIsolatedCaller("startActivity");
3458        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3459                false, ALLOW_FULL_ONLY, "startActivity", null);
3460        // TODO: Switch to user app stacks here.
3461        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3462                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3463                profilerInfo, null, null, options, userId, null, null);
3464    }
3465
3466    @Override
3467    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3468            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3469            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3470
3471        // This is very dangerous -- it allows you to perform a start activity (including
3472        // permission grants) as any app that may launch one of your own activities.  So
3473        // we will only allow this to be done from activities that are part of the core framework,
3474        // and then only when they are running as the system.
3475        final ActivityRecord sourceRecord;
3476        final int targetUid;
3477        final String targetPackage;
3478        synchronized (this) {
3479            if (resultTo == null) {
3480                throw new SecurityException("Must be called from an activity");
3481            }
3482            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3483            if (sourceRecord == null) {
3484                throw new SecurityException("Called with bad activity token: " + resultTo);
3485            }
3486            if (!sourceRecord.info.packageName.equals("android")) {
3487                throw new SecurityException(
3488                        "Must be called from an activity that is declared in the android package");
3489            }
3490            if (sourceRecord.app == null) {
3491                throw new SecurityException("Called without a process attached to activity");
3492            }
3493            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3494                // This is still okay, as long as this activity is running under the
3495                // uid of the original calling activity.
3496                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3497                    throw new SecurityException(
3498                            "Calling activity in uid " + sourceRecord.app.uid
3499                                    + " must be system uid or original calling uid "
3500                                    + sourceRecord.launchedFromUid);
3501                }
3502            }
3503            targetUid = sourceRecord.launchedFromUid;
3504            targetPackage = sourceRecord.launchedFromPackage;
3505        }
3506
3507        // TODO: Switch to user app stacks here.
3508        try {
3509            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3510                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3511                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3512            return ret;
3513        } catch (SecurityException e) {
3514            // XXX need to figure out how to propagate to original app.
3515            // A SecurityException here is generally actually a fault of the original
3516            // calling activity (such as a fairly granting permissions), so propagate it
3517            // back to them.
3518            /*
3519            StringBuilder msg = new StringBuilder();
3520            msg.append("While launching");
3521            msg.append(intent.toString());
3522            msg.append(": ");
3523            msg.append(e.getMessage());
3524            */
3525            throw e;
3526        }
3527    }
3528
3529    @Override
3530    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3531            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3532            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3533        enforceNotIsolatedCaller("startActivityAndWait");
3534        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3535                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3536        WaitResult res = new WaitResult();
3537        // TODO: Switch to user app stacks here.
3538        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3539                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3540                options, userId, null, null);
3541        return res;
3542    }
3543
3544    @Override
3545    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3546            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3547            int startFlags, Configuration config, Bundle options, int userId) {
3548        enforceNotIsolatedCaller("startActivityWithConfig");
3549        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3550                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3551        // TODO: Switch to user app stacks here.
3552        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3553                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3554                null, null, config, options, userId, null, null);
3555        return ret;
3556    }
3557
3558    @Override
3559    public int startActivityIntentSender(IApplicationThread caller,
3560            IntentSender intent, Intent fillInIntent, String resolvedType,
3561            IBinder resultTo, String resultWho, int requestCode,
3562            int flagsMask, int flagsValues, Bundle options) {
3563        enforceNotIsolatedCaller("startActivityIntentSender");
3564        // Refuse possible leaked file descriptors
3565        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3566            throw new IllegalArgumentException("File descriptors passed in Intent");
3567        }
3568
3569        IIntentSender sender = intent.getTarget();
3570        if (!(sender instanceof PendingIntentRecord)) {
3571            throw new IllegalArgumentException("Bad PendingIntent object");
3572        }
3573
3574        PendingIntentRecord pir = (PendingIntentRecord)sender;
3575
3576        synchronized (this) {
3577            // If this is coming from the currently resumed activity, it is
3578            // effectively saying that app switches are allowed at this point.
3579            final ActivityStack stack = getFocusedStack();
3580            if (stack.mResumedActivity != null &&
3581                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3582                mAppSwitchesAllowedTime = 0;
3583            }
3584        }
3585        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3586                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3587        return ret;
3588    }
3589
3590    @Override
3591    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3592            Intent intent, String resolvedType, IVoiceInteractionSession session,
3593            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3594            Bundle options, int userId) {
3595        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3596                != PackageManager.PERMISSION_GRANTED) {
3597            String msg = "Permission Denial: startVoiceActivity() from pid="
3598                    + Binder.getCallingPid()
3599                    + ", uid=" + Binder.getCallingUid()
3600                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3601            Slog.w(TAG, msg);
3602            throw new SecurityException(msg);
3603        }
3604        if (session == null || interactor == null) {
3605            throw new NullPointerException("null session or interactor");
3606        }
3607        userId = handleIncomingUser(callingPid, callingUid, userId,
3608                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3609        // TODO: Switch to user app stacks here.
3610        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3611                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3612                null, options, userId, null, null);
3613    }
3614
3615    @Override
3616    public boolean startNextMatchingActivity(IBinder callingActivity,
3617            Intent intent, Bundle options) {
3618        // Refuse possible leaked file descriptors
3619        if (intent != null && intent.hasFileDescriptors() == true) {
3620            throw new IllegalArgumentException("File descriptors passed in Intent");
3621        }
3622
3623        synchronized (this) {
3624            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3625            if (r == null) {
3626                ActivityOptions.abort(options);
3627                return false;
3628            }
3629            if (r.app == null || r.app.thread == null) {
3630                // The caller is not running...  d'oh!
3631                ActivityOptions.abort(options);
3632                return false;
3633            }
3634            intent = new Intent(intent);
3635            // The caller is not allowed to change the data.
3636            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3637            // And we are resetting to find the next component...
3638            intent.setComponent(null);
3639
3640            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3641
3642            ActivityInfo aInfo = null;
3643            try {
3644                List<ResolveInfo> resolves =
3645                    AppGlobals.getPackageManager().queryIntentActivities(
3646                            intent, r.resolvedType,
3647                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3648                            UserHandle.getCallingUserId());
3649
3650                // Look for the original activity in the list...
3651                final int N = resolves != null ? resolves.size() : 0;
3652                for (int i=0; i<N; i++) {
3653                    ResolveInfo rInfo = resolves.get(i);
3654                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3655                            && rInfo.activityInfo.name.equals(r.info.name)) {
3656                        // We found the current one...  the next matching is
3657                        // after it.
3658                        i++;
3659                        if (i<N) {
3660                            aInfo = resolves.get(i).activityInfo;
3661                        }
3662                        if (debug) {
3663                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3664                                    + "/" + r.info.name);
3665                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3666                                    + "/" + aInfo.name);
3667                        }
3668                        break;
3669                    }
3670                }
3671            } catch (RemoteException e) {
3672            }
3673
3674            if (aInfo == null) {
3675                // Nobody who is next!
3676                ActivityOptions.abort(options);
3677                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3678                return false;
3679            }
3680
3681            intent.setComponent(new ComponentName(
3682                    aInfo.applicationInfo.packageName, aInfo.name));
3683            intent.setFlags(intent.getFlags()&~(
3684                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3685                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3686                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3687                    Intent.FLAG_ACTIVITY_NEW_TASK));
3688
3689            // Okay now we need to start the new activity, replacing the
3690            // currently running activity.  This is a little tricky because
3691            // we want to start the new one as if the current one is finished,
3692            // but not finish the current one first so that there is no flicker.
3693            // And thus...
3694            final boolean wasFinishing = r.finishing;
3695            r.finishing = true;
3696
3697            // Propagate reply information over to the new activity.
3698            final ActivityRecord resultTo = r.resultTo;
3699            final String resultWho = r.resultWho;
3700            final int requestCode = r.requestCode;
3701            r.resultTo = null;
3702            if (resultTo != null) {
3703                resultTo.removeResultsLocked(r, resultWho, requestCode);
3704            }
3705
3706            final long origId = Binder.clearCallingIdentity();
3707            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3708                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3709                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3710                    options, false, null, null, null);
3711            Binder.restoreCallingIdentity(origId);
3712
3713            r.finishing = wasFinishing;
3714            if (res != ActivityManager.START_SUCCESS) {
3715                return false;
3716            }
3717            return true;
3718        }
3719    }
3720
3721    @Override
3722    public final int startActivityFromRecents(int taskId, Bundle options) {
3723        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3724            String msg = "Permission Denial: startActivityFromRecents called without " +
3725                    START_TASKS_FROM_RECENTS;
3726            Slog.w(TAG, msg);
3727            throw new SecurityException(msg);
3728        }
3729        return startActivityFromRecentsInner(taskId, options);
3730    }
3731
3732    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3733        final TaskRecord task;
3734        final int callingUid;
3735        final String callingPackage;
3736        final Intent intent;
3737        final int userId;
3738        synchronized (this) {
3739            task = recentTaskForIdLocked(taskId);
3740            if (task == null) {
3741                throw new IllegalArgumentException("Task " + taskId + " not found.");
3742            }
3743            callingUid = task.mCallingUid;
3744            callingPackage = task.mCallingPackage;
3745            intent = task.intent;
3746            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3747            userId = task.userId;
3748        }
3749        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3750                options, userId, null, task);
3751    }
3752
3753    final int startActivityInPackage(int uid, String callingPackage,
3754            Intent intent, String resolvedType, IBinder resultTo,
3755            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3756            IActivityContainer container, TaskRecord inTask) {
3757
3758        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3759                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3760
3761        // TODO: Switch to user app stacks here.
3762        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3763                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3764                null, null, null, options, userId, container, inTask);
3765        return ret;
3766    }
3767
3768    @Override
3769    public final int startActivities(IApplicationThread caller, String callingPackage,
3770            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3771            int userId) {
3772        enforceNotIsolatedCaller("startActivities");
3773        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3774                false, ALLOW_FULL_ONLY, "startActivity", null);
3775        // TODO: Switch to user app stacks here.
3776        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3777                resolvedTypes, resultTo, options, userId);
3778        return ret;
3779    }
3780
3781    final int startActivitiesInPackage(int uid, String callingPackage,
3782            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3783            Bundle options, int userId) {
3784
3785        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3786                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3787        // TODO: Switch to user app stacks here.
3788        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3789                resultTo, options, userId);
3790        return ret;
3791    }
3792
3793    //explicitly remove thd old information in mRecentTasks when removing existing user.
3794    private void removeRecentTasksForUserLocked(int userId) {
3795        if(userId <= 0) {
3796            Slog.i(TAG, "Can't remove recent task on user " + userId);
3797            return;
3798        }
3799
3800        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3801            TaskRecord tr = mRecentTasks.get(i);
3802            if (tr.userId == userId) {
3803                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3804                        + " when finishing user" + userId);
3805                mRecentTasks.remove(i);
3806                tr.removedFromRecents(mTaskPersister);
3807            }
3808        }
3809
3810        // Remove tasks from persistent storage.
3811        mTaskPersister.wakeup(null, true);
3812    }
3813
3814    /**
3815     * Update the recent tasks lists: make sure tasks should still be here (their
3816     * applications / activities still exist), update their availability, fixup ordering
3817     * of affiliations.
3818     */
3819    void cleanupRecentTasksLocked(int userId) {
3820        if (mRecentTasks == null) {
3821            // Happens when called from the packagemanager broadcast before boot.
3822            return;
3823        }
3824
3825        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3826        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3827        final IPackageManager pm = AppGlobals.getPackageManager();
3828        final ActivityInfo dummyAct = new ActivityInfo();
3829        final ApplicationInfo dummyApp = new ApplicationInfo();
3830
3831        int N = mRecentTasks.size();
3832
3833        int[] users = userId == UserHandle.USER_ALL
3834                ? getUsersLocked() : new int[] { userId };
3835        for (int user : users) {
3836            for (int i = 0; i < N; i++) {
3837                TaskRecord task = mRecentTasks.get(i);
3838                if (task.userId != user) {
3839                    // Only look at tasks for the user ID of interest.
3840                    continue;
3841                }
3842                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3843                    // This situation is broken, and we should just get rid of it now.
3844                    mRecentTasks.remove(i);
3845                    task.removedFromRecents(mTaskPersister);
3846                    i--;
3847                    N--;
3848                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3849                    continue;
3850                }
3851                // Check whether this activity is currently available.
3852                if (task.realActivity != null) {
3853                    ActivityInfo ai = availActCache.get(task.realActivity);
3854                    if (ai == null) {
3855                        try {
3856                            ai = pm.getActivityInfo(task.realActivity,
3857                                    PackageManager.GET_UNINSTALLED_PACKAGES
3858                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3859                        } catch (RemoteException e) {
3860                            // Will never happen.
3861                            continue;
3862                        }
3863                        if (ai == null) {
3864                            ai = dummyAct;
3865                        }
3866                        availActCache.put(task.realActivity, ai);
3867                    }
3868                    if (ai == dummyAct) {
3869                        // This could be either because the activity no longer exists, or the
3870                        // app is temporarily gone.  For the former we want to remove the recents
3871                        // entry; for the latter we want to mark it as unavailable.
3872                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3873                        if (app == null) {
3874                            try {
3875                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3876                                        PackageManager.GET_UNINSTALLED_PACKAGES
3877                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3878                            } catch (RemoteException e) {
3879                                // Will never happen.
3880                                continue;
3881                            }
3882                            if (app == null) {
3883                                app = dummyApp;
3884                            }
3885                            availAppCache.put(task.realActivity.getPackageName(), app);
3886                        }
3887                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3888                            // Doesn't exist any more!  Good-bye.
3889                            mRecentTasks.remove(i);
3890                            task.removedFromRecents(mTaskPersister);
3891                            i--;
3892                            N--;
3893                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3894                            continue;
3895                        } else {
3896                            // Otherwise just not available for now.
3897                            if (task.isAvailable) {
3898                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3899                                        + task);
3900                            }
3901                            task.isAvailable = false;
3902                        }
3903                    } else {
3904                        if (!ai.enabled || !ai.applicationInfo.enabled
3905                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3906                            if (task.isAvailable) {
3907                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3908                                        + task + " (enabled=" + ai.enabled + "/"
3909                                        + ai.applicationInfo.enabled +  " flags="
3910                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3911                            }
3912                            task.isAvailable = false;
3913                        } else {
3914                            if (!task.isAvailable) {
3915                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3916                                        + task);
3917                            }
3918                            task.isAvailable = true;
3919                        }
3920                    }
3921                }
3922            }
3923        }
3924
3925        // Verify the affiliate chain for each task.
3926        for (int i = 0; i < N; ) {
3927            TaskRecord task = mRecentTasks.remove(i);
3928            if (mTmpRecents.contains(task)) {
3929                continue;
3930            }
3931            int affiliatedTaskId = task.mAffiliatedTaskId;
3932            while (true) {
3933                TaskRecord next = task.mNextAffiliate;
3934                if (next == null) {
3935                    break;
3936                }
3937                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3938                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3939                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3940                    task.setNextAffiliate(null);
3941                    if (next.mPrevAffiliate == task) {
3942                        next.setPrevAffiliate(null);
3943                    }
3944                    break;
3945                }
3946                if (next.mPrevAffiliate != task) {
3947                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3948                            next.mPrevAffiliate + " task=" + task);
3949                    next.setPrevAffiliate(null);
3950                    task.setNextAffiliate(null);
3951                    break;
3952                }
3953                if (!mRecentTasks.contains(next)) {
3954                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3955                    task.setNextAffiliate(null);
3956                    // We know that next.mPrevAffiliate is always task, from above, so clear
3957                    // its previous affiliate.
3958                    next.setPrevAffiliate(null);
3959                    break;
3960                }
3961                task = next;
3962            }
3963            // task is now the end of the list
3964            do {
3965                mRecentTasks.remove(task);
3966                mRecentTasks.add(i++, task);
3967                mTmpRecents.add(task);
3968                task.inRecents = true;
3969            } while ((task = task.mPrevAffiliate) != null);
3970        }
3971        mTmpRecents.clear();
3972        // mRecentTasks is now in sorted, affiliated order.
3973    }
3974
3975    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3976        int N = mRecentTasks.size();
3977        TaskRecord top = task;
3978        int topIndex = taskIndex;
3979        while (top.mNextAffiliate != null && topIndex > 0) {
3980            top = top.mNextAffiliate;
3981            topIndex--;
3982        }
3983        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3984                + topIndex + " from intial " + taskIndex);
3985        // Find the end of the chain, doing a sanity check along the way.
3986        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3987        int endIndex = topIndex;
3988        TaskRecord prev = top;
3989        while (endIndex < N) {
3990            TaskRecord cur = mRecentTasks.get(endIndex);
3991            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3992                    + endIndex + " " + cur);
3993            if (cur == top) {
3994                // Verify start of the chain.
3995                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3996                    Slog.wtf(TAG, "Bad chain @" + endIndex
3997                            + ": first task has next affiliate: " + prev);
3998                    sane = false;
3999                    break;
4000                }
4001            } else {
4002                // Verify middle of the chain's next points back to the one before.
4003                if (cur.mNextAffiliate != prev
4004                        || cur.mNextAffiliateTaskId != prev.taskId) {
4005                    Slog.wtf(TAG, "Bad chain @" + endIndex
4006                            + ": middle task " + cur + " @" + endIndex
4007                            + " has bad next affiliate "
4008                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4009                            + ", expected " + prev);
4010                    sane = false;
4011                    break;
4012                }
4013            }
4014            if (cur.mPrevAffiliateTaskId == -1) {
4015                // Chain ends here.
4016                if (cur.mPrevAffiliate != null) {
4017                    Slog.wtf(TAG, "Bad chain @" + endIndex
4018                            + ": last task " + cur + " has previous affiliate "
4019                            + cur.mPrevAffiliate);
4020                    sane = false;
4021                }
4022                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4023                break;
4024            } else {
4025                // Verify middle of the chain's prev points to a valid item.
4026                if (cur.mPrevAffiliate == null) {
4027                    Slog.wtf(TAG, "Bad chain @" + endIndex
4028                            + ": task " + cur + " has previous affiliate "
4029                            + cur.mPrevAffiliate + " but should be id "
4030                            + cur.mPrevAffiliate);
4031                    sane = false;
4032                    break;
4033                }
4034            }
4035            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4036                Slog.wtf(TAG, "Bad chain @" + endIndex
4037                        + ": task " + cur + " has affiliated id "
4038                        + cur.mAffiliatedTaskId + " but should be "
4039                        + task.mAffiliatedTaskId);
4040                sane = false;
4041                break;
4042            }
4043            prev = cur;
4044            endIndex++;
4045            if (endIndex >= N) {
4046                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4047                        + ": last task " + prev);
4048                sane = false;
4049                break;
4050            }
4051        }
4052        if (sane) {
4053            if (endIndex < taskIndex) {
4054                Slog.wtf(TAG, "Bad chain @" + endIndex
4055                        + ": did not extend to task " + task + " @" + taskIndex);
4056                sane = false;
4057            }
4058        }
4059        if (sane) {
4060            // All looks good, we can just move all of the affiliated tasks
4061            // to the top.
4062            for (int i=topIndex; i<=endIndex; i++) {
4063                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4064                        + " from " + i + " to " + (i-topIndex));
4065                TaskRecord cur = mRecentTasks.remove(i);
4066                mRecentTasks.add(i-topIndex, cur);
4067            }
4068            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4069                    + " to " + endIndex);
4070            return true;
4071        }
4072
4073        // Whoops, couldn't do it.
4074        return false;
4075    }
4076
4077    final void addRecentTaskLocked(TaskRecord task) {
4078        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4079                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4080
4081        int N = mRecentTasks.size();
4082        // Quick case: check if the top-most recent task is the same.
4083        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4084            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4085            return;
4086        }
4087        // Another quick case: check if this is part of a set of affiliated
4088        // tasks that are at the top.
4089        if (isAffiliated && N > 0 && task.inRecents
4090                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4091            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4092                    + " at top when adding " + task);
4093            return;
4094        }
4095        // Another quick case: never add voice sessions.
4096        if (task.voiceSession != null) {
4097            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4098            return;
4099        }
4100
4101        boolean needAffiliationFix = false;
4102
4103        // Slightly less quick case: the task is already in recents, so all we need
4104        // to do is move it.
4105        if (task.inRecents) {
4106            int taskIndex = mRecentTasks.indexOf(task);
4107            if (taskIndex >= 0) {
4108                if (!isAffiliated) {
4109                    // Simple case: this is not an affiliated task, so we just move it to the front.
4110                    mRecentTasks.remove(taskIndex);
4111                    mRecentTasks.add(0, task);
4112                    notifyTaskPersisterLocked(task, false);
4113                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4114                            + " from " + taskIndex);
4115                    return;
4116                } else {
4117                    // More complicated: need to keep all affiliated tasks together.
4118                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4119                        // All went well.
4120                        return;
4121                    }
4122
4123                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4124                    // everything and then go through our general path of adding a new task.
4125                    needAffiliationFix = true;
4126                }
4127            } else {
4128                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4129                needAffiliationFix = true;
4130            }
4131        }
4132
4133        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4134        trimRecentsForTask(task, true);
4135
4136        N = mRecentTasks.size();
4137        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4138            final TaskRecord tr = mRecentTasks.remove(N - 1);
4139            tr.removedFromRecents(mTaskPersister);
4140            N--;
4141        }
4142        task.inRecents = true;
4143        if (!isAffiliated || needAffiliationFix) {
4144            // If this is a simple non-affiliated task, or we had some failure trying to
4145            // handle it as part of an affilated task, then just place it at the top.
4146            mRecentTasks.add(0, task);
4147        } else if (isAffiliated) {
4148            // If this is a new affiliated task, then move all of the affiliated tasks
4149            // to the front and insert this new one.
4150            TaskRecord other = task.mNextAffiliate;
4151            if (other == null) {
4152                other = task.mPrevAffiliate;
4153            }
4154            if (other != null) {
4155                int otherIndex = mRecentTasks.indexOf(other);
4156                if (otherIndex >= 0) {
4157                    // Insert new task at appropriate location.
4158                    int taskIndex;
4159                    if (other == task.mNextAffiliate) {
4160                        // We found the index of our next affiliation, which is who is
4161                        // before us in the list, so add after that point.
4162                        taskIndex = otherIndex+1;
4163                    } else {
4164                        // We found the index of our previous affiliation, which is who is
4165                        // after us in the list, so add at their position.
4166                        taskIndex = otherIndex;
4167                    }
4168                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4169                            + taskIndex + ": " + task);
4170                    mRecentTasks.add(taskIndex, task);
4171
4172                    // Now move everything to the front.
4173                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4174                        // All went well.
4175                        return;
4176                    }
4177
4178                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4179                    // everything and then go through our general path of adding a new task.
4180                    needAffiliationFix = true;
4181                } else {
4182                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4183                            + other);
4184                    needAffiliationFix = true;
4185                }
4186            } else {
4187                if (DEBUG_RECENTS) Slog.d(TAG,
4188                        "addRecent: adding affiliated task without next/prev:" + task);
4189                needAffiliationFix = true;
4190            }
4191        }
4192        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4193
4194        if (needAffiliationFix) {
4195            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4196            cleanupRecentTasksLocked(task.userId);
4197        }
4198    }
4199
4200    /**
4201     * If needed, remove oldest existing entries in recents that are for the same kind
4202     * of task as the given one.
4203     */
4204    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4205        int N = mRecentTasks.size();
4206        final Intent intent = task.intent;
4207        final boolean document = intent != null && intent.isDocument();
4208
4209        int maxRecents = task.maxRecents - 1;
4210        for (int i=0; i<N; i++) {
4211            final TaskRecord tr = mRecentTasks.get(i);
4212            if (task != tr) {
4213                if (task.userId != tr.userId) {
4214                    continue;
4215                }
4216                if (i > MAX_RECENT_BITMAPS) {
4217                    tr.freeLastThumbnail();
4218                }
4219                final Intent trIntent = tr.intent;
4220                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4221                    (intent == null || !intent.filterEquals(trIntent))) {
4222                    continue;
4223                }
4224                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4225                if (document && trIsDocument) {
4226                    // These are the same document activity (not necessarily the same doc).
4227                    if (maxRecents > 0) {
4228                        --maxRecents;
4229                        continue;
4230                    }
4231                    // Hit the maximum number of documents for this task. Fall through
4232                    // and remove this document from recents.
4233                } else if (document || trIsDocument) {
4234                    // Only one of these is a document. Not the droid we're looking for.
4235                    continue;
4236                }
4237            }
4238
4239            if (!doTrim) {
4240                // If the caller is not actually asking for a trim, just tell them we reached
4241                // a point where the trim would happen.
4242                return i;
4243            }
4244
4245            // Either task and tr are the same or, their affinities match or their intents match
4246            // and neither of them is a document, or they are documents using the same activity
4247            // and their maxRecents has been reached.
4248            tr.disposeThumbnail();
4249            mRecentTasks.remove(i);
4250            if (task != tr) {
4251                tr.removedFromRecents(mTaskPersister);
4252            }
4253            i--;
4254            N--;
4255            if (task.intent == null) {
4256                // If the new recent task we are adding is not fully
4257                // specified, then replace it with the existing recent task.
4258                task = tr;
4259            }
4260            notifyTaskPersisterLocked(tr, false);
4261        }
4262
4263        return -1;
4264    }
4265
4266    @Override
4267    public void reportActivityFullyDrawn(IBinder token) {
4268        synchronized (this) {
4269            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4270            if (r == null) {
4271                return;
4272            }
4273            r.reportFullyDrawnLocked();
4274        }
4275    }
4276
4277    @Override
4278    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4279        synchronized (this) {
4280            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4281            if (r == null) {
4282                return;
4283            }
4284            final long origId = Binder.clearCallingIdentity();
4285            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4286            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4287                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4288            if (config != null) {
4289                r.frozenBeforeDestroy = true;
4290                if (!updateConfigurationLocked(config, r, false, false)) {
4291                    mStackSupervisor.resumeTopActivitiesLocked();
4292                }
4293            }
4294            Binder.restoreCallingIdentity(origId);
4295        }
4296    }
4297
4298    @Override
4299    public int getRequestedOrientation(IBinder token) {
4300        synchronized (this) {
4301            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4302            if (r == null) {
4303                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4304            }
4305            return mWindowManager.getAppOrientation(r.appToken);
4306        }
4307    }
4308
4309    /**
4310     * This is the internal entry point for handling Activity.finish().
4311     *
4312     * @param token The Binder token referencing the Activity we want to finish.
4313     * @param resultCode Result code, if any, from this Activity.
4314     * @param resultData Result data (Intent), if any, from this Activity.
4315     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4316     *            the root Activity in the task.
4317     *
4318     * @return Returns true if the activity successfully finished, or false if it is still running.
4319     */
4320    @Override
4321    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4322            boolean finishTask) {
4323        // Refuse possible leaked file descriptors
4324        if (resultData != null && resultData.hasFileDescriptors() == true) {
4325            throw new IllegalArgumentException("File descriptors passed in Intent");
4326        }
4327
4328        synchronized(this) {
4329            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4330            if (r == null) {
4331                return true;
4332            }
4333            // Keep track of the root activity of the task before we finish it
4334            TaskRecord tr = r.task;
4335            ActivityRecord rootR = tr.getRootActivity();
4336            // Do not allow task to finish in Lock Task mode.
4337            if (tr == mStackSupervisor.mLockTaskModeTask) {
4338                if (rootR == r) {
4339                    mStackSupervisor.showLockTaskToast();
4340                    return false;
4341                }
4342            }
4343            if (mController != null) {
4344                // Find the first activity that is not finishing.
4345                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4346                if (next != null) {
4347                    // ask watcher if this is allowed
4348                    boolean resumeOK = true;
4349                    try {
4350                        resumeOK = mController.activityResuming(next.packageName);
4351                    } catch (RemoteException e) {
4352                        mController = null;
4353                        Watchdog.getInstance().setActivityController(null);
4354                    }
4355
4356                    if (!resumeOK) {
4357                        return false;
4358                    }
4359                }
4360            }
4361            final long origId = Binder.clearCallingIdentity();
4362            try {
4363                boolean res;
4364                if (finishTask && r == rootR) {
4365                    // If requested, remove the task that is associated to this activity only if it
4366                    // was the root activity in the task.  The result code and data is ignored because
4367                    // we don't support returning them across task boundaries.
4368                    res = removeTaskByIdLocked(tr.taskId, 0);
4369                } else {
4370                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4371                            resultData, "app-request", true);
4372                }
4373                return res;
4374            } finally {
4375                Binder.restoreCallingIdentity(origId);
4376            }
4377        }
4378    }
4379
4380    @Override
4381    public final void finishHeavyWeightApp() {
4382        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4383                != PackageManager.PERMISSION_GRANTED) {
4384            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4385                    + Binder.getCallingPid()
4386                    + ", uid=" + Binder.getCallingUid()
4387                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4388            Slog.w(TAG, msg);
4389            throw new SecurityException(msg);
4390        }
4391
4392        synchronized(this) {
4393            if (mHeavyWeightProcess == null) {
4394                return;
4395            }
4396
4397            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4398                    mHeavyWeightProcess.activities);
4399            for (int i=0; i<activities.size(); i++) {
4400                ActivityRecord r = activities.get(i);
4401                if (!r.finishing) {
4402                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4403                            null, "finish-heavy", true);
4404                }
4405            }
4406
4407            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4408                    mHeavyWeightProcess.userId, 0));
4409            mHeavyWeightProcess = null;
4410        }
4411    }
4412
4413    @Override
4414    public void crashApplication(int uid, int initialPid, String packageName,
4415            String message) {
4416        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4417                != PackageManager.PERMISSION_GRANTED) {
4418            String msg = "Permission Denial: crashApplication() from pid="
4419                    + Binder.getCallingPid()
4420                    + ", uid=" + Binder.getCallingUid()
4421                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4422            Slog.w(TAG, msg);
4423            throw new SecurityException(msg);
4424        }
4425
4426        synchronized(this) {
4427            ProcessRecord proc = null;
4428
4429            // Figure out which process to kill.  We don't trust that initialPid
4430            // still has any relation to current pids, so must scan through the
4431            // list.
4432            synchronized (mPidsSelfLocked) {
4433                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4434                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4435                    if (p.uid != uid) {
4436                        continue;
4437                    }
4438                    if (p.pid == initialPid) {
4439                        proc = p;
4440                        break;
4441                    }
4442                    if (p.pkgList.containsKey(packageName)) {
4443                        proc = p;
4444                    }
4445                }
4446            }
4447
4448            if (proc == null) {
4449                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4450                        + " initialPid=" + initialPid
4451                        + " packageName=" + packageName);
4452                return;
4453            }
4454
4455            if (proc.thread != null) {
4456                if (proc.pid == Process.myPid()) {
4457                    Log.w(TAG, "crashApplication: trying to crash self!");
4458                    return;
4459                }
4460                long ident = Binder.clearCallingIdentity();
4461                try {
4462                    proc.thread.scheduleCrash(message);
4463                } catch (RemoteException e) {
4464                }
4465                Binder.restoreCallingIdentity(ident);
4466            }
4467        }
4468    }
4469
4470    @Override
4471    public final void finishSubActivity(IBinder token, String resultWho,
4472            int requestCode) {
4473        synchronized(this) {
4474            final long origId = Binder.clearCallingIdentity();
4475            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4476            if (r != null) {
4477                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4478            }
4479            Binder.restoreCallingIdentity(origId);
4480        }
4481    }
4482
4483    @Override
4484    public boolean finishActivityAffinity(IBinder token) {
4485        synchronized(this) {
4486            final long origId = Binder.clearCallingIdentity();
4487            try {
4488                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4489
4490                ActivityRecord rootR = r.task.getRootActivity();
4491                // Do not allow task to finish in Lock Task mode.
4492                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4493                    if (rootR == r) {
4494                        mStackSupervisor.showLockTaskToast();
4495                        return false;
4496                    }
4497                }
4498                boolean res = false;
4499                if (r != null) {
4500                    res = r.task.stack.finishActivityAffinityLocked(r);
4501                }
4502                return res;
4503            } finally {
4504                Binder.restoreCallingIdentity(origId);
4505            }
4506        }
4507    }
4508
4509    @Override
4510    public void finishVoiceTask(IVoiceInteractionSession session) {
4511        synchronized(this) {
4512            final long origId = Binder.clearCallingIdentity();
4513            try {
4514                mStackSupervisor.finishVoiceTask(session);
4515            } finally {
4516                Binder.restoreCallingIdentity(origId);
4517            }
4518        }
4519
4520    }
4521
4522    @Override
4523    public boolean releaseActivityInstance(IBinder token) {
4524        synchronized(this) {
4525            final long origId = Binder.clearCallingIdentity();
4526            try {
4527                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4528                if (r.task == null || r.task.stack == null) {
4529                    return false;
4530                }
4531                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4532            } finally {
4533                Binder.restoreCallingIdentity(origId);
4534            }
4535        }
4536    }
4537
4538    @Override
4539    public void releaseSomeActivities(IApplicationThread appInt) {
4540        synchronized(this) {
4541            final long origId = Binder.clearCallingIdentity();
4542            try {
4543                ProcessRecord app = getRecordForAppLocked(appInt);
4544                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4545            } finally {
4546                Binder.restoreCallingIdentity(origId);
4547            }
4548        }
4549    }
4550
4551    @Override
4552    public boolean willActivityBeVisible(IBinder token) {
4553        synchronized(this) {
4554            ActivityStack stack = ActivityRecord.getStackLocked(token);
4555            if (stack != null) {
4556                return stack.willActivityBeVisibleLocked(token);
4557            }
4558            return false;
4559        }
4560    }
4561
4562    @Override
4563    public void overridePendingTransition(IBinder token, String packageName,
4564            int enterAnim, int exitAnim) {
4565        synchronized(this) {
4566            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4567            if (self == null) {
4568                return;
4569            }
4570
4571            final long origId = Binder.clearCallingIdentity();
4572
4573            if (self.state == ActivityState.RESUMED
4574                    || self.state == ActivityState.PAUSING) {
4575                mWindowManager.overridePendingAppTransition(packageName,
4576                        enterAnim, exitAnim, null);
4577            }
4578
4579            Binder.restoreCallingIdentity(origId);
4580        }
4581    }
4582
4583    /**
4584     * Main function for removing an existing process from the activity manager
4585     * as a result of that process going away.  Clears out all connections
4586     * to the process.
4587     */
4588    private final void handleAppDiedLocked(ProcessRecord app,
4589            boolean restarting, boolean allowRestart) {
4590        int pid = app.pid;
4591        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4592        if (!restarting) {
4593            removeLruProcessLocked(app);
4594            if (pid > 0) {
4595                ProcessList.remove(pid);
4596            }
4597        }
4598
4599        if (mProfileProc == app) {
4600            clearProfilerLocked();
4601        }
4602
4603        // Remove this application's activities from active lists.
4604        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4605
4606        app.activities.clear();
4607
4608        if (app.instrumentationClass != null) {
4609            Slog.w(TAG, "Crash of app " + app.processName
4610                  + " running instrumentation " + app.instrumentationClass);
4611            Bundle info = new Bundle();
4612            info.putString("shortMsg", "Process crashed.");
4613            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4614        }
4615
4616        if (!restarting) {
4617            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4618                // If there was nothing to resume, and we are not already
4619                // restarting this process, but there is a visible activity that
4620                // is hosted by the process...  then make sure all visible
4621                // activities are running, taking care of restarting this
4622                // process.
4623                if (hasVisibleActivities) {
4624                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4625                }
4626            }
4627        }
4628    }
4629
4630    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4631        IBinder threadBinder = thread.asBinder();
4632        // Find the application record.
4633        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4634            ProcessRecord rec = mLruProcesses.get(i);
4635            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4636                return i;
4637            }
4638        }
4639        return -1;
4640    }
4641
4642    final ProcessRecord getRecordForAppLocked(
4643            IApplicationThread thread) {
4644        if (thread == null) {
4645            return null;
4646        }
4647
4648        int appIndex = getLRURecordIndexForAppLocked(thread);
4649        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4650    }
4651
4652    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4653        // If there are no longer any background processes running,
4654        // and the app that died was not running instrumentation,
4655        // then tell everyone we are now low on memory.
4656        boolean haveBg = false;
4657        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4658            ProcessRecord rec = mLruProcesses.get(i);
4659            if (rec.thread != null
4660                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4661                haveBg = true;
4662                break;
4663            }
4664        }
4665
4666        if (!haveBg) {
4667            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4668            if (doReport) {
4669                long now = SystemClock.uptimeMillis();
4670                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4671                    doReport = false;
4672                } else {
4673                    mLastMemUsageReportTime = now;
4674                }
4675            }
4676            final ArrayList<ProcessMemInfo> memInfos
4677                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4678            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4679            long now = SystemClock.uptimeMillis();
4680            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4681                ProcessRecord rec = mLruProcesses.get(i);
4682                if (rec == dyingProc || rec.thread == null) {
4683                    continue;
4684                }
4685                if (doReport) {
4686                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4687                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4688                }
4689                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4690                    // The low memory report is overriding any current
4691                    // state for a GC request.  Make sure to do
4692                    // heavy/important/visible/foreground processes first.
4693                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4694                        rec.lastRequestedGc = 0;
4695                    } else {
4696                        rec.lastRequestedGc = rec.lastLowMemory;
4697                    }
4698                    rec.reportLowMemory = true;
4699                    rec.lastLowMemory = now;
4700                    mProcessesToGc.remove(rec);
4701                    addProcessToGcListLocked(rec);
4702                }
4703            }
4704            if (doReport) {
4705                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4706                mHandler.sendMessage(msg);
4707            }
4708            scheduleAppGcsLocked();
4709        }
4710    }
4711
4712    final void appDiedLocked(ProcessRecord app) {
4713       appDiedLocked(app, app.pid, app.thread);
4714    }
4715
4716    final void appDiedLocked(ProcessRecord app, int pid,
4717            IApplicationThread thread) {
4718
4719        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4720        synchronized (stats) {
4721            stats.noteProcessDiedLocked(app.info.uid, pid);
4722        }
4723
4724        Process.killProcessGroup(app.info.uid, pid);
4725
4726        // Clean up already done if the process has been re-started.
4727        if (app.pid == pid && app.thread != null &&
4728                app.thread.asBinder() == thread.asBinder()) {
4729            boolean doLowMem = app.instrumentationClass == null;
4730            boolean doOomAdj = doLowMem;
4731            if (!app.killedByAm) {
4732                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4733                        + ") has died.");
4734                mAllowLowerMemLevel = true;
4735            } else {
4736                // Note that we always want to do oom adj to update our state with the
4737                // new number of procs.
4738                mAllowLowerMemLevel = false;
4739                doLowMem = false;
4740            }
4741            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4742            if (DEBUG_CLEANUP) Slog.v(
4743                TAG, "Dying app: " + app + ", pid: " + pid
4744                + ", thread: " + thread.asBinder());
4745            handleAppDiedLocked(app, false, true);
4746
4747            if (doOomAdj) {
4748                updateOomAdjLocked();
4749            }
4750            if (doLowMem) {
4751                doLowMemReportIfNeededLocked(app);
4752            }
4753        } else if (app.pid != pid) {
4754            // A new process has already been started.
4755            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4756                    + ") has died and restarted (pid " + app.pid + ").");
4757            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4758        } else if (DEBUG_PROCESSES) {
4759            Slog.d(TAG, "Received spurious death notification for thread "
4760                    + thread.asBinder());
4761        }
4762    }
4763
4764    /**
4765     * If a stack trace dump file is configured, dump process stack traces.
4766     * @param clearTraces causes the dump file to be erased prior to the new
4767     *    traces being written, if true; when false, the new traces will be
4768     *    appended to any existing file content.
4769     * @param firstPids of dalvik VM processes to dump stack traces for first
4770     * @param lastPids of dalvik VM processes to dump stack traces for last
4771     * @param nativeProcs optional list of native process names to dump stack crawls
4772     * @return file containing stack traces, or null if no dump file is configured
4773     */
4774    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4775            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4776        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4777        if (tracesPath == null || tracesPath.length() == 0) {
4778            return null;
4779        }
4780
4781        File tracesFile = new File(tracesPath);
4782        try {
4783            File tracesDir = tracesFile.getParentFile();
4784            if (!tracesDir.exists()) {
4785                tracesFile.mkdirs();
4786                if (!SELinux.restorecon(tracesDir)) {
4787                    return null;
4788                }
4789            }
4790            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4791
4792            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4793            tracesFile.createNewFile();
4794            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4795        } catch (IOException e) {
4796            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4797            return null;
4798        }
4799
4800        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4801        return tracesFile;
4802    }
4803
4804    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4805            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4806        // Use a FileObserver to detect when traces finish writing.
4807        // The order of traces is considered important to maintain for legibility.
4808        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4809            @Override
4810            public synchronized void onEvent(int event, String path) { notify(); }
4811        };
4812
4813        try {
4814            observer.startWatching();
4815
4816            // First collect all of the stacks of the most important pids.
4817            if (firstPids != null) {
4818                try {
4819                    int num = firstPids.size();
4820                    for (int i = 0; i < num; i++) {
4821                        synchronized (observer) {
4822                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4823                            observer.wait(200);  // Wait for write-close, give up after 200msec
4824                        }
4825                    }
4826                } catch (InterruptedException e) {
4827                    Log.wtf(TAG, e);
4828                }
4829            }
4830
4831            // Next collect the stacks of the native pids
4832            if (nativeProcs != null) {
4833                int[] pids = Process.getPidsForCommands(nativeProcs);
4834                if (pids != null) {
4835                    for (int pid : pids) {
4836                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4837                    }
4838                }
4839            }
4840
4841            // Lastly, measure CPU usage.
4842            if (processCpuTracker != null) {
4843                processCpuTracker.init();
4844                System.gc();
4845                processCpuTracker.update();
4846                try {
4847                    synchronized (processCpuTracker) {
4848                        processCpuTracker.wait(500); // measure over 1/2 second.
4849                    }
4850                } catch (InterruptedException e) {
4851                }
4852                processCpuTracker.update();
4853
4854                // We'll take the stack crawls of just the top apps using CPU.
4855                final int N = processCpuTracker.countWorkingStats();
4856                int numProcs = 0;
4857                for (int i=0; i<N && numProcs<5; i++) {
4858                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4859                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4860                        numProcs++;
4861                        try {
4862                            synchronized (observer) {
4863                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4864                                observer.wait(200);  // Wait for write-close, give up after 200msec
4865                            }
4866                        } catch (InterruptedException e) {
4867                            Log.wtf(TAG, e);
4868                        }
4869
4870                    }
4871                }
4872            }
4873        } finally {
4874            observer.stopWatching();
4875        }
4876    }
4877
4878    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4879        if (true || IS_USER_BUILD) {
4880            return;
4881        }
4882        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4883        if (tracesPath == null || tracesPath.length() == 0) {
4884            return;
4885        }
4886
4887        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4888        StrictMode.allowThreadDiskWrites();
4889        try {
4890            final File tracesFile = new File(tracesPath);
4891            final File tracesDir = tracesFile.getParentFile();
4892            final File tracesTmp = new File(tracesDir, "__tmp__");
4893            try {
4894                if (!tracesDir.exists()) {
4895                    tracesFile.mkdirs();
4896                    if (!SELinux.restorecon(tracesDir.getPath())) {
4897                        return;
4898                    }
4899                }
4900                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4901
4902                if (tracesFile.exists()) {
4903                    tracesTmp.delete();
4904                    tracesFile.renameTo(tracesTmp);
4905                }
4906                StringBuilder sb = new StringBuilder();
4907                Time tobj = new Time();
4908                tobj.set(System.currentTimeMillis());
4909                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4910                sb.append(": ");
4911                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4912                sb.append(" since ");
4913                sb.append(msg);
4914                FileOutputStream fos = new FileOutputStream(tracesFile);
4915                fos.write(sb.toString().getBytes());
4916                if (app == null) {
4917                    fos.write("\n*** No application process!".getBytes());
4918                }
4919                fos.close();
4920                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4921            } catch (IOException e) {
4922                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4923                return;
4924            }
4925
4926            if (app != null) {
4927                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4928                firstPids.add(app.pid);
4929                dumpStackTraces(tracesPath, firstPids, null, null, null);
4930            }
4931
4932            File lastTracesFile = null;
4933            File curTracesFile = null;
4934            for (int i=9; i>=0; i--) {
4935                String name = String.format(Locale.US, "slow%02d.txt", i);
4936                curTracesFile = new File(tracesDir, name);
4937                if (curTracesFile.exists()) {
4938                    if (lastTracesFile != null) {
4939                        curTracesFile.renameTo(lastTracesFile);
4940                    } else {
4941                        curTracesFile.delete();
4942                    }
4943                }
4944                lastTracesFile = curTracesFile;
4945            }
4946            tracesFile.renameTo(curTracesFile);
4947            if (tracesTmp.exists()) {
4948                tracesTmp.renameTo(tracesFile);
4949            }
4950        } finally {
4951            StrictMode.setThreadPolicy(oldPolicy);
4952        }
4953    }
4954
4955    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4956            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4957        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4958        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4959
4960        if (mController != null) {
4961            try {
4962                // 0 == continue, -1 = kill process immediately
4963                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4964                if (res < 0 && app.pid != MY_PID) {
4965                    app.kill("anr", true);
4966                }
4967            } catch (RemoteException e) {
4968                mController = null;
4969                Watchdog.getInstance().setActivityController(null);
4970            }
4971        }
4972
4973        long anrTime = SystemClock.uptimeMillis();
4974        if (MONITOR_CPU_USAGE) {
4975            updateCpuStatsNow();
4976        }
4977
4978        synchronized (this) {
4979            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4980            if (mShuttingDown) {
4981                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4982                return;
4983            } else if (app.notResponding) {
4984                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4985                return;
4986            } else if (app.crashing) {
4987                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4988                return;
4989            }
4990
4991            // In case we come through here for the same app before completing
4992            // this one, mark as anring now so we will bail out.
4993            app.notResponding = true;
4994
4995            // Log the ANR to the event log.
4996            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4997                    app.processName, app.info.flags, annotation);
4998
4999            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5000            firstPids.add(app.pid);
5001
5002            int parentPid = app.pid;
5003            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5004            if (parentPid != app.pid) firstPids.add(parentPid);
5005
5006            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5007
5008            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5009                ProcessRecord r = mLruProcesses.get(i);
5010                if (r != null && r.thread != null) {
5011                    int pid = r.pid;
5012                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5013                        if (r.persistent) {
5014                            firstPids.add(pid);
5015                        } else {
5016                            lastPids.put(pid, Boolean.TRUE);
5017                        }
5018                    }
5019                }
5020            }
5021        }
5022
5023        // Log the ANR to the main log.
5024        StringBuilder info = new StringBuilder();
5025        info.setLength(0);
5026        info.append("ANR in ").append(app.processName);
5027        if (activity != null && activity.shortComponentName != null) {
5028            info.append(" (").append(activity.shortComponentName).append(")");
5029        }
5030        info.append("\n");
5031        info.append("PID: ").append(app.pid).append("\n");
5032        if (annotation != null) {
5033            info.append("Reason: ").append(annotation).append("\n");
5034        }
5035        if (parent != null && parent != activity) {
5036            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5037        }
5038
5039        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5040
5041        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5042                NATIVE_STACKS_OF_INTEREST);
5043
5044        String cpuInfo = null;
5045        if (MONITOR_CPU_USAGE) {
5046            updateCpuStatsNow();
5047            synchronized (mProcessCpuThread) {
5048                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5049            }
5050            info.append(processCpuTracker.printCurrentLoad());
5051            info.append(cpuInfo);
5052        }
5053
5054        info.append(processCpuTracker.printCurrentState(anrTime));
5055
5056        Slog.e(TAG, info.toString());
5057        if (tracesFile == null) {
5058            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5059            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5060        }
5061
5062        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5063                cpuInfo, tracesFile, null);
5064
5065        if (mController != null) {
5066            try {
5067                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5068                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5069                if (res != 0) {
5070                    if (res < 0 && app.pid != MY_PID) {
5071                        app.kill("anr", true);
5072                    } else {
5073                        synchronized (this) {
5074                            mServices.scheduleServiceTimeoutLocked(app);
5075                        }
5076                    }
5077                    return;
5078                }
5079            } catch (RemoteException e) {
5080                mController = null;
5081                Watchdog.getInstance().setActivityController(null);
5082            }
5083        }
5084
5085        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5086        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5087                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5088
5089        synchronized (this) {
5090            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5091                app.kill("bg anr", true);
5092                return;
5093            }
5094
5095            // Set the app's notResponding state, and look up the errorReportReceiver
5096            makeAppNotRespondingLocked(app,
5097                    activity != null ? activity.shortComponentName : null,
5098                    annotation != null ? "ANR " + annotation : "ANR",
5099                    info.toString());
5100
5101            // Bring up the infamous App Not Responding dialog
5102            Message msg = Message.obtain();
5103            HashMap<String, Object> map = new HashMap<String, Object>();
5104            msg.what = SHOW_NOT_RESPONDING_MSG;
5105            msg.obj = map;
5106            msg.arg1 = aboveSystem ? 1 : 0;
5107            map.put("app", app);
5108            if (activity != null) {
5109                map.put("activity", activity);
5110            }
5111
5112            mHandler.sendMessage(msg);
5113        }
5114    }
5115
5116    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5117        if (!mLaunchWarningShown) {
5118            mLaunchWarningShown = true;
5119            mHandler.post(new Runnable() {
5120                @Override
5121                public void run() {
5122                    synchronized (ActivityManagerService.this) {
5123                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5124                        d.show();
5125                        mHandler.postDelayed(new Runnable() {
5126                            @Override
5127                            public void run() {
5128                                synchronized (ActivityManagerService.this) {
5129                                    d.dismiss();
5130                                    mLaunchWarningShown = false;
5131                                }
5132                            }
5133                        }, 4000);
5134                    }
5135                }
5136            });
5137        }
5138    }
5139
5140    @Override
5141    public boolean clearApplicationUserData(final String packageName,
5142            final IPackageDataObserver observer, int userId) {
5143        enforceNotIsolatedCaller("clearApplicationUserData");
5144        int uid = Binder.getCallingUid();
5145        int pid = Binder.getCallingPid();
5146        userId = handleIncomingUser(pid, uid,
5147                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5148        long callingId = Binder.clearCallingIdentity();
5149        try {
5150            IPackageManager pm = AppGlobals.getPackageManager();
5151            int pkgUid = -1;
5152            synchronized(this) {
5153                try {
5154                    pkgUid = pm.getPackageUid(packageName, userId);
5155                } catch (RemoteException e) {
5156                }
5157                if (pkgUid == -1) {
5158                    Slog.w(TAG, "Invalid packageName: " + packageName);
5159                    if (observer != null) {
5160                        try {
5161                            observer.onRemoveCompleted(packageName, false);
5162                        } catch (RemoteException e) {
5163                            Slog.i(TAG, "Observer no longer exists.");
5164                        }
5165                    }
5166                    return false;
5167                }
5168                if (uid == pkgUid || checkComponentPermission(
5169                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5170                        pid, uid, -1, true)
5171                        == PackageManager.PERMISSION_GRANTED) {
5172                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5173                } else {
5174                    throw new SecurityException("PID " + pid + " does not have permission "
5175                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5176                                    + " of package " + packageName);
5177                }
5178
5179                // Remove all tasks match the cleared application package and user
5180                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5181                    final TaskRecord tr = mRecentTasks.get(i);
5182                    final String taskPackageName =
5183                            tr.getBaseIntent().getComponent().getPackageName();
5184                    if (tr.userId != userId) continue;
5185                    if (!taskPackageName.equals(packageName)) continue;
5186                    removeTaskByIdLocked(tr.taskId, 0);
5187                }
5188            }
5189
5190            try {
5191                // Clear application user data
5192                pm.clearApplicationUserData(packageName, observer, userId);
5193
5194                synchronized(this) {
5195                    // Remove all permissions granted from/to this package
5196                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5197                }
5198
5199                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5200                        Uri.fromParts("package", packageName, null));
5201                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5202                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5203                        null, null, 0, null, null, null, false, false, userId);
5204            } catch (RemoteException e) {
5205            }
5206        } finally {
5207            Binder.restoreCallingIdentity(callingId);
5208        }
5209        return true;
5210    }
5211
5212    @Override
5213    public void killBackgroundProcesses(final String packageName, int userId) {
5214        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5215                != PackageManager.PERMISSION_GRANTED &&
5216                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5217                        != PackageManager.PERMISSION_GRANTED) {
5218            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5219                    + Binder.getCallingPid()
5220                    + ", uid=" + Binder.getCallingUid()
5221                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5222            Slog.w(TAG, msg);
5223            throw new SecurityException(msg);
5224        }
5225
5226        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5227                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5228        long callingId = Binder.clearCallingIdentity();
5229        try {
5230            IPackageManager pm = AppGlobals.getPackageManager();
5231            synchronized(this) {
5232                int appId = -1;
5233                try {
5234                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5235                } catch (RemoteException e) {
5236                }
5237                if (appId == -1) {
5238                    Slog.w(TAG, "Invalid packageName: " + packageName);
5239                    return;
5240                }
5241                killPackageProcessesLocked(packageName, appId, userId,
5242                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5243            }
5244        } finally {
5245            Binder.restoreCallingIdentity(callingId);
5246        }
5247    }
5248
5249    @Override
5250    public void killAllBackgroundProcesses() {
5251        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5252                != PackageManager.PERMISSION_GRANTED) {
5253            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5254                    + Binder.getCallingPid()
5255                    + ", uid=" + Binder.getCallingUid()
5256                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5257            Slog.w(TAG, msg);
5258            throw new SecurityException(msg);
5259        }
5260
5261        long callingId = Binder.clearCallingIdentity();
5262        try {
5263            synchronized(this) {
5264                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5265                final int NP = mProcessNames.getMap().size();
5266                for (int ip=0; ip<NP; ip++) {
5267                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5268                    final int NA = apps.size();
5269                    for (int ia=0; ia<NA; ia++) {
5270                        ProcessRecord app = apps.valueAt(ia);
5271                        if (app.persistent) {
5272                            // we don't kill persistent processes
5273                            continue;
5274                        }
5275                        if (app.removed) {
5276                            procs.add(app);
5277                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5278                            app.removed = true;
5279                            procs.add(app);
5280                        }
5281                    }
5282                }
5283
5284                int N = procs.size();
5285                for (int i=0; i<N; i++) {
5286                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5287                }
5288                mAllowLowerMemLevel = true;
5289                updateOomAdjLocked();
5290                doLowMemReportIfNeededLocked(null);
5291            }
5292        } finally {
5293            Binder.restoreCallingIdentity(callingId);
5294        }
5295    }
5296
5297    @Override
5298    public void forceStopPackage(final String packageName, int userId) {
5299        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5300                != PackageManager.PERMISSION_GRANTED) {
5301            String msg = "Permission Denial: forceStopPackage() from pid="
5302                    + Binder.getCallingPid()
5303                    + ", uid=" + Binder.getCallingUid()
5304                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5305            Slog.w(TAG, msg);
5306            throw new SecurityException(msg);
5307        }
5308        final int callingPid = Binder.getCallingPid();
5309        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5310                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5311        long callingId = Binder.clearCallingIdentity();
5312        try {
5313            IPackageManager pm = AppGlobals.getPackageManager();
5314            synchronized(this) {
5315                int[] users = userId == UserHandle.USER_ALL
5316                        ? getUsersLocked() : new int[] { userId };
5317                for (int user : users) {
5318                    int pkgUid = -1;
5319                    try {
5320                        pkgUid = pm.getPackageUid(packageName, user);
5321                    } catch (RemoteException e) {
5322                    }
5323                    if (pkgUid == -1) {
5324                        Slog.w(TAG, "Invalid packageName: " + packageName);
5325                        continue;
5326                    }
5327                    try {
5328                        pm.setPackageStoppedState(packageName, true, user);
5329                    } catch (RemoteException e) {
5330                    } catch (IllegalArgumentException e) {
5331                        Slog.w(TAG, "Failed trying to unstop package "
5332                                + packageName + ": " + e);
5333                    }
5334                    if (isUserRunningLocked(user, false)) {
5335                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5336                    }
5337                }
5338            }
5339        } finally {
5340            Binder.restoreCallingIdentity(callingId);
5341        }
5342    }
5343
5344    @Override
5345    public void addPackageDependency(String packageName) {
5346        synchronized (this) {
5347            int callingPid = Binder.getCallingPid();
5348            if (callingPid == Process.myPid()) {
5349                //  Yeah, um, no.
5350                Slog.w(TAG, "Can't addPackageDependency on system process");
5351                return;
5352            }
5353            ProcessRecord proc;
5354            synchronized (mPidsSelfLocked) {
5355                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5356            }
5357            if (proc != null) {
5358                if (proc.pkgDeps == null) {
5359                    proc.pkgDeps = new ArraySet<String>(1);
5360                }
5361                proc.pkgDeps.add(packageName);
5362            }
5363        }
5364    }
5365
5366    /*
5367     * The pkg name and app id have to be specified.
5368     */
5369    @Override
5370    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5371        if (pkg == null) {
5372            return;
5373        }
5374        // Make sure the uid is valid.
5375        if (appid < 0) {
5376            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5377            return;
5378        }
5379        int callerUid = Binder.getCallingUid();
5380        // Only the system server can kill an application
5381        if (callerUid == Process.SYSTEM_UID) {
5382            // Post an aysnc message to kill the application
5383            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5384            msg.arg1 = appid;
5385            msg.arg2 = 0;
5386            Bundle bundle = new Bundle();
5387            bundle.putString("pkg", pkg);
5388            bundle.putString("reason", reason);
5389            msg.obj = bundle;
5390            mHandler.sendMessage(msg);
5391        } else {
5392            throw new SecurityException(callerUid + " cannot kill pkg: " +
5393                    pkg);
5394        }
5395    }
5396
5397    @Override
5398    public void closeSystemDialogs(String reason) {
5399        enforceNotIsolatedCaller("closeSystemDialogs");
5400
5401        final int pid = Binder.getCallingPid();
5402        final int uid = Binder.getCallingUid();
5403        final long origId = Binder.clearCallingIdentity();
5404        try {
5405            synchronized (this) {
5406                // Only allow this from foreground processes, so that background
5407                // applications can't abuse it to prevent system UI from being shown.
5408                if (uid >= Process.FIRST_APPLICATION_UID) {
5409                    ProcessRecord proc;
5410                    synchronized (mPidsSelfLocked) {
5411                        proc = mPidsSelfLocked.get(pid);
5412                    }
5413                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5414                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5415                                + " from background process " + proc);
5416                        return;
5417                    }
5418                }
5419                closeSystemDialogsLocked(reason);
5420            }
5421        } finally {
5422            Binder.restoreCallingIdentity(origId);
5423        }
5424    }
5425
5426    void closeSystemDialogsLocked(String reason) {
5427        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5428        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5429                | Intent.FLAG_RECEIVER_FOREGROUND);
5430        if (reason != null) {
5431            intent.putExtra("reason", reason);
5432        }
5433        mWindowManager.closeSystemDialogs(reason);
5434
5435        mStackSupervisor.closeSystemDialogsLocked();
5436
5437        broadcastIntentLocked(null, null, intent, null,
5438                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5439                Process.SYSTEM_UID, UserHandle.USER_ALL);
5440    }
5441
5442    @Override
5443    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5444        enforceNotIsolatedCaller("getProcessMemoryInfo");
5445        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5446        for (int i=pids.length-1; i>=0; i--) {
5447            ProcessRecord proc;
5448            int oomAdj;
5449            synchronized (this) {
5450                synchronized (mPidsSelfLocked) {
5451                    proc = mPidsSelfLocked.get(pids[i]);
5452                    oomAdj = proc != null ? proc.setAdj : 0;
5453                }
5454            }
5455            infos[i] = new Debug.MemoryInfo();
5456            Debug.getMemoryInfo(pids[i], infos[i]);
5457            if (proc != null) {
5458                synchronized (this) {
5459                    if (proc.thread != null && proc.setAdj == oomAdj) {
5460                        // Record this for posterity if the process has been stable.
5461                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5462                                infos[i].getTotalUss(), false, proc.pkgList);
5463                    }
5464                }
5465            }
5466        }
5467        return infos;
5468    }
5469
5470    @Override
5471    public long[] getProcessPss(int[] pids) {
5472        enforceNotIsolatedCaller("getProcessPss");
5473        long[] pss = new long[pids.length];
5474        for (int i=pids.length-1; i>=0; i--) {
5475            ProcessRecord proc;
5476            int oomAdj;
5477            synchronized (this) {
5478                synchronized (mPidsSelfLocked) {
5479                    proc = mPidsSelfLocked.get(pids[i]);
5480                    oomAdj = proc != null ? proc.setAdj : 0;
5481                }
5482            }
5483            long[] tmpUss = new long[1];
5484            pss[i] = Debug.getPss(pids[i], tmpUss);
5485            if (proc != null) {
5486                synchronized (this) {
5487                    if (proc.thread != null && proc.setAdj == oomAdj) {
5488                        // Record this for posterity if the process has been stable.
5489                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5490                    }
5491                }
5492            }
5493        }
5494        return pss;
5495    }
5496
5497    @Override
5498    public void killApplicationProcess(String processName, int uid) {
5499        if (processName == null) {
5500            return;
5501        }
5502
5503        int callerUid = Binder.getCallingUid();
5504        // Only the system server can kill an application
5505        if (callerUid == Process.SYSTEM_UID) {
5506            synchronized (this) {
5507                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5508                if (app != null && app.thread != null) {
5509                    try {
5510                        app.thread.scheduleSuicide();
5511                    } catch (RemoteException e) {
5512                        // If the other end already died, then our work here is done.
5513                    }
5514                } else {
5515                    Slog.w(TAG, "Process/uid not found attempting kill of "
5516                            + processName + " / " + uid);
5517                }
5518            }
5519        } else {
5520            throw new SecurityException(callerUid + " cannot kill app process: " +
5521                    processName);
5522        }
5523    }
5524
5525    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5526        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5527                false, true, false, false, UserHandle.getUserId(uid), reason);
5528        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5529                Uri.fromParts("package", packageName, null));
5530        if (!mProcessesReady) {
5531            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5532                    | Intent.FLAG_RECEIVER_FOREGROUND);
5533        }
5534        intent.putExtra(Intent.EXTRA_UID, uid);
5535        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5536        broadcastIntentLocked(null, null, intent,
5537                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5538                false, false,
5539                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5540    }
5541
5542    private void forceStopUserLocked(int userId, String reason) {
5543        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5544        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5545        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5546                | Intent.FLAG_RECEIVER_FOREGROUND);
5547        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5548        broadcastIntentLocked(null, null, intent,
5549                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5550                false, false,
5551                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5552    }
5553
5554    private final boolean killPackageProcessesLocked(String packageName, int appId,
5555            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5556            boolean doit, boolean evenPersistent, String reason) {
5557        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5558
5559        // Remove all processes this package may have touched: all with the
5560        // same UID (except for the system or root user), and all whose name
5561        // matches the package name.
5562        final int NP = mProcessNames.getMap().size();
5563        for (int ip=0; ip<NP; ip++) {
5564            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5565            final int NA = apps.size();
5566            for (int ia=0; ia<NA; ia++) {
5567                ProcessRecord app = apps.valueAt(ia);
5568                if (app.persistent && !evenPersistent) {
5569                    // we don't kill persistent processes
5570                    continue;
5571                }
5572                if (app.removed) {
5573                    if (doit) {
5574                        procs.add(app);
5575                    }
5576                    continue;
5577                }
5578
5579                // Skip process if it doesn't meet our oom adj requirement.
5580                if (app.setAdj < minOomAdj) {
5581                    continue;
5582                }
5583
5584                // If no package is specified, we call all processes under the
5585                // give user id.
5586                if (packageName == null) {
5587                    if (app.userId != userId) {
5588                        continue;
5589                    }
5590                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5591                        continue;
5592                    }
5593                // Package has been specified, we want to hit all processes
5594                // that match it.  We need to qualify this by the processes
5595                // that are running under the specified app and user ID.
5596                } else {
5597                    final boolean isDep = app.pkgDeps != null
5598                            && app.pkgDeps.contains(packageName);
5599                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5600                        continue;
5601                    }
5602                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5603                        continue;
5604                    }
5605                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5606                        continue;
5607                    }
5608                }
5609
5610                // Process has passed all conditions, kill it!
5611                if (!doit) {
5612                    return true;
5613                }
5614                app.removed = true;
5615                procs.add(app);
5616            }
5617        }
5618
5619        int N = procs.size();
5620        for (int i=0; i<N; i++) {
5621            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5622        }
5623        updateOomAdjLocked();
5624        return N > 0;
5625    }
5626
5627    private final boolean forceStopPackageLocked(String name, int appId,
5628            boolean callerWillRestart, boolean purgeCache, boolean doit,
5629            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5630        int i;
5631        int N;
5632
5633        if (userId == UserHandle.USER_ALL && name == null) {
5634            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5635        }
5636
5637        if (appId < 0 && name != null) {
5638            try {
5639                appId = UserHandle.getAppId(
5640                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5641            } catch (RemoteException e) {
5642            }
5643        }
5644
5645        if (doit) {
5646            if (name != null) {
5647                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5648                        + " user=" + userId + ": " + reason);
5649            } else {
5650                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5651            }
5652
5653            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5654            for (int ip=pmap.size()-1; ip>=0; ip--) {
5655                SparseArray<Long> ba = pmap.valueAt(ip);
5656                for (i=ba.size()-1; i>=0; i--) {
5657                    boolean remove = false;
5658                    final int entUid = ba.keyAt(i);
5659                    if (name != null) {
5660                        if (userId == UserHandle.USER_ALL) {
5661                            if (UserHandle.getAppId(entUid) == appId) {
5662                                remove = true;
5663                            }
5664                        } else {
5665                            if (entUid == UserHandle.getUid(userId, appId)) {
5666                                remove = true;
5667                            }
5668                        }
5669                    } else if (UserHandle.getUserId(entUid) == userId) {
5670                        remove = true;
5671                    }
5672                    if (remove) {
5673                        ba.removeAt(i);
5674                    }
5675                }
5676                if (ba.size() == 0) {
5677                    pmap.removeAt(ip);
5678                }
5679            }
5680        }
5681
5682        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5683                -100, callerWillRestart, true, doit, evenPersistent,
5684                name == null ? ("stop user " + userId) : ("stop " + name));
5685
5686        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5687            if (!doit) {
5688                return true;
5689            }
5690            didSomething = true;
5691        }
5692
5693        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5694            if (!doit) {
5695                return true;
5696            }
5697            didSomething = true;
5698        }
5699
5700        if (name == null) {
5701            // Remove all sticky broadcasts from this user.
5702            mStickyBroadcasts.remove(userId);
5703        }
5704
5705        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5706        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5707                userId, providers)) {
5708            if (!doit) {
5709                return true;
5710            }
5711            didSomething = true;
5712        }
5713        N = providers.size();
5714        for (i=0; i<N; i++) {
5715            removeDyingProviderLocked(null, providers.get(i), true);
5716        }
5717
5718        // Remove transient permissions granted from/to this package/user
5719        removeUriPermissionsForPackageLocked(name, userId, false);
5720
5721        if (name == null || uninstalling) {
5722            // Remove pending intents.  For now we only do this when force
5723            // stopping users, because we have some problems when doing this
5724            // for packages -- app widgets are not currently cleaned up for
5725            // such packages, so they can be left with bad pending intents.
5726            if (mIntentSenderRecords.size() > 0) {
5727                Iterator<WeakReference<PendingIntentRecord>> it
5728                        = mIntentSenderRecords.values().iterator();
5729                while (it.hasNext()) {
5730                    WeakReference<PendingIntentRecord> wpir = it.next();
5731                    if (wpir == null) {
5732                        it.remove();
5733                        continue;
5734                    }
5735                    PendingIntentRecord pir = wpir.get();
5736                    if (pir == null) {
5737                        it.remove();
5738                        continue;
5739                    }
5740                    if (name == null) {
5741                        // Stopping user, remove all objects for the user.
5742                        if (pir.key.userId != userId) {
5743                            // Not the same user, skip it.
5744                            continue;
5745                        }
5746                    } else {
5747                        if (UserHandle.getAppId(pir.uid) != appId) {
5748                            // Different app id, skip it.
5749                            continue;
5750                        }
5751                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5752                            // Different user, skip it.
5753                            continue;
5754                        }
5755                        if (!pir.key.packageName.equals(name)) {
5756                            // Different package, skip it.
5757                            continue;
5758                        }
5759                    }
5760                    if (!doit) {
5761                        return true;
5762                    }
5763                    didSomething = true;
5764                    it.remove();
5765                    pir.canceled = true;
5766                    if (pir.key.activity != null) {
5767                        pir.key.activity.pendingResults.remove(pir.ref);
5768                    }
5769                }
5770            }
5771        }
5772
5773        if (doit) {
5774            if (purgeCache && name != null) {
5775                AttributeCache ac = AttributeCache.instance();
5776                if (ac != null) {
5777                    ac.removePackage(name);
5778                }
5779            }
5780            if (mBooted) {
5781                mStackSupervisor.resumeTopActivitiesLocked();
5782                mStackSupervisor.scheduleIdleLocked();
5783            }
5784        }
5785
5786        return didSomething;
5787    }
5788
5789    private final boolean removeProcessLocked(ProcessRecord app,
5790            boolean callerWillRestart, boolean allowRestart, String reason) {
5791        final String name = app.processName;
5792        final int uid = app.uid;
5793        if (DEBUG_PROCESSES) Slog.d(
5794            TAG, "Force removing proc " + app.toShortString() + " (" + name
5795            + "/" + uid + ")");
5796
5797        mProcessNames.remove(name, uid);
5798        mIsolatedProcesses.remove(app.uid);
5799        if (mHeavyWeightProcess == app) {
5800            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5801                    mHeavyWeightProcess.userId, 0));
5802            mHeavyWeightProcess = null;
5803        }
5804        boolean needRestart = false;
5805        if (app.pid > 0 && app.pid != MY_PID) {
5806            int pid = app.pid;
5807            synchronized (mPidsSelfLocked) {
5808                mPidsSelfLocked.remove(pid);
5809                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5810            }
5811            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5812            if (app.isolated) {
5813                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5814            }
5815            app.kill(reason, true);
5816            handleAppDiedLocked(app, true, allowRestart);
5817            removeLruProcessLocked(app);
5818
5819            if (app.persistent && !app.isolated) {
5820                if (!callerWillRestart) {
5821                    addAppLocked(app.info, false, null /* ABI override */);
5822                } else {
5823                    needRestart = true;
5824                }
5825            }
5826        } else {
5827            mRemovedProcesses.add(app);
5828        }
5829
5830        return needRestart;
5831    }
5832
5833    private final void processStartTimedOutLocked(ProcessRecord app) {
5834        final int pid = app.pid;
5835        boolean gone = false;
5836        synchronized (mPidsSelfLocked) {
5837            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5838            if (knownApp != null && knownApp.thread == null) {
5839                mPidsSelfLocked.remove(pid);
5840                gone = true;
5841            }
5842        }
5843
5844        if (gone) {
5845            Slog.w(TAG, "Process " + app + " failed to attach");
5846            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5847                    pid, app.uid, app.processName);
5848            mProcessNames.remove(app.processName, app.uid);
5849            mIsolatedProcesses.remove(app.uid);
5850            if (mHeavyWeightProcess == app) {
5851                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5852                        mHeavyWeightProcess.userId, 0));
5853                mHeavyWeightProcess = null;
5854            }
5855            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5856            if (app.isolated) {
5857                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5858            }
5859            // Take care of any launching providers waiting for this process.
5860            checkAppInLaunchingProvidersLocked(app, true);
5861            // Take care of any services that are waiting for the process.
5862            mServices.processStartTimedOutLocked(app);
5863            app.kill("start timeout", true);
5864            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5865                Slog.w(TAG, "Unattached app died before backup, skipping");
5866                try {
5867                    IBackupManager bm = IBackupManager.Stub.asInterface(
5868                            ServiceManager.getService(Context.BACKUP_SERVICE));
5869                    bm.agentDisconnected(app.info.packageName);
5870                } catch (RemoteException e) {
5871                    // Can't happen; the backup manager is local
5872                }
5873            }
5874            if (isPendingBroadcastProcessLocked(pid)) {
5875                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5876                skipPendingBroadcastLocked(pid);
5877            }
5878        } else {
5879            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5880        }
5881    }
5882
5883    private final boolean attachApplicationLocked(IApplicationThread thread,
5884            int pid) {
5885
5886        // Find the application record that is being attached...  either via
5887        // the pid if we are running in multiple processes, or just pull the
5888        // next app record if we are emulating process with anonymous threads.
5889        ProcessRecord app;
5890        if (pid != MY_PID && pid >= 0) {
5891            synchronized (mPidsSelfLocked) {
5892                app = mPidsSelfLocked.get(pid);
5893            }
5894        } else {
5895            app = null;
5896        }
5897
5898        if (app == null) {
5899            Slog.w(TAG, "No pending application record for pid " + pid
5900                    + " (IApplicationThread " + thread + "); dropping process");
5901            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5902            if (pid > 0 && pid != MY_PID) {
5903                Process.killProcessQuiet(pid);
5904                //TODO: Process.killProcessGroup(app.info.uid, pid);
5905            } else {
5906                try {
5907                    thread.scheduleExit();
5908                } catch (Exception e) {
5909                    // Ignore exceptions.
5910                }
5911            }
5912            return false;
5913        }
5914
5915        // If this application record is still attached to a previous
5916        // process, clean it up now.
5917        if (app.thread != null) {
5918            handleAppDiedLocked(app, true, true);
5919        }
5920
5921        // Tell the process all about itself.
5922
5923        if (localLOGV) Slog.v(
5924                TAG, "Binding process pid " + pid + " to record " + app);
5925
5926        final String processName = app.processName;
5927        try {
5928            AppDeathRecipient adr = new AppDeathRecipient(
5929                    app, pid, thread);
5930            thread.asBinder().linkToDeath(adr, 0);
5931            app.deathRecipient = adr;
5932        } catch (RemoteException e) {
5933            app.resetPackageList(mProcessStats);
5934            startProcessLocked(app, "link fail", processName);
5935            return false;
5936        }
5937
5938        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5939
5940        app.makeActive(thread, mProcessStats);
5941        app.curAdj = app.setAdj = -100;
5942        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5943        app.forcingToForeground = null;
5944        updateProcessForegroundLocked(app, false, false);
5945        app.hasShownUi = false;
5946        app.debugging = false;
5947        app.cached = false;
5948
5949        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5950
5951        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5952        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5953
5954        if (!normalMode) {
5955            Slog.i(TAG, "Launching preboot mode app: " + app);
5956        }
5957
5958        if (localLOGV) Slog.v(
5959            TAG, "New app record " + app
5960            + " thread=" + thread.asBinder() + " pid=" + pid);
5961        try {
5962            int testMode = IApplicationThread.DEBUG_OFF;
5963            if (mDebugApp != null && mDebugApp.equals(processName)) {
5964                testMode = mWaitForDebugger
5965                    ? IApplicationThread.DEBUG_WAIT
5966                    : IApplicationThread.DEBUG_ON;
5967                app.debugging = true;
5968                if (mDebugTransient) {
5969                    mDebugApp = mOrigDebugApp;
5970                    mWaitForDebugger = mOrigWaitForDebugger;
5971                }
5972            }
5973            String profileFile = app.instrumentationProfileFile;
5974            ParcelFileDescriptor profileFd = null;
5975            int samplingInterval = 0;
5976            boolean profileAutoStop = false;
5977            if (mProfileApp != null && mProfileApp.equals(processName)) {
5978                mProfileProc = app;
5979                profileFile = mProfileFile;
5980                profileFd = mProfileFd;
5981                samplingInterval = mSamplingInterval;
5982                profileAutoStop = mAutoStopProfiler;
5983            }
5984            boolean enableOpenGlTrace = false;
5985            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5986                enableOpenGlTrace = true;
5987                mOpenGlTraceApp = null;
5988            }
5989
5990            // If the app is being launched for restore or full backup, set it up specially
5991            boolean isRestrictedBackupMode = false;
5992            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5993                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5994                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5995                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5996            }
5997
5998            ensurePackageDexOpt(app.instrumentationInfo != null
5999                    ? app.instrumentationInfo.packageName
6000                    : app.info.packageName);
6001            if (app.instrumentationClass != null) {
6002                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6003            }
6004            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6005                    + processName + " with config " + mConfiguration);
6006            ApplicationInfo appInfo = app.instrumentationInfo != null
6007                    ? app.instrumentationInfo : app.info;
6008            app.compat = compatibilityInfoForPackageLocked(appInfo);
6009            if (profileFd != null) {
6010                profileFd = profileFd.dup();
6011            }
6012            ProfilerInfo profilerInfo = profileFile == null ? null
6013                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6014            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6015                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6016                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6017                    isRestrictedBackupMode || !normalMode, app.persistent,
6018                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6019                    mCoreSettingsObserver.getCoreSettingsLocked());
6020            updateLruProcessLocked(app, false, null);
6021            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6022        } catch (Exception e) {
6023            // todo: Yikes!  What should we do?  For now we will try to
6024            // start another process, but that could easily get us in
6025            // an infinite loop of restarting processes...
6026            Slog.w(TAG, "Exception thrown during bind!", e);
6027
6028            app.resetPackageList(mProcessStats);
6029            app.unlinkDeathRecipient();
6030            startProcessLocked(app, "bind fail", processName);
6031            return false;
6032        }
6033
6034        // Remove this record from the list of starting applications.
6035        mPersistentStartingProcesses.remove(app);
6036        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6037                "Attach application locked removing on hold: " + app);
6038        mProcessesOnHold.remove(app);
6039
6040        boolean badApp = false;
6041        boolean didSomething = false;
6042
6043        // See if the top visible activity is waiting to run in this process...
6044        if (normalMode) {
6045            try {
6046                if (mStackSupervisor.attachApplicationLocked(app)) {
6047                    didSomething = true;
6048                }
6049            } catch (Exception e) {
6050                badApp = true;
6051            }
6052        }
6053
6054        // Find any services that should be running in this process...
6055        if (!badApp) {
6056            try {
6057                didSomething |= mServices.attachApplicationLocked(app, processName);
6058            } catch (Exception e) {
6059                badApp = true;
6060            }
6061        }
6062
6063        // Check if a next-broadcast receiver is in this process...
6064        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6065            try {
6066                didSomething |= sendPendingBroadcastsLocked(app);
6067            } catch (Exception e) {
6068                // If the app died trying to launch the receiver we declare it 'bad'
6069                badApp = true;
6070            }
6071        }
6072
6073        // Check whether the next backup agent is in this process...
6074        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6075            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6076            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6077            try {
6078                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6079                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6080                        mBackupTarget.backupMode);
6081            } catch (Exception e) {
6082                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6083                e.printStackTrace();
6084            }
6085        }
6086
6087        if (badApp) {
6088            // todo: Also need to kill application to deal with all
6089            // kinds of exceptions.
6090            handleAppDiedLocked(app, false, true);
6091            return false;
6092        }
6093
6094        if (!didSomething) {
6095            updateOomAdjLocked();
6096        }
6097
6098        return true;
6099    }
6100
6101    @Override
6102    public final void attachApplication(IApplicationThread thread) {
6103        synchronized (this) {
6104            int callingPid = Binder.getCallingPid();
6105            final long origId = Binder.clearCallingIdentity();
6106            attachApplicationLocked(thread, callingPid);
6107            Binder.restoreCallingIdentity(origId);
6108        }
6109    }
6110
6111    @Override
6112    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6113        final long origId = Binder.clearCallingIdentity();
6114        synchronized (this) {
6115            ActivityStack stack = ActivityRecord.getStackLocked(token);
6116            if (stack != null) {
6117                ActivityRecord r =
6118                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6119                if (stopProfiling) {
6120                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6121                        try {
6122                            mProfileFd.close();
6123                        } catch (IOException e) {
6124                        }
6125                        clearProfilerLocked();
6126                    }
6127                }
6128            }
6129        }
6130        Binder.restoreCallingIdentity(origId);
6131    }
6132
6133    void postEnableScreenAfterBootLocked() {
6134        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6135    }
6136
6137    void enableScreenAfterBoot() {
6138        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6139                SystemClock.uptimeMillis());
6140        mWindowManager.enableScreenAfterBoot();
6141
6142        synchronized (this) {
6143            updateEventDispatchingLocked();
6144        }
6145    }
6146
6147    @Override
6148    public void showBootMessage(final CharSequence msg, final boolean always) {
6149        enforceNotIsolatedCaller("showBootMessage");
6150        mWindowManager.showBootMessage(msg, always);
6151    }
6152
6153    @Override
6154    public void keyguardWaitingForActivityDrawn() {
6155        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6156        final long token = Binder.clearCallingIdentity();
6157        try {
6158            synchronized (this) {
6159                if (DEBUG_LOCKSCREEN) logLockScreen("");
6160                mWindowManager.keyguardWaitingForActivityDrawn();
6161            }
6162        } finally {
6163            Binder.restoreCallingIdentity(token);
6164        }
6165    }
6166
6167    final void finishBooting() {
6168        // Register receivers to handle package update events
6169        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6170
6171        // Let system services know.
6172        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6173
6174        synchronized (this) {
6175            // Ensure that any processes we had put on hold are now started
6176            // up.
6177            final int NP = mProcessesOnHold.size();
6178            if (NP > 0) {
6179                ArrayList<ProcessRecord> procs =
6180                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6181                for (int ip=0; ip<NP; ip++) {
6182                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6183                            + procs.get(ip));
6184                    startProcessLocked(procs.get(ip), "on-hold", null);
6185                }
6186            }
6187
6188            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6189                // Start looking for apps that are abusing wake locks.
6190                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6191                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6192                // Tell anyone interested that we are done booting!
6193                SystemProperties.set("sys.boot_completed", "1");
6194                SystemProperties.set("dev.bootcomplete", "1");
6195                for (int i=0; i<mStartedUsers.size(); i++) {
6196                    UserStartedState uss = mStartedUsers.valueAt(i);
6197                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6198                        uss.mState = UserStartedState.STATE_RUNNING;
6199                        final int userId = mStartedUsers.keyAt(i);
6200                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6201                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6202                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6203                        broadcastIntentLocked(null, null, intent, null,
6204                                new IIntentReceiver.Stub() {
6205                                    @Override
6206                                    public void performReceive(Intent intent, int resultCode,
6207                                            String data, Bundle extras, boolean ordered,
6208                                            boolean sticky, int sendingUser) {
6209                                        synchronized (ActivityManagerService.this) {
6210                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6211                                                    true, false);
6212                                        }
6213                                    }
6214                                },
6215                                0, null, null,
6216                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6217                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6218                                userId);
6219                    }
6220                }
6221                scheduleStartProfilesLocked();
6222            }
6223        }
6224    }
6225
6226    final void ensureBootCompleted() {
6227        boolean booting;
6228        boolean enableScreen;
6229        synchronized (this) {
6230            booting = mBooting;
6231            mBooting = false;
6232            enableScreen = !mBooted;
6233            mBooted = true;
6234        }
6235
6236        if (booting) {
6237            finishBooting();
6238        }
6239
6240        if (enableScreen) {
6241            enableScreenAfterBoot();
6242        }
6243    }
6244
6245    @Override
6246    public final void activityResumed(IBinder token) {
6247        final long origId = Binder.clearCallingIdentity();
6248        synchronized(this) {
6249            ActivityStack stack = ActivityRecord.getStackLocked(token);
6250            if (stack != null) {
6251                ActivityRecord.activityResumedLocked(token);
6252            }
6253        }
6254        Binder.restoreCallingIdentity(origId);
6255    }
6256
6257    @Override
6258    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
6259        final long origId = Binder.clearCallingIdentity();
6260        synchronized(this) {
6261            ActivityStack stack = ActivityRecord.getStackLocked(token);
6262            if (stack != null) {
6263                stack.activityPausedLocked(token, false, persistentState);
6264            }
6265        }
6266        Binder.restoreCallingIdentity(origId);
6267    }
6268
6269    @Override
6270    public final void activityStopped(IBinder token, Bundle icicle,
6271            PersistableBundle persistentState, CharSequence description) {
6272        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6273
6274        // Refuse possible leaked file descriptors
6275        if (icicle != null && icicle.hasFileDescriptors()) {
6276            throw new IllegalArgumentException("File descriptors passed in Bundle");
6277        }
6278
6279        final long origId = Binder.clearCallingIdentity();
6280
6281        synchronized (this) {
6282            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6283            if (r != null) {
6284                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6285            }
6286        }
6287
6288        trimApplications();
6289
6290        Binder.restoreCallingIdentity(origId);
6291    }
6292
6293    @Override
6294    public final void activityDestroyed(IBinder token) {
6295        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6296        synchronized (this) {
6297            ActivityStack stack = ActivityRecord.getStackLocked(token);
6298            if (stack != null) {
6299                stack.activityDestroyedLocked(token);
6300            }
6301        }
6302    }
6303
6304    @Override
6305    public final void backgroundResourcesReleased(IBinder token) {
6306        final long origId = Binder.clearCallingIdentity();
6307        try {
6308            synchronized (this) {
6309                ActivityStack stack = ActivityRecord.getStackLocked(token);
6310                if (stack != null) {
6311                    stack.backgroundResourcesReleased(token);
6312                }
6313            }
6314        } finally {
6315            Binder.restoreCallingIdentity(origId);
6316        }
6317    }
6318
6319    @Override
6320    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6321        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6322    }
6323
6324    @Override
6325    public final void notifyEnterAnimationComplete(IBinder token) {
6326        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6327    }
6328
6329    @Override
6330    public String getCallingPackage(IBinder token) {
6331        synchronized (this) {
6332            ActivityRecord r = getCallingRecordLocked(token);
6333            return r != null ? r.info.packageName : null;
6334        }
6335    }
6336
6337    @Override
6338    public ComponentName getCallingActivity(IBinder token) {
6339        synchronized (this) {
6340            ActivityRecord r = getCallingRecordLocked(token);
6341            return r != null ? r.intent.getComponent() : null;
6342        }
6343    }
6344
6345    private ActivityRecord getCallingRecordLocked(IBinder token) {
6346        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6347        if (r == null) {
6348            return null;
6349        }
6350        return r.resultTo;
6351    }
6352
6353    @Override
6354    public ComponentName getActivityClassForToken(IBinder token) {
6355        synchronized(this) {
6356            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6357            if (r == null) {
6358                return null;
6359            }
6360            return r.intent.getComponent();
6361        }
6362    }
6363
6364    @Override
6365    public String getPackageForToken(IBinder token) {
6366        synchronized(this) {
6367            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6368            if (r == null) {
6369                return null;
6370            }
6371            return r.packageName;
6372        }
6373    }
6374
6375    @Override
6376    public IIntentSender getIntentSender(int type,
6377            String packageName, IBinder token, String resultWho,
6378            int requestCode, Intent[] intents, String[] resolvedTypes,
6379            int flags, Bundle options, int userId) {
6380        enforceNotIsolatedCaller("getIntentSender");
6381        // Refuse possible leaked file descriptors
6382        if (intents != null) {
6383            if (intents.length < 1) {
6384                throw new IllegalArgumentException("Intents array length must be >= 1");
6385            }
6386            for (int i=0; i<intents.length; i++) {
6387                Intent intent = intents[i];
6388                if (intent != null) {
6389                    if (intent.hasFileDescriptors()) {
6390                        throw new IllegalArgumentException("File descriptors passed in Intent");
6391                    }
6392                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6393                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6394                        throw new IllegalArgumentException(
6395                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6396                    }
6397                    intents[i] = new Intent(intent);
6398                }
6399            }
6400            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6401                throw new IllegalArgumentException(
6402                        "Intent array length does not match resolvedTypes length");
6403            }
6404        }
6405        if (options != null) {
6406            if (options.hasFileDescriptors()) {
6407                throw new IllegalArgumentException("File descriptors passed in options");
6408            }
6409        }
6410
6411        synchronized(this) {
6412            int callingUid = Binder.getCallingUid();
6413            int origUserId = userId;
6414            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6415                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6416                    ALLOW_NON_FULL, "getIntentSender", null);
6417            if (origUserId == UserHandle.USER_CURRENT) {
6418                // We don't want to evaluate this until the pending intent is
6419                // actually executed.  However, we do want to always do the
6420                // security checking for it above.
6421                userId = UserHandle.USER_CURRENT;
6422            }
6423            try {
6424                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6425                    int uid = AppGlobals.getPackageManager()
6426                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6427                    if (!UserHandle.isSameApp(callingUid, uid)) {
6428                        String msg = "Permission Denial: getIntentSender() from pid="
6429                            + Binder.getCallingPid()
6430                            + ", uid=" + Binder.getCallingUid()
6431                            + ", (need uid=" + uid + ")"
6432                            + " is not allowed to send as package " + packageName;
6433                        Slog.w(TAG, msg);
6434                        throw new SecurityException(msg);
6435                    }
6436                }
6437
6438                return getIntentSenderLocked(type, packageName, callingUid, userId,
6439                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6440
6441            } catch (RemoteException e) {
6442                throw new SecurityException(e);
6443            }
6444        }
6445    }
6446
6447    IIntentSender getIntentSenderLocked(int type, String packageName,
6448            int callingUid, int userId, IBinder token, String resultWho,
6449            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6450            Bundle options) {
6451        if (DEBUG_MU)
6452            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6453        ActivityRecord activity = null;
6454        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6455            activity = ActivityRecord.isInStackLocked(token);
6456            if (activity == null) {
6457                return null;
6458            }
6459            if (activity.finishing) {
6460                return null;
6461            }
6462        }
6463
6464        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6465        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6466        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6467        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6468                |PendingIntent.FLAG_UPDATE_CURRENT);
6469
6470        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6471                type, packageName, activity, resultWho,
6472                requestCode, intents, resolvedTypes, flags, options, userId);
6473        WeakReference<PendingIntentRecord> ref;
6474        ref = mIntentSenderRecords.get(key);
6475        PendingIntentRecord rec = ref != null ? ref.get() : null;
6476        if (rec != null) {
6477            if (!cancelCurrent) {
6478                if (updateCurrent) {
6479                    if (rec.key.requestIntent != null) {
6480                        rec.key.requestIntent.replaceExtras(intents != null ?
6481                                intents[intents.length - 1] : null);
6482                    }
6483                    if (intents != null) {
6484                        intents[intents.length-1] = rec.key.requestIntent;
6485                        rec.key.allIntents = intents;
6486                        rec.key.allResolvedTypes = resolvedTypes;
6487                    } else {
6488                        rec.key.allIntents = null;
6489                        rec.key.allResolvedTypes = null;
6490                    }
6491                }
6492                return rec;
6493            }
6494            rec.canceled = true;
6495            mIntentSenderRecords.remove(key);
6496        }
6497        if (noCreate) {
6498            return rec;
6499        }
6500        rec = new PendingIntentRecord(this, key, callingUid);
6501        mIntentSenderRecords.put(key, rec.ref);
6502        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6503            if (activity.pendingResults == null) {
6504                activity.pendingResults
6505                        = new HashSet<WeakReference<PendingIntentRecord>>();
6506            }
6507            activity.pendingResults.add(rec.ref);
6508        }
6509        return rec;
6510    }
6511
6512    @Override
6513    public void cancelIntentSender(IIntentSender sender) {
6514        if (!(sender instanceof PendingIntentRecord)) {
6515            return;
6516        }
6517        synchronized(this) {
6518            PendingIntentRecord rec = (PendingIntentRecord)sender;
6519            try {
6520                int uid = AppGlobals.getPackageManager()
6521                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6522                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6523                    String msg = "Permission Denial: cancelIntentSender() from pid="
6524                        + Binder.getCallingPid()
6525                        + ", uid=" + Binder.getCallingUid()
6526                        + " is not allowed to cancel packges "
6527                        + rec.key.packageName;
6528                    Slog.w(TAG, msg);
6529                    throw new SecurityException(msg);
6530                }
6531            } catch (RemoteException e) {
6532                throw new SecurityException(e);
6533            }
6534            cancelIntentSenderLocked(rec, true);
6535        }
6536    }
6537
6538    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6539        rec.canceled = true;
6540        mIntentSenderRecords.remove(rec.key);
6541        if (cleanActivity && rec.key.activity != null) {
6542            rec.key.activity.pendingResults.remove(rec.ref);
6543        }
6544    }
6545
6546    @Override
6547    public String getPackageForIntentSender(IIntentSender pendingResult) {
6548        if (!(pendingResult instanceof PendingIntentRecord)) {
6549            return null;
6550        }
6551        try {
6552            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6553            return res.key.packageName;
6554        } catch (ClassCastException e) {
6555        }
6556        return null;
6557    }
6558
6559    @Override
6560    public int getUidForIntentSender(IIntentSender sender) {
6561        if (sender instanceof PendingIntentRecord) {
6562            try {
6563                PendingIntentRecord res = (PendingIntentRecord)sender;
6564                return res.uid;
6565            } catch (ClassCastException e) {
6566            }
6567        }
6568        return -1;
6569    }
6570
6571    @Override
6572    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6573        if (!(pendingResult instanceof PendingIntentRecord)) {
6574            return false;
6575        }
6576        try {
6577            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6578            if (res.key.allIntents == null) {
6579                return false;
6580            }
6581            for (int i=0; i<res.key.allIntents.length; i++) {
6582                Intent intent = res.key.allIntents[i];
6583                if (intent.getPackage() != null && intent.getComponent() != null) {
6584                    return false;
6585                }
6586            }
6587            return true;
6588        } catch (ClassCastException e) {
6589        }
6590        return false;
6591    }
6592
6593    @Override
6594    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6595        if (!(pendingResult instanceof PendingIntentRecord)) {
6596            return false;
6597        }
6598        try {
6599            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6600            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6601                return true;
6602            }
6603            return false;
6604        } catch (ClassCastException e) {
6605        }
6606        return false;
6607    }
6608
6609    @Override
6610    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6611        if (!(pendingResult instanceof PendingIntentRecord)) {
6612            return null;
6613        }
6614        try {
6615            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6616            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6617        } catch (ClassCastException e) {
6618        }
6619        return null;
6620    }
6621
6622    @Override
6623    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6624        if (!(pendingResult instanceof PendingIntentRecord)) {
6625            return null;
6626        }
6627        try {
6628            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6629            Intent intent = res.key.requestIntent;
6630            if (intent != null) {
6631                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6632                        || res.lastTagPrefix.equals(prefix))) {
6633                    return res.lastTag;
6634                }
6635                res.lastTagPrefix = prefix;
6636                StringBuilder sb = new StringBuilder(128);
6637                if (prefix != null) {
6638                    sb.append(prefix);
6639                }
6640                if (intent.getAction() != null) {
6641                    sb.append(intent.getAction());
6642                } else if (intent.getComponent() != null) {
6643                    intent.getComponent().appendShortString(sb);
6644                } else {
6645                    sb.append("?");
6646                }
6647                return res.lastTag = sb.toString();
6648            }
6649        } catch (ClassCastException e) {
6650        }
6651        return null;
6652    }
6653
6654    @Override
6655    public void setProcessLimit(int max) {
6656        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6657                "setProcessLimit()");
6658        synchronized (this) {
6659            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6660            mProcessLimitOverride = max;
6661        }
6662        trimApplications();
6663    }
6664
6665    @Override
6666    public int getProcessLimit() {
6667        synchronized (this) {
6668            return mProcessLimitOverride;
6669        }
6670    }
6671
6672    void foregroundTokenDied(ForegroundToken token) {
6673        synchronized (ActivityManagerService.this) {
6674            synchronized (mPidsSelfLocked) {
6675                ForegroundToken cur
6676                    = mForegroundProcesses.get(token.pid);
6677                if (cur != token) {
6678                    return;
6679                }
6680                mForegroundProcesses.remove(token.pid);
6681                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6682                if (pr == null) {
6683                    return;
6684                }
6685                pr.forcingToForeground = null;
6686                updateProcessForegroundLocked(pr, false, false);
6687            }
6688            updateOomAdjLocked();
6689        }
6690    }
6691
6692    @Override
6693    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6694        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6695                "setProcessForeground()");
6696        synchronized(this) {
6697            boolean changed = false;
6698
6699            synchronized (mPidsSelfLocked) {
6700                ProcessRecord pr = mPidsSelfLocked.get(pid);
6701                if (pr == null && isForeground) {
6702                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6703                    return;
6704                }
6705                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6706                if (oldToken != null) {
6707                    oldToken.token.unlinkToDeath(oldToken, 0);
6708                    mForegroundProcesses.remove(pid);
6709                    if (pr != null) {
6710                        pr.forcingToForeground = null;
6711                    }
6712                    changed = true;
6713                }
6714                if (isForeground && token != null) {
6715                    ForegroundToken newToken = new ForegroundToken() {
6716                        @Override
6717                        public void binderDied() {
6718                            foregroundTokenDied(this);
6719                        }
6720                    };
6721                    newToken.pid = pid;
6722                    newToken.token = token;
6723                    try {
6724                        token.linkToDeath(newToken, 0);
6725                        mForegroundProcesses.put(pid, newToken);
6726                        pr.forcingToForeground = token;
6727                        changed = true;
6728                    } catch (RemoteException e) {
6729                        // If the process died while doing this, we will later
6730                        // do the cleanup with the process death link.
6731                    }
6732                }
6733            }
6734
6735            if (changed) {
6736                updateOomAdjLocked();
6737            }
6738        }
6739    }
6740
6741    // =========================================================
6742    // PERMISSIONS
6743    // =========================================================
6744
6745    static class PermissionController extends IPermissionController.Stub {
6746        ActivityManagerService mActivityManagerService;
6747        PermissionController(ActivityManagerService activityManagerService) {
6748            mActivityManagerService = activityManagerService;
6749        }
6750
6751        @Override
6752        public boolean checkPermission(String permission, int pid, int uid) {
6753            return mActivityManagerService.checkPermission(permission, pid,
6754                    uid) == PackageManager.PERMISSION_GRANTED;
6755        }
6756    }
6757
6758    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6759        @Override
6760        public int checkComponentPermission(String permission, int pid, int uid,
6761                int owningUid, boolean exported) {
6762            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6763                    owningUid, exported);
6764        }
6765
6766        @Override
6767        public Object getAMSLock() {
6768            return ActivityManagerService.this;
6769        }
6770    }
6771
6772    /**
6773     * This can be called with or without the global lock held.
6774     */
6775    int checkComponentPermission(String permission, int pid, int uid,
6776            int owningUid, boolean exported) {
6777        // We might be performing an operation on behalf of an indirect binder
6778        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6779        // client identity accordingly before proceeding.
6780        Identity tlsIdentity = sCallerIdentity.get();
6781        if (tlsIdentity != null) {
6782            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6783                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6784            uid = tlsIdentity.uid;
6785            pid = tlsIdentity.pid;
6786        }
6787
6788        if (pid == MY_PID) {
6789            return PackageManager.PERMISSION_GRANTED;
6790        }
6791
6792        return ActivityManager.checkComponentPermission(permission, uid,
6793                owningUid, exported);
6794    }
6795
6796    /**
6797     * As the only public entry point for permissions checking, this method
6798     * can enforce the semantic that requesting a check on a null global
6799     * permission is automatically denied.  (Internally a null permission
6800     * string is used when calling {@link #checkComponentPermission} in cases
6801     * when only uid-based security is needed.)
6802     *
6803     * This can be called with or without the global lock held.
6804     */
6805    @Override
6806    public int checkPermission(String permission, int pid, int uid) {
6807        if (permission == null) {
6808            return PackageManager.PERMISSION_DENIED;
6809        }
6810        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6811    }
6812
6813    /**
6814     * Binder IPC calls go through the public entry point.
6815     * This can be called with or without the global lock held.
6816     */
6817    int checkCallingPermission(String permission) {
6818        return checkPermission(permission,
6819                Binder.getCallingPid(),
6820                UserHandle.getAppId(Binder.getCallingUid()));
6821    }
6822
6823    /**
6824     * This can be called with or without the global lock held.
6825     */
6826    void enforceCallingPermission(String permission, String func) {
6827        if (checkCallingPermission(permission)
6828                == PackageManager.PERMISSION_GRANTED) {
6829            return;
6830        }
6831
6832        String msg = "Permission Denial: " + func + " from pid="
6833                + Binder.getCallingPid()
6834                + ", uid=" + Binder.getCallingUid()
6835                + " requires " + permission;
6836        Slog.w(TAG, msg);
6837        throw new SecurityException(msg);
6838    }
6839
6840    /**
6841     * Determine if UID is holding permissions required to access {@link Uri} in
6842     * the given {@link ProviderInfo}. Final permission checking is always done
6843     * in {@link ContentProvider}.
6844     */
6845    private final boolean checkHoldingPermissionsLocked(
6846            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6847        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6848                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6849        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6850            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6851                    != PERMISSION_GRANTED) {
6852                return false;
6853            }
6854        }
6855        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6856    }
6857
6858    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6859            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6860        if (pi.applicationInfo.uid == uid) {
6861            return true;
6862        } else if (!pi.exported) {
6863            return false;
6864        }
6865
6866        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6867        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6868        try {
6869            // check if target holds top-level <provider> permissions
6870            if (!readMet && pi.readPermission != null && considerUidPermissions
6871                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6872                readMet = true;
6873            }
6874            if (!writeMet && pi.writePermission != null && considerUidPermissions
6875                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6876                writeMet = true;
6877            }
6878
6879            // track if unprotected read/write is allowed; any denied
6880            // <path-permission> below removes this ability
6881            boolean allowDefaultRead = pi.readPermission == null;
6882            boolean allowDefaultWrite = pi.writePermission == null;
6883
6884            // check if target holds any <path-permission> that match uri
6885            final PathPermission[] pps = pi.pathPermissions;
6886            if (pps != null) {
6887                final String path = grantUri.uri.getPath();
6888                int i = pps.length;
6889                while (i > 0 && (!readMet || !writeMet)) {
6890                    i--;
6891                    PathPermission pp = pps[i];
6892                    if (pp.match(path)) {
6893                        if (!readMet) {
6894                            final String pprperm = pp.getReadPermission();
6895                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6896                                    + pprperm + " for " + pp.getPath()
6897                                    + ": match=" + pp.match(path)
6898                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6899                            if (pprperm != null) {
6900                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6901                                        == PERMISSION_GRANTED) {
6902                                    readMet = true;
6903                                } else {
6904                                    allowDefaultRead = false;
6905                                }
6906                            }
6907                        }
6908                        if (!writeMet) {
6909                            final String ppwperm = pp.getWritePermission();
6910                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6911                                    + ppwperm + " for " + pp.getPath()
6912                                    + ": match=" + pp.match(path)
6913                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6914                            if (ppwperm != null) {
6915                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6916                                        == PERMISSION_GRANTED) {
6917                                    writeMet = true;
6918                                } else {
6919                                    allowDefaultWrite = false;
6920                                }
6921                            }
6922                        }
6923                    }
6924                }
6925            }
6926
6927            // grant unprotected <provider> read/write, if not blocked by
6928            // <path-permission> above
6929            if (allowDefaultRead) readMet = true;
6930            if (allowDefaultWrite) writeMet = true;
6931
6932        } catch (RemoteException e) {
6933            return false;
6934        }
6935
6936        return readMet && writeMet;
6937    }
6938
6939    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6940        ProviderInfo pi = null;
6941        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6942        if (cpr != null) {
6943            pi = cpr.info;
6944        } else {
6945            try {
6946                pi = AppGlobals.getPackageManager().resolveContentProvider(
6947                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6948            } catch (RemoteException ex) {
6949            }
6950        }
6951        return pi;
6952    }
6953
6954    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6955        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6956        if (targetUris != null) {
6957            return targetUris.get(grantUri);
6958        }
6959        return null;
6960    }
6961
6962    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6963            String targetPkg, int targetUid, GrantUri grantUri) {
6964        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6965        if (targetUris == null) {
6966            targetUris = Maps.newArrayMap();
6967            mGrantedUriPermissions.put(targetUid, targetUris);
6968        }
6969
6970        UriPermission perm = targetUris.get(grantUri);
6971        if (perm == null) {
6972            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6973            targetUris.put(grantUri, perm);
6974        }
6975
6976        return perm;
6977    }
6978
6979    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6980            final int modeFlags) {
6981        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6982        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6983                : UriPermission.STRENGTH_OWNED;
6984
6985        // Root gets to do everything.
6986        if (uid == 0) {
6987            return true;
6988        }
6989
6990        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6991        if (perms == null) return false;
6992
6993        // First look for exact match
6994        final UriPermission exactPerm = perms.get(grantUri);
6995        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6996            return true;
6997        }
6998
6999        // No exact match, look for prefixes
7000        final int N = perms.size();
7001        for (int i = 0; i < N; i++) {
7002            final UriPermission perm = perms.valueAt(i);
7003            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7004                    && perm.getStrength(modeFlags) >= minStrength) {
7005                return true;
7006            }
7007        }
7008
7009        return false;
7010    }
7011
7012    /**
7013     * @param uri This uri must NOT contain an embedded userId.
7014     * @param userId The userId in which the uri is to be resolved.
7015     */
7016    @Override
7017    public int checkUriPermission(Uri uri, int pid, int uid,
7018            final int modeFlags, int userId) {
7019        enforceNotIsolatedCaller("checkUriPermission");
7020
7021        // Another redirected-binder-call permissions check as in
7022        // {@link checkComponentPermission}.
7023        Identity tlsIdentity = sCallerIdentity.get();
7024        if (tlsIdentity != null) {
7025            uid = tlsIdentity.uid;
7026            pid = tlsIdentity.pid;
7027        }
7028
7029        // Our own process gets to do everything.
7030        if (pid == MY_PID) {
7031            return PackageManager.PERMISSION_GRANTED;
7032        }
7033        synchronized (this) {
7034            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7035                    ? PackageManager.PERMISSION_GRANTED
7036                    : PackageManager.PERMISSION_DENIED;
7037        }
7038    }
7039
7040    /**
7041     * Check if the targetPkg can be granted permission to access uri by
7042     * the callingUid using the given modeFlags.  Throws a security exception
7043     * if callingUid is not allowed to do this.  Returns the uid of the target
7044     * if the URI permission grant should be performed; returns -1 if it is not
7045     * needed (for example targetPkg already has permission to access the URI).
7046     * If you already know the uid of the target, you can supply it in
7047     * lastTargetUid else set that to -1.
7048     */
7049    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7050            final int modeFlags, int lastTargetUid) {
7051        if (!Intent.isAccessUriMode(modeFlags)) {
7052            return -1;
7053        }
7054
7055        if (targetPkg != null) {
7056            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7057                    "Checking grant " + targetPkg + " permission to " + grantUri);
7058        }
7059
7060        final IPackageManager pm = AppGlobals.getPackageManager();
7061
7062        // If this is not a content: uri, we can't do anything with it.
7063        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7064            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7065                    "Can't grant URI permission for non-content URI: " + grantUri);
7066            return -1;
7067        }
7068
7069        final String authority = grantUri.uri.getAuthority();
7070        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7071        if (pi == null) {
7072            Slog.w(TAG, "No content provider found for permission check: " +
7073                    grantUri.uri.toSafeString());
7074            return -1;
7075        }
7076
7077        int targetUid = lastTargetUid;
7078        if (targetUid < 0 && targetPkg != null) {
7079            try {
7080                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7081                if (targetUid < 0) {
7082                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7083                            "Can't grant URI permission no uid for: " + targetPkg);
7084                    return -1;
7085                }
7086            } catch (RemoteException ex) {
7087                return -1;
7088            }
7089        }
7090
7091        if (targetUid >= 0) {
7092            // First...  does the target actually need this permission?
7093            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7094                // No need to grant the target this permission.
7095                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7096                        "Target " + targetPkg + " already has full permission to " + grantUri);
7097                return -1;
7098            }
7099        } else {
7100            // First...  there is no target package, so can anyone access it?
7101            boolean allowed = pi.exported;
7102            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7103                if (pi.readPermission != null) {
7104                    allowed = false;
7105                }
7106            }
7107            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7108                if (pi.writePermission != null) {
7109                    allowed = false;
7110                }
7111            }
7112            if (allowed) {
7113                return -1;
7114            }
7115        }
7116
7117        /* There is a special cross user grant if:
7118         * - The target is on another user.
7119         * - Apps on the current user can access the uri without any uid permissions.
7120         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7121         * grant uri permissions.
7122         */
7123        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7124                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7125                modeFlags, false /*without considering the uid permissions*/);
7126
7127        // Second...  is the provider allowing granting of URI permissions?
7128        if (!specialCrossUserGrant) {
7129            if (!pi.grantUriPermissions) {
7130                throw new SecurityException("Provider " + pi.packageName
7131                        + "/" + pi.name
7132                        + " does not allow granting of Uri permissions (uri "
7133                        + grantUri + ")");
7134            }
7135            if (pi.uriPermissionPatterns != null) {
7136                final int N = pi.uriPermissionPatterns.length;
7137                boolean allowed = false;
7138                for (int i=0; i<N; i++) {
7139                    if (pi.uriPermissionPatterns[i] != null
7140                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7141                        allowed = true;
7142                        break;
7143                    }
7144                }
7145                if (!allowed) {
7146                    throw new SecurityException("Provider " + pi.packageName
7147                            + "/" + pi.name
7148                            + " does not allow granting of permission to path of Uri "
7149                            + grantUri);
7150                }
7151            }
7152        }
7153
7154        // Third...  does the caller itself have permission to access
7155        // this uri?
7156        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7157            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7158                // Require they hold a strong enough Uri permission
7159                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7160                    throw new SecurityException("Uid " + callingUid
7161                            + " does not have permission to uri " + grantUri);
7162                }
7163            }
7164        }
7165        return targetUid;
7166    }
7167
7168    /**
7169     * @param uri This uri must NOT contain an embedded userId.
7170     * @param userId The userId in which the uri is to be resolved.
7171     */
7172    @Override
7173    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7174            final int modeFlags, int userId) {
7175        enforceNotIsolatedCaller("checkGrantUriPermission");
7176        synchronized(this) {
7177            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7178                    new GrantUri(userId, uri, false), modeFlags, -1);
7179        }
7180    }
7181
7182    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7183            final int modeFlags, UriPermissionOwner owner) {
7184        if (!Intent.isAccessUriMode(modeFlags)) {
7185            return;
7186        }
7187
7188        // So here we are: the caller has the assumed permission
7189        // to the uri, and the target doesn't.  Let's now give this to
7190        // the target.
7191
7192        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7193                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7194
7195        final String authority = grantUri.uri.getAuthority();
7196        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7197        if (pi == null) {
7198            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7199            return;
7200        }
7201
7202        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7203            grantUri.prefix = true;
7204        }
7205        final UriPermission perm = findOrCreateUriPermissionLocked(
7206                pi.packageName, targetPkg, targetUid, grantUri);
7207        perm.grantModes(modeFlags, owner);
7208    }
7209
7210    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7211            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7212        if (targetPkg == null) {
7213            throw new NullPointerException("targetPkg");
7214        }
7215        int targetUid;
7216        final IPackageManager pm = AppGlobals.getPackageManager();
7217        try {
7218            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7219        } catch (RemoteException ex) {
7220            return;
7221        }
7222
7223        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7224                targetUid);
7225        if (targetUid < 0) {
7226            return;
7227        }
7228
7229        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7230                owner);
7231    }
7232
7233    static class NeededUriGrants extends ArrayList<GrantUri> {
7234        final String targetPkg;
7235        final int targetUid;
7236        final int flags;
7237
7238        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7239            this.targetPkg = targetPkg;
7240            this.targetUid = targetUid;
7241            this.flags = flags;
7242        }
7243    }
7244
7245    /**
7246     * Like checkGrantUriPermissionLocked, but takes an Intent.
7247     */
7248    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7249            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7250        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7251                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7252                + " clip=" + (intent != null ? intent.getClipData() : null)
7253                + " from " + intent + "; flags=0x"
7254                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7255
7256        if (targetPkg == null) {
7257            throw new NullPointerException("targetPkg");
7258        }
7259
7260        if (intent == null) {
7261            return null;
7262        }
7263        Uri data = intent.getData();
7264        ClipData clip = intent.getClipData();
7265        if (data == null && clip == null) {
7266            return null;
7267        }
7268        // Default userId for uris in the intent (if they don't specify it themselves)
7269        int contentUserHint = intent.getContentUserHint();
7270        if (contentUserHint == UserHandle.USER_CURRENT) {
7271            contentUserHint = UserHandle.getUserId(callingUid);
7272        }
7273        final IPackageManager pm = AppGlobals.getPackageManager();
7274        int targetUid;
7275        if (needed != null) {
7276            targetUid = needed.targetUid;
7277        } else {
7278            try {
7279                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7280            } catch (RemoteException ex) {
7281                return null;
7282            }
7283            if (targetUid < 0) {
7284                if (DEBUG_URI_PERMISSION) {
7285                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7286                            + " on user " + targetUserId);
7287                }
7288                return null;
7289            }
7290        }
7291        if (data != null) {
7292            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7293            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7294                    targetUid);
7295            if (targetUid > 0) {
7296                if (needed == null) {
7297                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7298                }
7299                needed.add(grantUri);
7300            }
7301        }
7302        if (clip != null) {
7303            for (int i=0; i<clip.getItemCount(); i++) {
7304                Uri uri = clip.getItemAt(i).getUri();
7305                if (uri != null) {
7306                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7307                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7308                            targetUid);
7309                    if (targetUid > 0) {
7310                        if (needed == null) {
7311                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7312                        }
7313                        needed.add(grantUri);
7314                    }
7315                } else {
7316                    Intent clipIntent = clip.getItemAt(i).getIntent();
7317                    if (clipIntent != null) {
7318                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7319                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7320                        if (newNeeded != null) {
7321                            needed = newNeeded;
7322                        }
7323                    }
7324                }
7325            }
7326        }
7327
7328        return needed;
7329    }
7330
7331    /**
7332     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7333     */
7334    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7335            UriPermissionOwner owner) {
7336        if (needed != null) {
7337            for (int i=0; i<needed.size(); i++) {
7338                GrantUri grantUri = needed.get(i);
7339                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7340                        grantUri, needed.flags, owner);
7341            }
7342        }
7343    }
7344
7345    void grantUriPermissionFromIntentLocked(int callingUid,
7346            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7347        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7348                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7349        if (needed == null) {
7350            return;
7351        }
7352
7353        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7354    }
7355
7356    /**
7357     * @param uri This uri must NOT contain an embedded userId.
7358     * @param userId The userId in which the uri is to be resolved.
7359     */
7360    @Override
7361    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7362            final int modeFlags, int userId) {
7363        enforceNotIsolatedCaller("grantUriPermission");
7364        GrantUri grantUri = new GrantUri(userId, uri, false);
7365        synchronized(this) {
7366            final ProcessRecord r = getRecordForAppLocked(caller);
7367            if (r == null) {
7368                throw new SecurityException("Unable to find app for caller "
7369                        + caller
7370                        + " when granting permission to uri " + grantUri);
7371            }
7372            if (targetPkg == null) {
7373                throw new IllegalArgumentException("null target");
7374            }
7375            if (grantUri == null) {
7376                throw new IllegalArgumentException("null uri");
7377            }
7378
7379            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7380                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7381                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7382                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7383
7384            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7385                    UserHandle.getUserId(r.uid));
7386        }
7387    }
7388
7389    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7390        if (perm.modeFlags == 0) {
7391            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7392                    perm.targetUid);
7393            if (perms != null) {
7394                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7395                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7396
7397                perms.remove(perm.uri);
7398                if (perms.isEmpty()) {
7399                    mGrantedUriPermissions.remove(perm.targetUid);
7400                }
7401            }
7402        }
7403    }
7404
7405    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7406        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7407
7408        final IPackageManager pm = AppGlobals.getPackageManager();
7409        final String authority = grantUri.uri.getAuthority();
7410        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7411        if (pi == null) {
7412            Slog.w(TAG, "No content provider found for permission revoke: "
7413                    + grantUri.toSafeString());
7414            return;
7415        }
7416
7417        // Does the caller have this permission on the URI?
7418        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7419            // Right now, if you are not the original owner of the permission,
7420            // you are not allowed to revoke it.
7421            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7422                throw new SecurityException("Uid " + callingUid
7423                        + " does not have permission to uri " + grantUri);
7424            //}
7425        }
7426
7427        boolean persistChanged = false;
7428
7429        // Go through all of the permissions and remove any that match.
7430        int N = mGrantedUriPermissions.size();
7431        for (int i = 0; i < N; i++) {
7432            final int targetUid = mGrantedUriPermissions.keyAt(i);
7433            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7434
7435            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7436                final UriPermission perm = it.next();
7437                if (perm.uri.sourceUserId == grantUri.sourceUserId
7438                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7439                    if (DEBUG_URI_PERMISSION)
7440                        Slog.v(TAG,
7441                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7442                    persistChanged |= perm.revokeModes(
7443                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7444                    if (perm.modeFlags == 0) {
7445                        it.remove();
7446                    }
7447                }
7448            }
7449
7450            if (perms.isEmpty()) {
7451                mGrantedUriPermissions.remove(targetUid);
7452                N--;
7453                i--;
7454            }
7455        }
7456
7457        if (persistChanged) {
7458            schedulePersistUriGrants();
7459        }
7460    }
7461
7462    /**
7463     * @param uri This uri must NOT contain an embedded userId.
7464     * @param userId The userId in which the uri is to be resolved.
7465     */
7466    @Override
7467    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7468            int userId) {
7469        enforceNotIsolatedCaller("revokeUriPermission");
7470        synchronized(this) {
7471            final ProcessRecord r = getRecordForAppLocked(caller);
7472            if (r == null) {
7473                throw new SecurityException("Unable to find app for caller "
7474                        + caller
7475                        + " when revoking permission to uri " + uri);
7476            }
7477            if (uri == null) {
7478                Slog.w(TAG, "revokeUriPermission: null uri");
7479                return;
7480            }
7481
7482            if (!Intent.isAccessUriMode(modeFlags)) {
7483                return;
7484            }
7485
7486            final IPackageManager pm = AppGlobals.getPackageManager();
7487            final String authority = uri.getAuthority();
7488            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7489            if (pi == null) {
7490                Slog.w(TAG, "No content provider found for permission revoke: "
7491                        + uri.toSafeString());
7492                return;
7493            }
7494
7495            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7496        }
7497    }
7498
7499    /**
7500     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7501     * given package.
7502     *
7503     * @param packageName Package name to match, or {@code null} to apply to all
7504     *            packages.
7505     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7506     *            to all users.
7507     * @param persistable If persistable grants should be removed.
7508     */
7509    private void removeUriPermissionsForPackageLocked(
7510            String packageName, int userHandle, boolean persistable) {
7511        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7512            throw new IllegalArgumentException("Must narrow by either package or user");
7513        }
7514
7515        boolean persistChanged = false;
7516
7517        int N = mGrantedUriPermissions.size();
7518        for (int i = 0; i < N; i++) {
7519            final int targetUid = mGrantedUriPermissions.keyAt(i);
7520            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7521
7522            // Only inspect grants matching user
7523            if (userHandle == UserHandle.USER_ALL
7524                    || userHandle == UserHandle.getUserId(targetUid)) {
7525                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7526                    final UriPermission perm = it.next();
7527
7528                    // Only inspect grants matching package
7529                    if (packageName == null || perm.sourcePkg.equals(packageName)
7530                            || perm.targetPkg.equals(packageName)) {
7531                        persistChanged |= perm.revokeModes(
7532                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7533
7534                        // Only remove when no modes remain; any persisted grants
7535                        // will keep this alive.
7536                        if (perm.modeFlags == 0) {
7537                            it.remove();
7538                        }
7539                    }
7540                }
7541
7542                if (perms.isEmpty()) {
7543                    mGrantedUriPermissions.remove(targetUid);
7544                    N--;
7545                    i--;
7546                }
7547            }
7548        }
7549
7550        if (persistChanged) {
7551            schedulePersistUriGrants();
7552        }
7553    }
7554
7555    @Override
7556    public IBinder newUriPermissionOwner(String name) {
7557        enforceNotIsolatedCaller("newUriPermissionOwner");
7558        synchronized(this) {
7559            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7560            return owner.getExternalTokenLocked();
7561        }
7562    }
7563
7564    /**
7565     * @param uri This uri must NOT contain an embedded userId.
7566     * @param sourceUserId The userId in which the uri is to be resolved.
7567     * @param targetUserId The userId of the app that receives the grant.
7568     */
7569    @Override
7570    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7571            final int modeFlags, int sourceUserId, int targetUserId) {
7572        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7573                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7574        synchronized(this) {
7575            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7576            if (owner == null) {
7577                throw new IllegalArgumentException("Unknown owner: " + token);
7578            }
7579            if (fromUid != Binder.getCallingUid()) {
7580                if (Binder.getCallingUid() != Process.myUid()) {
7581                    // Only system code can grant URI permissions on behalf
7582                    // of other users.
7583                    throw new SecurityException("nice try");
7584                }
7585            }
7586            if (targetPkg == null) {
7587                throw new IllegalArgumentException("null target");
7588            }
7589            if (uri == null) {
7590                throw new IllegalArgumentException("null uri");
7591            }
7592
7593            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7594                    modeFlags, owner, targetUserId);
7595        }
7596    }
7597
7598    /**
7599     * @param uri This uri must NOT contain an embedded userId.
7600     * @param userId The userId in which the uri is to be resolved.
7601     */
7602    @Override
7603    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7604        synchronized(this) {
7605            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7606            if (owner == null) {
7607                throw new IllegalArgumentException("Unknown owner: " + token);
7608            }
7609
7610            if (uri == null) {
7611                owner.removeUriPermissionsLocked(mode);
7612            } else {
7613                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7614            }
7615        }
7616    }
7617
7618    private void schedulePersistUriGrants() {
7619        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7620            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7621                    10 * DateUtils.SECOND_IN_MILLIS);
7622        }
7623    }
7624
7625    private void writeGrantedUriPermissions() {
7626        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7627
7628        // Snapshot permissions so we can persist without lock
7629        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7630        synchronized (this) {
7631            final int size = mGrantedUriPermissions.size();
7632            for (int i = 0; i < size; i++) {
7633                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7634                for (UriPermission perm : perms.values()) {
7635                    if (perm.persistedModeFlags != 0) {
7636                        persist.add(perm.snapshot());
7637                    }
7638                }
7639            }
7640        }
7641
7642        FileOutputStream fos = null;
7643        try {
7644            fos = mGrantFile.startWrite();
7645
7646            XmlSerializer out = new FastXmlSerializer();
7647            out.setOutput(fos, "utf-8");
7648            out.startDocument(null, true);
7649            out.startTag(null, TAG_URI_GRANTS);
7650            for (UriPermission.Snapshot perm : persist) {
7651                out.startTag(null, TAG_URI_GRANT);
7652                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7653                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7654                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7655                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7656                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7657                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7658                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7659                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7660                out.endTag(null, TAG_URI_GRANT);
7661            }
7662            out.endTag(null, TAG_URI_GRANTS);
7663            out.endDocument();
7664
7665            mGrantFile.finishWrite(fos);
7666        } catch (IOException e) {
7667            if (fos != null) {
7668                mGrantFile.failWrite(fos);
7669            }
7670        }
7671    }
7672
7673    private void readGrantedUriPermissionsLocked() {
7674        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7675
7676        final long now = System.currentTimeMillis();
7677
7678        FileInputStream fis = null;
7679        try {
7680            fis = mGrantFile.openRead();
7681            final XmlPullParser in = Xml.newPullParser();
7682            in.setInput(fis, null);
7683
7684            int type;
7685            while ((type = in.next()) != END_DOCUMENT) {
7686                final String tag = in.getName();
7687                if (type == START_TAG) {
7688                    if (TAG_URI_GRANT.equals(tag)) {
7689                        final int sourceUserId;
7690                        final int targetUserId;
7691                        final int userHandle = readIntAttribute(in,
7692                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7693                        if (userHandle != UserHandle.USER_NULL) {
7694                            // For backwards compatibility.
7695                            sourceUserId = userHandle;
7696                            targetUserId = userHandle;
7697                        } else {
7698                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7699                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7700                        }
7701                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7702                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7703                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7704                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7705                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7706                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7707
7708                        // Sanity check that provider still belongs to source package
7709                        final ProviderInfo pi = getProviderInfoLocked(
7710                                uri.getAuthority(), sourceUserId);
7711                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7712                            int targetUid = -1;
7713                            try {
7714                                targetUid = AppGlobals.getPackageManager()
7715                                        .getPackageUid(targetPkg, targetUserId);
7716                            } catch (RemoteException e) {
7717                            }
7718                            if (targetUid != -1) {
7719                                final UriPermission perm = findOrCreateUriPermissionLocked(
7720                                        sourcePkg, targetPkg, targetUid,
7721                                        new GrantUri(sourceUserId, uri, prefix));
7722                                perm.initPersistedModes(modeFlags, createdTime);
7723                            }
7724                        } else {
7725                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7726                                    + " but instead found " + pi);
7727                        }
7728                    }
7729                }
7730            }
7731        } catch (FileNotFoundException e) {
7732            // Missing grants is okay
7733        } catch (IOException e) {
7734            Log.wtf(TAG, "Failed reading Uri grants", e);
7735        } catch (XmlPullParserException e) {
7736            Log.wtf(TAG, "Failed reading Uri grants", e);
7737        } finally {
7738            IoUtils.closeQuietly(fis);
7739        }
7740    }
7741
7742    /**
7743     * @param uri This uri must NOT contain an embedded userId.
7744     * @param userId The userId in which the uri is to be resolved.
7745     */
7746    @Override
7747    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7748        enforceNotIsolatedCaller("takePersistableUriPermission");
7749
7750        Preconditions.checkFlagsArgument(modeFlags,
7751                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7752
7753        synchronized (this) {
7754            final int callingUid = Binder.getCallingUid();
7755            boolean persistChanged = false;
7756            GrantUri grantUri = new GrantUri(userId, uri, false);
7757
7758            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7759                    new GrantUri(userId, uri, false));
7760            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7761                    new GrantUri(userId, uri, true));
7762
7763            final boolean exactValid = (exactPerm != null)
7764                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7765            final boolean prefixValid = (prefixPerm != null)
7766                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7767
7768            if (!(exactValid || prefixValid)) {
7769                throw new SecurityException("No persistable permission grants found for UID "
7770                        + callingUid + " and Uri " + grantUri.toSafeString());
7771            }
7772
7773            if (exactValid) {
7774                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7775            }
7776            if (prefixValid) {
7777                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7778            }
7779
7780            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7781
7782            if (persistChanged) {
7783                schedulePersistUriGrants();
7784            }
7785        }
7786    }
7787
7788    /**
7789     * @param uri This uri must NOT contain an embedded userId.
7790     * @param userId The userId in which the uri is to be resolved.
7791     */
7792    @Override
7793    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7794        enforceNotIsolatedCaller("releasePersistableUriPermission");
7795
7796        Preconditions.checkFlagsArgument(modeFlags,
7797                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7798
7799        synchronized (this) {
7800            final int callingUid = Binder.getCallingUid();
7801            boolean persistChanged = false;
7802
7803            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7804                    new GrantUri(userId, uri, false));
7805            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7806                    new GrantUri(userId, uri, true));
7807            if (exactPerm == null && prefixPerm == null) {
7808                throw new SecurityException("No permission grants found for UID " + callingUid
7809                        + " and Uri " + uri.toSafeString());
7810            }
7811
7812            if (exactPerm != null) {
7813                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7814                removeUriPermissionIfNeededLocked(exactPerm);
7815            }
7816            if (prefixPerm != null) {
7817                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7818                removeUriPermissionIfNeededLocked(prefixPerm);
7819            }
7820
7821            if (persistChanged) {
7822                schedulePersistUriGrants();
7823            }
7824        }
7825    }
7826
7827    /**
7828     * Prune any older {@link UriPermission} for the given UID until outstanding
7829     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7830     *
7831     * @return if any mutations occured that require persisting.
7832     */
7833    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7834        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7835        if (perms == null) return false;
7836        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7837
7838        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7839        for (UriPermission perm : perms.values()) {
7840            if (perm.persistedModeFlags != 0) {
7841                persisted.add(perm);
7842            }
7843        }
7844
7845        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7846        if (trimCount <= 0) return false;
7847
7848        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7849        for (int i = 0; i < trimCount; i++) {
7850            final UriPermission perm = persisted.get(i);
7851
7852            if (DEBUG_URI_PERMISSION) {
7853                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7854            }
7855
7856            perm.releasePersistableModes(~0);
7857            removeUriPermissionIfNeededLocked(perm);
7858        }
7859
7860        return true;
7861    }
7862
7863    @Override
7864    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7865            String packageName, boolean incoming) {
7866        enforceNotIsolatedCaller("getPersistedUriPermissions");
7867        Preconditions.checkNotNull(packageName, "packageName");
7868
7869        final int callingUid = Binder.getCallingUid();
7870        final IPackageManager pm = AppGlobals.getPackageManager();
7871        try {
7872            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7873            if (packageUid != callingUid) {
7874                throw new SecurityException(
7875                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7876            }
7877        } catch (RemoteException e) {
7878            throw new SecurityException("Failed to verify package name ownership");
7879        }
7880
7881        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7882        synchronized (this) {
7883            if (incoming) {
7884                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7885                        callingUid);
7886                if (perms == null) {
7887                    Slog.w(TAG, "No permission grants found for " + packageName);
7888                } else {
7889                    for (UriPermission perm : perms.values()) {
7890                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7891                            result.add(perm.buildPersistedPublicApiObject());
7892                        }
7893                    }
7894                }
7895            } else {
7896                final int size = mGrantedUriPermissions.size();
7897                for (int i = 0; i < size; i++) {
7898                    final ArrayMap<GrantUri, UriPermission> perms =
7899                            mGrantedUriPermissions.valueAt(i);
7900                    for (UriPermission perm : perms.values()) {
7901                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7902                            result.add(perm.buildPersistedPublicApiObject());
7903                        }
7904                    }
7905                }
7906            }
7907        }
7908        return new ParceledListSlice<android.content.UriPermission>(result);
7909    }
7910
7911    @Override
7912    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7913        synchronized (this) {
7914            ProcessRecord app =
7915                who != null ? getRecordForAppLocked(who) : null;
7916            if (app == null) return;
7917
7918            Message msg = Message.obtain();
7919            msg.what = WAIT_FOR_DEBUGGER_MSG;
7920            msg.obj = app;
7921            msg.arg1 = waiting ? 1 : 0;
7922            mHandler.sendMessage(msg);
7923        }
7924    }
7925
7926    @Override
7927    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7928        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7929        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7930        outInfo.availMem = Process.getFreeMemory();
7931        outInfo.totalMem = Process.getTotalMemory();
7932        outInfo.threshold = homeAppMem;
7933        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7934        outInfo.hiddenAppThreshold = cachedAppMem;
7935        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7936                ProcessList.SERVICE_ADJ);
7937        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7938                ProcessList.VISIBLE_APP_ADJ);
7939        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7940                ProcessList.FOREGROUND_APP_ADJ);
7941    }
7942
7943    // =========================================================
7944    // TASK MANAGEMENT
7945    // =========================================================
7946
7947    @Override
7948    public List<IAppTask> getAppTasks(String callingPackage) {
7949        int callingUid = Binder.getCallingUid();
7950        long ident = Binder.clearCallingIdentity();
7951
7952        synchronized(this) {
7953            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7954            try {
7955                if (localLOGV) Slog.v(TAG, "getAppTasks");
7956
7957                final int N = mRecentTasks.size();
7958                for (int i = 0; i < N; i++) {
7959                    TaskRecord tr = mRecentTasks.get(i);
7960                    // Skip tasks that do not match the caller.  We don't need to verify
7961                    // callingPackage, because we are also limiting to callingUid and know
7962                    // that will limit to the correct security sandbox.
7963                    if (tr.effectiveUid != callingUid) {
7964                        continue;
7965                    }
7966                    Intent intent = tr.getBaseIntent();
7967                    if (intent == null ||
7968                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7969                        continue;
7970                    }
7971                    ActivityManager.RecentTaskInfo taskInfo =
7972                            createRecentTaskInfoFromTaskRecord(tr);
7973                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7974                    list.add(taskImpl);
7975                }
7976            } finally {
7977                Binder.restoreCallingIdentity(ident);
7978            }
7979            return list;
7980        }
7981    }
7982
7983    @Override
7984    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7985        final int callingUid = Binder.getCallingUid();
7986        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7987
7988        synchronized(this) {
7989            if (localLOGV) Slog.v(
7990                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7991
7992            final boolean allowed = checkCallingPermission(
7993                    android.Manifest.permission.GET_TASKS)
7994                    == PackageManager.PERMISSION_GRANTED;
7995            if (!allowed) {
7996                Slog.w(TAG, "getTasks: caller " + callingUid
7997                        + " does not hold GET_TASKS; limiting output");
7998            }
7999
8000            // TODO: Improve with MRU list from all ActivityStacks.
8001            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8002        }
8003
8004        return list;
8005    }
8006
8007    TaskRecord getMostRecentTask() {
8008        return mRecentTasks.get(0);
8009    }
8010
8011    /**
8012     * Creates a new RecentTaskInfo from a TaskRecord.
8013     */
8014    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8015        // Update the task description to reflect any changes in the task stack
8016        tr.updateTaskDescription();
8017
8018        // Compose the recent task info
8019        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8020        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8021        rti.persistentId = tr.taskId;
8022        rti.baseIntent = new Intent(tr.getBaseIntent());
8023        rti.origActivity = tr.origActivity;
8024        rti.description = tr.lastDescription;
8025        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8026        rti.userId = tr.userId;
8027        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8028        rti.firstActiveTime = tr.firstActiveTime;
8029        rti.lastActiveTime = tr.lastActiveTime;
8030        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8031        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8032        return rti;
8033    }
8034
8035    @Override
8036    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8037        final int callingUid = Binder.getCallingUid();
8038        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8039                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8040
8041        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8042        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8043        synchronized (this) {
8044            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8045                    == PackageManager.PERMISSION_GRANTED;
8046            if (!allowed) {
8047                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8048                        + " does not hold GET_TASKS; limiting output");
8049            }
8050            final boolean detailed = checkCallingPermission(
8051                    android.Manifest.permission.GET_DETAILED_TASKS)
8052                    == PackageManager.PERMISSION_GRANTED;
8053
8054            final int N = mRecentTasks.size();
8055            ArrayList<ActivityManager.RecentTaskInfo> res
8056                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8057                            maxNum < N ? maxNum : N);
8058
8059            final Set<Integer> includedUsers;
8060            if (includeProfiles) {
8061                includedUsers = getProfileIdsLocked(userId);
8062            } else {
8063                includedUsers = new HashSet<Integer>();
8064            }
8065            includedUsers.add(Integer.valueOf(userId));
8066
8067            for (int i=0; i<N && maxNum > 0; i++) {
8068                TaskRecord tr = mRecentTasks.get(i);
8069                // Only add calling user or related users recent tasks
8070                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8071                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8072                    continue;
8073                }
8074
8075                // Return the entry if desired by the caller.  We always return
8076                // the first entry, because callers always expect this to be the
8077                // foreground app.  We may filter others if the caller has
8078                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8079                // we should exclude the entry.
8080
8081                if (i == 0
8082                        || withExcluded
8083                        || (tr.intent == null)
8084                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8085                                == 0)) {
8086                    if (!allowed) {
8087                        // If the caller doesn't have the GET_TASKS permission, then only
8088                        // allow them to see a small subset of tasks -- their own and home.
8089                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8090                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8091                            continue;
8092                        }
8093                    }
8094                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8095                        if (tr.stack != null && tr.stack.isHomeStack()) {
8096                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8097                            continue;
8098                        }
8099                    }
8100                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8101                        // Don't include auto remove tasks that are finished or finishing.
8102                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8103                                + tr);
8104                        continue;
8105                    }
8106                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8107                            && !tr.isAvailable) {
8108                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8109                        continue;
8110                    }
8111
8112                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8113                    if (!detailed) {
8114                        rti.baseIntent.replaceExtras((Bundle)null);
8115                    }
8116
8117                    res.add(rti);
8118                    maxNum--;
8119                }
8120            }
8121            return res;
8122        }
8123    }
8124
8125    private TaskRecord recentTaskForIdLocked(int id) {
8126        final int N = mRecentTasks.size();
8127            for (int i=0; i<N; i++) {
8128                TaskRecord tr = mRecentTasks.get(i);
8129                if (tr.taskId == id) {
8130                    return tr;
8131                }
8132            }
8133            return null;
8134    }
8135
8136    @Override
8137    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8138        synchronized (this) {
8139            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8140                    "getTaskThumbnail()");
8141            TaskRecord tr = recentTaskForIdLocked(id);
8142            if (tr != null) {
8143                return tr.getTaskThumbnailLocked();
8144            }
8145        }
8146        return null;
8147    }
8148
8149    @Override
8150    public int addAppTask(IBinder activityToken, Intent intent,
8151            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8152        final int callingUid = Binder.getCallingUid();
8153        final long callingIdent = Binder.clearCallingIdentity();
8154
8155        try {
8156            synchronized (this) {
8157                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8158                if (r == null) {
8159                    throw new IllegalArgumentException("Activity does not exist; token="
8160                            + activityToken);
8161                }
8162                ComponentName comp = intent.getComponent();
8163                if (comp == null) {
8164                    throw new IllegalArgumentException("Intent " + intent
8165                            + " must specify explicit component");
8166                }
8167                if (thumbnail.getWidth() != mThumbnailWidth
8168                        || thumbnail.getHeight() != mThumbnailHeight) {
8169                    throw new IllegalArgumentException("Bad thumbnail size: got "
8170                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8171                            + mThumbnailWidth + "x" + mThumbnailHeight);
8172                }
8173                if (intent.getSelector() != null) {
8174                    intent.setSelector(null);
8175                }
8176                if (intent.getSourceBounds() != null) {
8177                    intent.setSourceBounds(null);
8178                }
8179                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8180                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8181                        // The caller has added this as an auto-remove task...  that makes no
8182                        // sense, so turn off auto-remove.
8183                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8184                    }
8185                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8186                    // Must be a new task.
8187                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8188                }
8189                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8190                    mLastAddedTaskActivity = null;
8191                }
8192                ActivityInfo ainfo = mLastAddedTaskActivity;
8193                if (ainfo == null) {
8194                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8195                            comp, 0, UserHandle.getUserId(callingUid));
8196                    if (ainfo.applicationInfo.uid != callingUid) {
8197                        throw new SecurityException(
8198                                "Can't add task for another application: target uid="
8199                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8200                    }
8201                }
8202
8203                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8204                        intent, description);
8205
8206                int trimIdx = trimRecentsForTask(task, false);
8207                if (trimIdx >= 0) {
8208                    // If this would have caused a trim, then we'll abort because that
8209                    // means it would be added at the end of the list but then just removed.
8210                    return -1;
8211                }
8212
8213                final int N = mRecentTasks.size();
8214                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8215                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8216                    tr.removedFromRecents(mTaskPersister);
8217                }
8218
8219                task.inRecents = true;
8220                mRecentTasks.add(task);
8221                r.task.stack.addTask(task, false, false);
8222
8223                task.setLastThumbnail(thumbnail);
8224                task.freeLastThumbnail();
8225
8226                return task.taskId;
8227            }
8228        } finally {
8229            Binder.restoreCallingIdentity(callingIdent);
8230        }
8231    }
8232
8233    @Override
8234    public Point getAppTaskThumbnailSize() {
8235        synchronized (this) {
8236            return new Point(mThumbnailWidth,  mThumbnailHeight);
8237        }
8238    }
8239
8240    @Override
8241    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8242        synchronized (this) {
8243            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8244            if (r != null) {
8245                r.taskDescription = td;
8246                r.task.updateTaskDescription();
8247            }
8248        }
8249    }
8250
8251    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8252        mRecentTasks.remove(tr);
8253        tr.removedFromRecents(mTaskPersister);
8254        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8255        Intent baseIntent = new Intent(
8256                tr.intent != null ? tr.intent : tr.affinityIntent);
8257        ComponentName component = baseIntent.getComponent();
8258        if (component == null) {
8259            Slog.w(TAG, "Now component for base intent of task: " + tr);
8260            return;
8261        }
8262
8263        // Find any running services associated with this app.
8264        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8265
8266        if (killProcesses) {
8267            // Find any running processes associated with this app.
8268            final String pkg = component.getPackageName();
8269            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8270            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8271            for (int i=0; i<pmap.size(); i++) {
8272                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8273                for (int j=0; j<uids.size(); j++) {
8274                    ProcessRecord proc = uids.valueAt(j);
8275                    if (proc.userId != tr.userId) {
8276                        continue;
8277                    }
8278                    if (!proc.pkgList.containsKey(pkg)) {
8279                        continue;
8280                    }
8281                    procs.add(proc);
8282                }
8283            }
8284
8285            // Kill the running processes.
8286            for (int i=0; i<procs.size(); i++) {
8287                ProcessRecord pr = procs.get(i);
8288                if (pr == mHomeProcess) {
8289                    // Don't kill the home process along with tasks from the same package.
8290                    continue;
8291                }
8292                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8293                    pr.kill("remove task", true);
8294                } else {
8295                    pr.waitingToKill = "remove task";
8296                }
8297            }
8298        }
8299    }
8300
8301    /**
8302     * Removes the task with the specified task id.
8303     *
8304     * @param taskId Identifier of the task to be removed.
8305     * @param flags Additional operational flags.  May be 0 or
8306     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8307     * @return Returns true if the given task was found and removed.
8308     */
8309    private boolean removeTaskByIdLocked(int taskId, int flags) {
8310        TaskRecord tr = recentTaskForIdLocked(taskId);
8311        if (tr != null) {
8312            tr.removeTaskActivitiesLocked();
8313            cleanUpRemovedTaskLocked(tr, flags);
8314            if (tr.isPersistable) {
8315                notifyTaskPersisterLocked(null, true);
8316            }
8317            return true;
8318        }
8319        return false;
8320    }
8321
8322    @Override
8323    public boolean removeTask(int taskId, int flags) {
8324        synchronized (this) {
8325            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8326                    "removeTask()");
8327            long ident = Binder.clearCallingIdentity();
8328            try {
8329                return removeTaskByIdLocked(taskId, flags);
8330            } finally {
8331                Binder.restoreCallingIdentity(ident);
8332            }
8333        }
8334    }
8335
8336    /**
8337     * TODO: Add mController hook
8338     */
8339    @Override
8340    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8341        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8342                "moveTaskToFront()");
8343
8344        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8345        synchronized(this) {
8346            moveTaskToFrontLocked(taskId, flags, options);
8347        }
8348    }
8349
8350    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8351        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8352                Binder.getCallingUid(), "Task to front")) {
8353            ActivityOptions.abort(options);
8354            return;
8355        }
8356        final long origId = Binder.clearCallingIdentity();
8357        try {
8358            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8359            if (task == null) {
8360                return;
8361            }
8362            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8363                mStackSupervisor.showLockTaskToast();
8364                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8365                return;
8366            }
8367            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8368            if (prev != null && prev.isRecentsActivity()) {
8369                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8370            }
8371            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8372        } finally {
8373            Binder.restoreCallingIdentity(origId);
8374        }
8375        ActivityOptions.abort(options);
8376    }
8377
8378    @Override
8379    public void moveTaskToBack(int taskId) {
8380        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8381                "moveTaskToBack()");
8382
8383        synchronized(this) {
8384            TaskRecord tr = recentTaskForIdLocked(taskId);
8385            if (tr != null) {
8386                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8387                ActivityStack stack = tr.stack;
8388                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8389                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8390                            Binder.getCallingUid(), "Task to back")) {
8391                        return;
8392                    }
8393                }
8394                final long origId = Binder.clearCallingIdentity();
8395                try {
8396                    stack.moveTaskToBackLocked(taskId, null);
8397                } finally {
8398                    Binder.restoreCallingIdentity(origId);
8399                }
8400            }
8401        }
8402    }
8403
8404    /**
8405     * Moves an activity, and all of the other activities within the same task, to the bottom
8406     * of the history stack.  The activity's order within the task is unchanged.
8407     *
8408     * @param token A reference to the activity we wish to move
8409     * @param nonRoot If false then this only works if the activity is the root
8410     *                of a task; if true it will work for any activity in a task.
8411     * @return Returns true if the move completed, false if not.
8412     */
8413    @Override
8414    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8415        enforceNotIsolatedCaller("moveActivityTaskToBack");
8416        synchronized(this) {
8417            final long origId = Binder.clearCallingIdentity();
8418            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8419            if (taskId >= 0) {
8420                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8421            }
8422            Binder.restoreCallingIdentity(origId);
8423        }
8424        return false;
8425    }
8426
8427    @Override
8428    public void moveTaskBackwards(int task) {
8429        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8430                "moveTaskBackwards()");
8431
8432        synchronized(this) {
8433            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8434                    Binder.getCallingUid(), "Task backwards")) {
8435                return;
8436            }
8437            final long origId = Binder.clearCallingIdentity();
8438            moveTaskBackwardsLocked(task);
8439            Binder.restoreCallingIdentity(origId);
8440        }
8441    }
8442
8443    private final void moveTaskBackwardsLocked(int task) {
8444        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8445    }
8446
8447    @Override
8448    public IBinder getHomeActivityToken() throws RemoteException {
8449        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8450                "getHomeActivityToken()");
8451        synchronized (this) {
8452            return mStackSupervisor.getHomeActivityToken();
8453        }
8454    }
8455
8456    @Override
8457    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8458            IActivityContainerCallback callback) throws RemoteException {
8459        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8460                "createActivityContainer()");
8461        synchronized (this) {
8462            if (parentActivityToken == null) {
8463                throw new IllegalArgumentException("parent token must not be null");
8464            }
8465            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8466            if (r == null) {
8467                return null;
8468            }
8469            if (callback == null) {
8470                throw new IllegalArgumentException("callback must not be null");
8471            }
8472            return mStackSupervisor.createActivityContainer(r, callback);
8473        }
8474    }
8475
8476    @Override
8477    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8478        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8479                "deleteActivityContainer()");
8480        synchronized (this) {
8481            mStackSupervisor.deleteActivityContainer(container);
8482        }
8483    }
8484
8485    @Override
8486    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8487            throws RemoteException {
8488        synchronized (this) {
8489            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8490            if (stack != null) {
8491                return stack.mActivityContainer;
8492            }
8493            return null;
8494        }
8495    }
8496
8497    @Override
8498    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8499        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8500                "moveTaskToStack()");
8501        if (stackId == HOME_STACK_ID) {
8502            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8503                    new RuntimeException("here").fillInStackTrace());
8504        }
8505        synchronized (this) {
8506            long ident = Binder.clearCallingIdentity();
8507            try {
8508                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8509                        + stackId + " toTop=" + toTop);
8510                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8511            } finally {
8512                Binder.restoreCallingIdentity(ident);
8513            }
8514        }
8515    }
8516
8517    @Override
8518    public void resizeStack(int stackBoxId, Rect bounds) {
8519        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8520                "resizeStackBox()");
8521        long ident = Binder.clearCallingIdentity();
8522        try {
8523            mWindowManager.resizeStack(stackBoxId, bounds);
8524        } finally {
8525            Binder.restoreCallingIdentity(ident);
8526        }
8527    }
8528
8529    @Override
8530    public List<StackInfo> getAllStackInfos() {
8531        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8532                "getAllStackInfos()");
8533        long ident = Binder.clearCallingIdentity();
8534        try {
8535            synchronized (this) {
8536                return mStackSupervisor.getAllStackInfosLocked();
8537            }
8538        } finally {
8539            Binder.restoreCallingIdentity(ident);
8540        }
8541    }
8542
8543    @Override
8544    public StackInfo getStackInfo(int stackId) {
8545        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8546                "getStackInfo()");
8547        long ident = Binder.clearCallingIdentity();
8548        try {
8549            synchronized (this) {
8550                return mStackSupervisor.getStackInfoLocked(stackId);
8551            }
8552        } finally {
8553            Binder.restoreCallingIdentity(ident);
8554        }
8555    }
8556
8557    @Override
8558    public boolean isInHomeStack(int taskId) {
8559        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8560                "getStackInfo()");
8561        long ident = Binder.clearCallingIdentity();
8562        try {
8563            synchronized (this) {
8564                TaskRecord tr = recentTaskForIdLocked(taskId);
8565                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8566            }
8567        } finally {
8568            Binder.restoreCallingIdentity(ident);
8569        }
8570    }
8571
8572    @Override
8573    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8574        synchronized(this) {
8575            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8576        }
8577    }
8578
8579    private boolean isLockTaskAuthorized(String pkg) {
8580        final DevicePolicyManager dpm = (DevicePolicyManager)
8581                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8582        try {
8583            int uid = mContext.getPackageManager().getPackageUid(pkg,
8584                    Binder.getCallingUserHandle().getIdentifier());
8585            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8586        } catch (NameNotFoundException e) {
8587            return false;
8588        }
8589    }
8590
8591    void startLockTaskMode(TaskRecord task) {
8592        final String pkg;
8593        synchronized (this) {
8594            pkg = task.intent.getComponent().getPackageName();
8595        }
8596        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8597        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8598            final TaskRecord taskRecord = task;
8599            mHandler.post(new Runnable() {
8600                @Override
8601                public void run() {
8602                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8603                }
8604            });
8605            return;
8606        }
8607        long ident = Binder.clearCallingIdentity();
8608        try {
8609            synchronized (this) {
8610                // Since we lost lock on task, make sure it is still there.
8611                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8612                if (task != null) {
8613                    if (!isSystemInitiated
8614                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8615                        throw new IllegalArgumentException("Invalid task, not in foreground");
8616                    }
8617                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8618                }
8619            }
8620        } finally {
8621            Binder.restoreCallingIdentity(ident);
8622        }
8623    }
8624
8625    @Override
8626    public void startLockTaskMode(int taskId) {
8627        final TaskRecord task;
8628        long ident = Binder.clearCallingIdentity();
8629        try {
8630            synchronized (this) {
8631                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8632            }
8633        } finally {
8634            Binder.restoreCallingIdentity(ident);
8635        }
8636        if (task != null) {
8637            startLockTaskMode(task);
8638        }
8639    }
8640
8641    @Override
8642    public void startLockTaskMode(IBinder token) {
8643        final TaskRecord task;
8644        long ident = Binder.clearCallingIdentity();
8645        try {
8646            synchronized (this) {
8647                final ActivityRecord r = ActivityRecord.forToken(token);
8648                if (r == null) {
8649                    return;
8650                }
8651                task = r.task;
8652            }
8653        } finally {
8654            Binder.restoreCallingIdentity(ident);
8655        }
8656        if (task != null) {
8657            startLockTaskMode(task);
8658        }
8659    }
8660
8661    @Override
8662    public void startLockTaskModeOnCurrent() throws RemoteException {
8663        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8664        ActivityRecord r = null;
8665        synchronized (this) {
8666            r = mStackSupervisor.topRunningActivityLocked();
8667        }
8668        startLockTaskMode(r.task);
8669    }
8670
8671    @Override
8672    public void stopLockTaskMode() {
8673        // Verify that the user matches the package of the intent for the TaskRecord
8674        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8675        // and stopLockTaskMode.
8676        final int callingUid = Binder.getCallingUid();
8677        if (callingUid != Process.SYSTEM_UID) {
8678            try {
8679                String pkg =
8680                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8681                int uid = mContext.getPackageManager().getPackageUid(pkg,
8682                        Binder.getCallingUserHandle().getIdentifier());
8683                if (uid != callingUid) {
8684                    throw new SecurityException("Invalid uid, expected " + uid);
8685                }
8686            } catch (NameNotFoundException e) {
8687                Log.d(TAG, "stopLockTaskMode " + e);
8688                return;
8689            }
8690        }
8691        long ident = Binder.clearCallingIdentity();
8692        try {
8693            Log.d(TAG, "stopLockTaskMode");
8694            // Stop lock task
8695            synchronized (this) {
8696                mStackSupervisor.setLockTaskModeLocked(null, false);
8697            }
8698        } finally {
8699            Binder.restoreCallingIdentity(ident);
8700        }
8701    }
8702
8703    @Override
8704    public void stopLockTaskModeOnCurrent() throws RemoteException {
8705        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8706        long ident = Binder.clearCallingIdentity();
8707        try {
8708            stopLockTaskMode();
8709        } finally {
8710            Binder.restoreCallingIdentity(ident);
8711        }
8712    }
8713
8714    @Override
8715    public boolean isInLockTaskMode() {
8716        synchronized (this) {
8717            return mStackSupervisor.isInLockTaskMode();
8718        }
8719    }
8720
8721    // =========================================================
8722    // CONTENT PROVIDERS
8723    // =========================================================
8724
8725    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8726        List<ProviderInfo> providers = null;
8727        try {
8728            providers = AppGlobals.getPackageManager().
8729                queryContentProviders(app.processName, app.uid,
8730                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8731        } catch (RemoteException ex) {
8732        }
8733        if (DEBUG_MU)
8734            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8735        int userId = app.userId;
8736        if (providers != null) {
8737            int N = providers.size();
8738            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8739            for (int i=0; i<N; i++) {
8740                ProviderInfo cpi =
8741                    (ProviderInfo)providers.get(i);
8742                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8743                        cpi.name, cpi.flags);
8744                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8745                    // This is a singleton provider, but a user besides the
8746                    // default user is asking to initialize a process it runs
8747                    // in...  well, no, it doesn't actually run in this process,
8748                    // it runs in the process of the default user.  Get rid of it.
8749                    providers.remove(i);
8750                    N--;
8751                    i--;
8752                    continue;
8753                }
8754
8755                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8756                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8757                if (cpr == null) {
8758                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8759                    mProviderMap.putProviderByClass(comp, cpr);
8760                }
8761                if (DEBUG_MU)
8762                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8763                app.pubProviders.put(cpi.name, cpr);
8764                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8765                    // Don't add this if it is a platform component that is marked
8766                    // to run in multiple processes, because this is actually
8767                    // part of the framework so doesn't make sense to track as a
8768                    // separate apk in the process.
8769                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8770                            mProcessStats);
8771                }
8772                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8773            }
8774        }
8775        return providers;
8776    }
8777
8778    /**
8779     * Check if {@link ProcessRecord} has a possible chance at accessing the
8780     * given {@link ProviderInfo}. Final permission checking is always done
8781     * in {@link ContentProvider}.
8782     */
8783    private final String checkContentProviderPermissionLocked(
8784            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8785        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8786        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8787        boolean checkedGrants = false;
8788        if (checkUser) {
8789            // Looking for cross-user grants before enforcing the typical cross-users permissions
8790            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8791            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8792                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8793                    return null;
8794                }
8795                checkedGrants = true;
8796            }
8797            userId = handleIncomingUser(callingPid, callingUid, userId,
8798                    false, ALLOW_NON_FULL,
8799                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8800            if (userId != tmpTargetUserId) {
8801                // When we actually went to determine the final targer user ID, this ended
8802                // up different than our initial check for the authority.  This is because
8803                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8804                // SELF.  So we need to re-check the grants again.
8805                checkedGrants = false;
8806            }
8807        }
8808        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8809                cpi.applicationInfo.uid, cpi.exported)
8810                == PackageManager.PERMISSION_GRANTED) {
8811            return null;
8812        }
8813        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8814                cpi.applicationInfo.uid, cpi.exported)
8815                == PackageManager.PERMISSION_GRANTED) {
8816            return null;
8817        }
8818
8819        PathPermission[] pps = cpi.pathPermissions;
8820        if (pps != null) {
8821            int i = pps.length;
8822            while (i > 0) {
8823                i--;
8824                PathPermission pp = pps[i];
8825                String pprperm = pp.getReadPermission();
8826                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8827                        cpi.applicationInfo.uid, cpi.exported)
8828                        == PackageManager.PERMISSION_GRANTED) {
8829                    return null;
8830                }
8831                String ppwperm = pp.getWritePermission();
8832                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8833                        cpi.applicationInfo.uid, cpi.exported)
8834                        == PackageManager.PERMISSION_GRANTED) {
8835                    return null;
8836                }
8837            }
8838        }
8839        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8840            return null;
8841        }
8842
8843        String msg;
8844        if (!cpi.exported) {
8845            msg = "Permission Denial: opening provider " + cpi.name
8846                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8847                    + ", uid=" + callingUid + ") that is not exported from uid "
8848                    + cpi.applicationInfo.uid;
8849        } else {
8850            msg = "Permission Denial: opening provider " + cpi.name
8851                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8852                    + ", uid=" + callingUid + ") requires "
8853                    + cpi.readPermission + " or " + cpi.writePermission;
8854        }
8855        Slog.w(TAG, msg);
8856        return msg;
8857    }
8858
8859    /**
8860     * Returns if the ContentProvider has granted a uri to callingUid
8861     */
8862    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8863        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8864        if (perms != null) {
8865            for (int i=perms.size()-1; i>=0; i--) {
8866                GrantUri grantUri = perms.keyAt(i);
8867                if (grantUri.sourceUserId == userId || !checkUser) {
8868                    if (matchesProvider(grantUri.uri, cpi)) {
8869                        return true;
8870                    }
8871                }
8872            }
8873        }
8874        return false;
8875    }
8876
8877    /**
8878     * Returns true if the uri authority is one of the authorities specified in the provider.
8879     */
8880    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8881        String uriAuth = uri.getAuthority();
8882        String cpiAuth = cpi.authority;
8883        if (cpiAuth.indexOf(';') == -1) {
8884            return cpiAuth.equals(uriAuth);
8885        }
8886        String[] cpiAuths = cpiAuth.split(";");
8887        int length = cpiAuths.length;
8888        for (int i = 0; i < length; i++) {
8889            if (cpiAuths[i].equals(uriAuth)) return true;
8890        }
8891        return false;
8892    }
8893
8894    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8895            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8896        if (r != null) {
8897            for (int i=0; i<r.conProviders.size(); i++) {
8898                ContentProviderConnection conn = r.conProviders.get(i);
8899                if (conn.provider == cpr) {
8900                    if (DEBUG_PROVIDER) Slog.v(TAG,
8901                            "Adding provider requested by "
8902                            + r.processName + " from process "
8903                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8904                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8905                    if (stable) {
8906                        conn.stableCount++;
8907                        conn.numStableIncs++;
8908                    } else {
8909                        conn.unstableCount++;
8910                        conn.numUnstableIncs++;
8911                    }
8912                    return conn;
8913                }
8914            }
8915            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8916            if (stable) {
8917                conn.stableCount = 1;
8918                conn.numStableIncs = 1;
8919            } else {
8920                conn.unstableCount = 1;
8921                conn.numUnstableIncs = 1;
8922            }
8923            cpr.connections.add(conn);
8924            r.conProviders.add(conn);
8925            return conn;
8926        }
8927        cpr.addExternalProcessHandleLocked(externalProcessToken);
8928        return null;
8929    }
8930
8931    boolean decProviderCountLocked(ContentProviderConnection conn,
8932            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8933        if (conn != null) {
8934            cpr = conn.provider;
8935            if (DEBUG_PROVIDER) Slog.v(TAG,
8936                    "Removing provider requested by "
8937                    + conn.client.processName + " from process "
8938                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8939                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8940            if (stable) {
8941                conn.stableCount--;
8942            } else {
8943                conn.unstableCount--;
8944            }
8945            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8946                cpr.connections.remove(conn);
8947                conn.client.conProviders.remove(conn);
8948                return true;
8949            }
8950            return false;
8951        }
8952        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8953        return false;
8954    }
8955
8956    private void checkTime(long startTime, String where) {
8957        long now = SystemClock.elapsedRealtime();
8958        if ((now-startTime) > 1000) {
8959            // If we are taking more than a second, log about it.
8960            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8961        }
8962    }
8963
8964    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8965            String name, IBinder token, boolean stable, int userId) {
8966        ContentProviderRecord cpr;
8967        ContentProviderConnection conn = null;
8968        ProviderInfo cpi = null;
8969
8970        synchronized(this) {
8971            long startTime = SystemClock.elapsedRealtime();
8972
8973            ProcessRecord r = null;
8974            if (caller != null) {
8975                r = getRecordForAppLocked(caller);
8976                if (r == null) {
8977                    throw new SecurityException(
8978                            "Unable to find app for caller " + caller
8979                          + " (pid=" + Binder.getCallingPid()
8980                          + ") when getting content provider " + name);
8981                }
8982            }
8983
8984            boolean checkCrossUser = true;
8985
8986            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8987
8988            // First check if this content provider has been published...
8989            cpr = mProviderMap.getProviderByName(name, userId);
8990            // If that didn't work, check if it exists for user 0 and then
8991            // verify that it's a singleton provider before using it.
8992            if (cpr == null && userId != UserHandle.USER_OWNER) {
8993                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8994                if (cpr != null) {
8995                    cpi = cpr.info;
8996                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8997                            cpi.name, cpi.flags)
8998                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8999                        userId = UserHandle.USER_OWNER;
9000                        checkCrossUser = false;
9001                    } else {
9002                        cpr = null;
9003                        cpi = null;
9004                    }
9005                }
9006            }
9007
9008            boolean providerRunning = cpr != null;
9009            if (providerRunning) {
9010                cpi = cpr.info;
9011                String msg;
9012                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9013                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9014                        != null) {
9015                    throw new SecurityException(msg);
9016                }
9017                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9018
9019                if (r != null && cpr.canRunHere(r)) {
9020                    // This provider has been published or is in the process
9021                    // of being published...  but it is also allowed to run
9022                    // in the caller's process, so don't make a connection
9023                    // and just let the caller instantiate its own instance.
9024                    ContentProviderHolder holder = cpr.newHolder(null);
9025                    // don't give caller the provider object, it needs
9026                    // to make its own.
9027                    holder.provider = null;
9028                    return holder;
9029                }
9030
9031                final long origId = Binder.clearCallingIdentity();
9032
9033                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9034
9035                // In this case the provider instance already exists, so we can
9036                // return it right away.
9037                conn = incProviderCountLocked(r, cpr, token, stable);
9038                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9039                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9040                        // If this is a perceptible app accessing the provider,
9041                        // make sure to count it as being accessed and thus
9042                        // back up on the LRU list.  This is good because
9043                        // content providers are often expensive to start.
9044                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9045                        updateLruProcessLocked(cpr.proc, false, null);
9046                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9047                    }
9048                }
9049
9050                if (cpr.proc != null) {
9051                    if (false) {
9052                        if (cpr.name.flattenToShortString().equals(
9053                                "com.android.providers.calendar/.CalendarProvider2")) {
9054                            Slog.v(TAG, "****************** KILLING "
9055                                + cpr.name.flattenToShortString());
9056                            Process.killProcess(cpr.proc.pid);
9057                        }
9058                    }
9059                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9060                    boolean success = updateOomAdjLocked(cpr.proc);
9061                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9062                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9063                    // NOTE: there is still a race here where a signal could be
9064                    // pending on the process even though we managed to update its
9065                    // adj level.  Not sure what to do about this, but at least
9066                    // the race is now smaller.
9067                    if (!success) {
9068                        // Uh oh...  it looks like the provider's process
9069                        // has been killed on us.  We need to wait for a new
9070                        // process to be started, and make sure its death
9071                        // doesn't kill our process.
9072                        Slog.i(TAG,
9073                                "Existing provider " + cpr.name.flattenToShortString()
9074                                + " is crashing; detaching " + r);
9075                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9076                        checkTime(startTime, "getContentProviderImpl: before appDied");
9077                        appDiedLocked(cpr.proc);
9078                        checkTime(startTime, "getContentProviderImpl: after appDied");
9079                        if (!lastRef) {
9080                            // This wasn't the last ref our process had on
9081                            // the provider...  we have now been killed, bail.
9082                            return null;
9083                        }
9084                        providerRunning = false;
9085                        conn = null;
9086                    }
9087                }
9088
9089                Binder.restoreCallingIdentity(origId);
9090            }
9091
9092            boolean singleton;
9093            if (!providerRunning) {
9094                try {
9095                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9096                    cpi = AppGlobals.getPackageManager().
9097                        resolveContentProvider(name,
9098                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9099                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9100                } catch (RemoteException ex) {
9101                }
9102                if (cpi == null) {
9103                    return null;
9104                }
9105                // If the provider is a singleton AND
9106                // (it's a call within the same user || the provider is a
9107                // privileged app)
9108                // Then allow connecting to the singleton provider
9109                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9110                        cpi.name, cpi.flags)
9111                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9112                if (singleton) {
9113                    userId = UserHandle.USER_OWNER;
9114                }
9115                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9116                checkTime(startTime, "getContentProviderImpl: got app info for user");
9117
9118                String msg;
9119                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9120                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9121                        != null) {
9122                    throw new SecurityException(msg);
9123                }
9124                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9125
9126                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9127                        && !cpi.processName.equals("system")) {
9128                    // If this content provider does not run in the system
9129                    // process, and the system is not yet ready to run other
9130                    // processes, then fail fast instead of hanging.
9131                    throw new IllegalArgumentException(
9132                            "Attempt to launch content provider before system ready");
9133                }
9134
9135                // Make sure that the user who owns this provider is started.  If not,
9136                // we don't want to allow it to run.
9137                if (mStartedUsers.get(userId) == null) {
9138                    Slog.w(TAG, "Unable to launch app "
9139                            + cpi.applicationInfo.packageName + "/"
9140                            + cpi.applicationInfo.uid + " for provider "
9141                            + name + ": user " + userId + " is stopped");
9142                    return null;
9143                }
9144
9145                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9146                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9147                cpr = mProviderMap.getProviderByClass(comp, userId);
9148                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9149                final boolean firstClass = cpr == null;
9150                if (firstClass) {
9151                    try {
9152                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9153                        ApplicationInfo ai =
9154                            AppGlobals.getPackageManager().
9155                                getApplicationInfo(
9156                                        cpi.applicationInfo.packageName,
9157                                        STOCK_PM_FLAGS, userId);
9158                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9159                        if (ai == null) {
9160                            Slog.w(TAG, "No package info for content provider "
9161                                    + cpi.name);
9162                            return null;
9163                        }
9164                        ai = getAppInfoForUser(ai, userId);
9165                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9166                    } catch (RemoteException ex) {
9167                        // pm is in same process, this will never happen.
9168                    }
9169                }
9170
9171                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9172
9173                if (r != null && cpr.canRunHere(r)) {
9174                    // If this is a multiprocess provider, then just return its
9175                    // info and allow the caller to instantiate it.  Only do
9176                    // this if the provider is the same user as the caller's
9177                    // process, or can run as root (so can be in any process).
9178                    return cpr.newHolder(null);
9179                }
9180
9181                if (DEBUG_PROVIDER) {
9182                    RuntimeException e = new RuntimeException("here");
9183                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9184                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9185                }
9186
9187                // This is single process, and our app is now connecting to it.
9188                // See if we are already in the process of launching this
9189                // provider.
9190                final int N = mLaunchingProviders.size();
9191                int i;
9192                for (i=0; i<N; i++) {
9193                    if (mLaunchingProviders.get(i) == cpr) {
9194                        break;
9195                    }
9196                }
9197
9198                // If the provider is not already being launched, then get it
9199                // started.
9200                if (i >= N) {
9201                    final long origId = Binder.clearCallingIdentity();
9202
9203                    try {
9204                        // Content provider is now in use, its package can't be stopped.
9205                        try {
9206                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9207                            AppGlobals.getPackageManager().setPackageStoppedState(
9208                                    cpr.appInfo.packageName, false, userId);
9209                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9210                        } catch (RemoteException e) {
9211                        } catch (IllegalArgumentException e) {
9212                            Slog.w(TAG, "Failed trying to unstop package "
9213                                    + cpr.appInfo.packageName + ": " + e);
9214                        }
9215
9216                        // Use existing process if already started
9217                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9218                        ProcessRecord proc = getProcessRecordLocked(
9219                                cpi.processName, cpr.appInfo.uid, false);
9220                        if (proc != null && proc.thread != null) {
9221                            if (DEBUG_PROVIDER) {
9222                                Slog.d(TAG, "Installing in existing process " + proc);
9223                            }
9224                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9225                            proc.pubProviders.put(cpi.name, cpr);
9226                            try {
9227                                proc.thread.scheduleInstallProvider(cpi);
9228                            } catch (RemoteException e) {
9229                            }
9230                        } else {
9231                            checkTime(startTime, "getContentProviderImpl: before start process");
9232                            proc = startProcessLocked(cpi.processName,
9233                                    cpr.appInfo, false, 0, "content provider",
9234                                    new ComponentName(cpi.applicationInfo.packageName,
9235                                            cpi.name), false, false, false);
9236                            checkTime(startTime, "getContentProviderImpl: after start process");
9237                            if (proc == null) {
9238                                Slog.w(TAG, "Unable to launch app "
9239                                        + cpi.applicationInfo.packageName + "/"
9240                                        + cpi.applicationInfo.uid + " for provider "
9241                                        + name + ": process is bad");
9242                                return null;
9243                            }
9244                        }
9245                        cpr.launchingApp = proc;
9246                        mLaunchingProviders.add(cpr);
9247                    } finally {
9248                        Binder.restoreCallingIdentity(origId);
9249                    }
9250                }
9251
9252                checkTime(startTime, "getContentProviderImpl: updating data structures");
9253
9254                // Make sure the provider is published (the same provider class
9255                // may be published under multiple names).
9256                if (firstClass) {
9257                    mProviderMap.putProviderByClass(comp, cpr);
9258                }
9259
9260                mProviderMap.putProviderByName(name, cpr);
9261                conn = incProviderCountLocked(r, cpr, token, stable);
9262                if (conn != null) {
9263                    conn.waiting = true;
9264                }
9265            }
9266            checkTime(startTime, "getContentProviderImpl: done!");
9267        }
9268
9269        // Wait for the provider to be published...
9270        synchronized (cpr) {
9271            while (cpr.provider == null) {
9272                if (cpr.launchingApp == null) {
9273                    Slog.w(TAG, "Unable to launch app "
9274                            + cpi.applicationInfo.packageName + "/"
9275                            + cpi.applicationInfo.uid + " for provider "
9276                            + name + ": launching app became null");
9277                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9278                            UserHandle.getUserId(cpi.applicationInfo.uid),
9279                            cpi.applicationInfo.packageName,
9280                            cpi.applicationInfo.uid, name);
9281                    return null;
9282                }
9283                try {
9284                    if (DEBUG_MU) {
9285                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9286                                + cpr.launchingApp);
9287                    }
9288                    if (conn != null) {
9289                        conn.waiting = true;
9290                    }
9291                    cpr.wait();
9292                } catch (InterruptedException ex) {
9293                } finally {
9294                    if (conn != null) {
9295                        conn.waiting = false;
9296                    }
9297                }
9298            }
9299        }
9300        return cpr != null ? cpr.newHolder(conn) : null;
9301    }
9302
9303    @Override
9304    public final ContentProviderHolder getContentProvider(
9305            IApplicationThread caller, String name, int userId, boolean stable) {
9306        enforceNotIsolatedCaller("getContentProvider");
9307        if (caller == null) {
9308            String msg = "null IApplicationThread when getting content provider "
9309                    + name;
9310            Slog.w(TAG, msg);
9311            throw new SecurityException(msg);
9312        }
9313        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9314        // with cross-user grant.
9315        return getContentProviderImpl(caller, name, null, stable, userId);
9316    }
9317
9318    public ContentProviderHolder getContentProviderExternal(
9319            String name, int userId, IBinder token) {
9320        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9321            "Do not have permission in call getContentProviderExternal()");
9322        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9323                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9324        return getContentProviderExternalUnchecked(name, token, userId);
9325    }
9326
9327    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9328            IBinder token, int userId) {
9329        return getContentProviderImpl(null, name, token, true, userId);
9330    }
9331
9332    /**
9333     * Drop a content provider from a ProcessRecord's bookkeeping
9334     */
9335    public void removeContentProvider(IBinder connection, boolean stable) {
9336        enforceNotIsolatedCaller("removeContentProvider");
9337        long ident = Binder.clearCallingIdentity();
9338        try {
9339            synchronized (this) {
9340                ContentProviderConnection conn;
9341                try {
9342                    conn = (ContentProviderConnection)connection;
9343                } catch (ClassCastException e) {
9344                    String msg ="removeContentProvider: " + connection
9345                            + " not a ContentProviderConnection";
9346                    Slog.w(TAG, msg);
9347                    throw new IllegalArgumentException(msg);
9348                }
9349                if (conn == null) {
9350                    throw new NullPointerException("connection is null");
9351                }
9352                if (decProviderCountLocked(conn, null, null, stable)) {
9353                    updateOomAdjLocked();
9354                }
9355            }
9356        } finally {
9357            Binder.restoreCallingIdentity(ident);
9358        }
9359    }
9360
9361    public void removeContentProviderExternal(String name, IBinder token) {
9362        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9363            "Do not have permission in call removeContentProviderExternal()");
9364        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9365    }
9366
9367    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9368        synchronized (this) {
9369            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9370            if(cpr == null) {
9371                //remove from mProvidersByClass
9372                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9373                return;
9374            }
9375
9376            //update content provider record entry info
9377            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9378            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9379            if (localCpr.hasExternalProcessHandles()) {
9380                if (localCpr.removeExternalProcessHandleLocked(token)) {
9381                    updateOomAdjLocked();
9382                } else {
9383                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9384                            + " with no external reference for token: "
9385                            + token + ".");
9386                }
9387            } else {
9388                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9389                        + " with no external references.");
9390            }
9391        }
9392    }
9393
9394    public final void publishContentProviders(IApplicationThread caller,
9395            List<ContentProviderHolder> providers) {
9396        if (providers == null) {
9397            return;
9398        }
9399
9400        enforceNotIsolatedCaller("publishContentProviders");
9401        synchronized (this) {
9402            final ProcessRecord r = getRecordForAppLocked(caller);
9403            if (DEBUG_MU)
9404                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9405            if (r == null) {
9406                throw new SecurityException(
9407                        "Unable to find app for caller " + caller
9408                      + " (pid=" + Binder.getCallingPid()
9409                      + ") when publishing content providers");
9410            }
9411
9412            final long origId = Binder.clearCallingIdentity();
9413
9414            final int N = providers.size();
9415            for (int i=0; i<N; i++) {
9416                ContentProviderHolder src = providers.get(i);
9417                if (src == null || src.info == null || src.provider == null) {
9418                    continue;
9419                }
9420                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9421                if (DEBUG_MU)
9422                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9423                if (dst != null) {
9424                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9425                    mProviderMap.putProviderByClass(comp, dst);
9426                    String names[] = dst.info.authority.split(";");
9427                    for (int j = 0; j < names.length; j++) {
9428                        mProviderMap.putProviderByName(names[j], dst);
9429                    }
9430
9431                    int NL = mLaunchingProviders.size();
9432                    int j;
9433                    for (j=0; j<NL; j++) {
9434                        if (mLaunchingProviders.get(j) == dst) {
9435                            mLaunchingProviders.remove(j);
9436                            j--;
9437                            NL--;
9438                        }
9439                    }
9440                    synchronized (dst) {
9441                        dst.provider = src.provider;
9442                        dst.proc = r;
9443                        dst.notifyAll();
9444                    }
9445                    updateOomAdjLocked(r);
9446                }
9447            }
9448
9449            Binder.restoreCallingIdentity(origId);
9450        }
9451    }
9452
9453    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9454        ContentProviderConnection conn;
9455        try {
9456            conn = (ContentProviderConnection)connection;
9457        } catch (ClassCastException e) {
9458            String msg ="refContentProvider: " + connection
9459                    + " not a ContentProviderConnection";
9460            Slog.w(TAG, msg);
9461            throw new IllegalArgumentException(msg);
9462        }
9463        if (conn == null) {
9464            throw new NullPointerException("connection is null");
9465        }
9466
9467        synchronized (this) {
9468            if (stable > 0) {
9469                conn.numStableIncs += stable;
9470            }
9471            stable = conn.stableCount + stable;
9472            if (stable < 0) {
9473                throw new IllegalStateException("stableCount < 0: " + stable);
9474            }
9475
9476            if (unstable > 0) {
9477                conn.numUnstableIncs += unstable;
9478            }
9479            unstable = conn.unstableCount + unstable;
9480            if (unstable < 0) {
9481                throw new IllegalStateException("unstableCount < 0: " + unstable);
9482            }
9483
9484            if ((stable+unstable) <= 0) {
9485                throw new IllegalStateException("ref counts can't go to zero here: stable="
9486                        + stable + " unstable=" + unstable);
9487            }
9488            conn.stableCount = stable;
9489            conn.unstableCount = unstable;
9490            return !conn.dead;
9491        }
9492    }
9493
9494    public void unstableProviderDied(IBinder connection) {
9495        ContentProviderConnection conn;
9496        try {
9497            conn = (ContentProviderConnection)connection;
9498        } catch (ClassCastException e) {
9499            String msg ="refContentProvider: " + connection
9500                    + " not a ContentProviderConnection";
9501            Slog.w(TAG, msg);
9502            throw new IllegalArgumentException(msg);
9503        }
9504        if (conn == null) {
9505            throw new NullPointerException("connection is null");
9506        }
9507
9508        // Safely retrieve the content provider associated with the connection.
9509        IContentProvider provider;
9510        synchronized (this) {
9511            provider = conn.provider.provider;
9512        }
9513
9514        if (provider == null) {
9515            // Um, yeah, we're way ahead of you.
9516            return;
9517        }
9518
9519        // Make sure the caller is being honest with us.
9520        if (provider.asBinder().pingBinder()) {
9521            // Er, no, still looks good to us.
9522            synchronized (this) {
9523                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9524                        + " says " + conn + " died, but we don't agree");
9525                return;
9526            }
9527        }
9528
9529        // Well look at that!  It's dead!
9530        synchronized (this) {
9531            if (conn.provider.provider != provider) {
9532                // But something changed...  good enough.
9533                return;
9534            }
9535
9536            ProcessRecord proc = conn.provider.proc;
9537            if (proc == null || proc.thread == null) {
9538                // Seems like the process is already cleaned up.
9539                return;
9540            }
9541
9542            // As far as we're concerned, this is just like receiving a
9543            // death notification...  just a bit prematurely.
9544            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9545                    + ") early provider death");
9546            final long ident = Binder.clearCallingIdentity();
9547            try {
9548                appDiedLocked(proc);
9549            } finally {
9550                Binder.restoreCallingIdentity(ident);
9551            }
9552        }
9553    }
9554
9555    @Override
9556    public void appNotRespondingViaProvider(IBinder connection) {
9557        enforceCallingPermission(
9558                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9559
9560        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9561        if (conn == null) {
9562            Slog.w(TAG, "ContentProviderConnection is null");
9563            return;
9564        }
9565
9566        final ProcessRecord host = conn.provider.proc;
9567        if (host == null) {
9568            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9569            return;
9570        }
9571
9572        final long token = Binder.clearCallingIdentity();
9573        try {
9574            appNotResponding(host, null, null, false, "ContentProvider not responding");
9575        } finally {
9576            Binder.restoreCallingIdentity(token);
9577        }
9578    }
9579
9580    public final void installSystemProviders() {
9581        List<ProviderInfo> providers;
9582        synchronized (this) {
9583            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9584            providers = generateApplicationProvidersLocked(app);
9585            if (providers != null) {
9586                for (int i=providers.size()-1; i>=0; i--) {
9587                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9588                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9589                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9590                                + ": not system .apk");
9591                        providers.remove(i);
9592                    }
9593                }
9594            }
9595        }
9596        if (providers != null) {
9597            mSystemThread.installSystemProviders(providers);
9598        }
9599
9600        mCoreSettingsObserver = new CoreSettingsObserver(this);
9601
9602        //mUsageStatsService.monitorPackages();
9603    }
9604
9605    /**
9606     * Allows apps to retrieve the MIME type of a URI.
9607     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9608     * users, then it does not need permission to access the ContentProvider.
9609     * Either, it needs cross-user uri grants.
9610     *
9611     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9612     *
9613     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9614     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9615     */
9616    public String getProviderMimeType(Uri uri, int userId) {
9617        enforceNotIsolatedCaller("getProviderMimeType");
9618        final String name = uri.getAuthority();
9619        int callingUid = Binder.getCallingUid();
9620        int callingPid = Binder.getCallingPid();
9621        long ident = 0;
9622        boolean clearedIdentity = false;
9623        userId = unsafeConvertIncomingUser(userId);
9624        if (UserHandle.getUserId(callingUid) != userId) {
9625            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9626                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9627                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9628                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9629                clearedIdentity = true;
9630                ident = Binder.clearCallingIdentity();
9631            }
9632        }
9633        ContentProviderHolder holder = null;
9634        try {
9635            holder = getContentProviderExternalUnchecked(name, null, userId);
9636            if (holder != null) {
9637                return holder.provider.getType(uri);
9638            }
9639        } catch (RemoteException e) {
9640            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9641            return null;
9642        } finally {
9643            // We need to clear the identity to call removeContentProviderExternalUnchecked
9644            if (!clearedIdentity) {
9645                ident = Binder.clearCallingIdentity();
9646            }
9647            try {
9648                if (holder != null) {
9649                    removeContentProviderExternalUnchecked(name, null, userId);
9650                }
9651            } finally {
9652                Binder.restoreCallingIdentity(ident);
9653            }
9654        }
9655
9656        return null;
9657    }
9658
9659    // =========================================================
9660    // GLOBAL MANAGEMENT
9661    // =========================================================
9662
9663    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9664            boolean isolated, int isolatedUid) {
9665        String proc = customProcess != null ? customProcess : info.processName;
9666        BatteryStatsImpl.Uid.Proc ps = null;
9667        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9668        int uid = info.uid;
9669        if (isolated) {
9670            if (isolatedUid == 0) {
9671                int userId = UserHandle.getUserId(uid);
9672                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9673                while (true) {
9674                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9675                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9676                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9677                    }
9678                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9679                    mNextIsolatedProcessUid++;
9680                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9681                        // No process for this uid, use it.
9682                        break;
9683                    }
9684                    stepsLeft--;
9685                    if (stepsLeft <= 0) {
9686                        return null;
9687                    }
9688                }
9689            } else {
9690                // Special case for startIsolatedProcess (internal only), where
9691                // the uid of the isolated process is specified by the caller.
9692                uid = isolatedUid;
9693            }
9694        }
9695        return new ProcessRecord(stats, info, proc, uid);
9696    }
9697
9698    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9699            String abiOverride) {
9700        ProcessRecord app;
9701        if (!isolated) {
9702            app = getProcessRecordLocked(info.processName, info.uid, true);
9703        } else {
9704            app = null;
9705        }
9706
9707        if (app == null) {
9708            app = newProcessRecordLocked(info, null, isolated, 0);
9709            mProcessNames.put(info.processName, app.uid, app);
9710            if (isolated) {
9711                mIsolatedProcesses.put(app.uid, app);
9712            }
9713            updateLruProcessLocked(app, false, null);
9714            updateOomAdjLocked();
9715        }
9716
9717        // This package really, really can not be stopped.
9718        try {
9719            AppGlobals.getPackageManager().setPackageStoppedState(
9720                    info.packageName, false, UserHandle.getUserId(app.uid));
9721        } catch (RemoteException e) {
9722        } catch (IllegalArgumentException e) {
9723            Slog.w(TAG, "Failed trying to unstop package "
9724                    + info.packageName + ": " + e);
9725        }
9726
9727        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9728                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9729            app.persistent = true;
9730            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9731        }
9732        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9733            mPersistentStartingProcesses.add(app);
9734            startProcessLocked(app, "added application", app.processName, abiOverride,
9735                    null /* entryPoint */, null /* entryPointArgs */);
9736        }
9737
9738        return app;
9739    }
9740
9741    public void unhandledBack() {
9742        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9743                "unhandledBack()");
9744
9745        synchronized(this) {
9746            final long origId = Binder.clearCallingIdentity();
9747            try {
9748                getFocusedStack().unhandledBackLocked();
9749            } finally {
9750                Binder.restoreCallingIdentity(origId);
9751            }
9752        }
9753    }
9754
9755    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9756        enforceNotIsolatedCaller("openContentUri");
9757        final int userId = UserHandle.getCallingUserId();
9758        String name = uri.getAuthority();
9759        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9760        ParcelFileDescriptor pfd = null;
9761        if (cph != null) {
9762            // We record the binder invoker's uid in thread-local storage before
9763            // going to the content provider to open the file.  Later, in the code
9764            // that handles all permissions checks, we look for this uid and use
9765            // that rather than the Activity Manager's own uid.  The effect is that
9766            // we do the check against the caller's permissions even though it looks
9767            // to the content provider like the Activity Manager itself is making
9768            // the request.
9769            sCallerIdentity.set(new Identity(
9770                    Binder.getCallingPid(), Binder.getCallingUid()));
9771            try {
9772                pfd = cph.provider.openFile(null, uri, "r", null);
9773            } catch (FileNotFoundException e) {
9774                // do nothing; pfd will be returned null
9775            } finally {
9776                // Ensure that whatever happens, we clean up the identity state
9777                sCallerIdentity.remove();
9778            }
9779
9780            // We've got the fd now, so we're done with the provider.
9781            removeContentProviderExternalUnchecked(name, null, userId);
9782        } else {
9783            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9784        }
9785        return pfd;
9786    }
9787
9788    // Actually is sleeping or shutting down or whatever else in the future
9789    // is an inactive state.
9790    public boolean isSleepingOrShuttingDown() {
9791        return mSleeping || mShuttingDown;
9792    }
9793
9794    public boolean isSleeping() {
9795        return mSleeping;
9796    }
9797
9798    void goingToSleep() {
9799        synchronized(this) {
9800            mWentToSleep = true;
9801            updateEventDispatchingLocked();
9802            goToSleepIfNeededLocked();
9803        }
9804    }
9805
9806    void finishRunningVoiceLocked() {
9807        if (mRunningVoice) {
9808            mRunningVoice = false;
9809            goToSleepIfNeededLocked();
9810        }
9811    }
9812
9813    void goToSleepIfNeededLocked() {
9814        if (mWentToSleep && !mRunningVoice) {
9815            if (!mSleeping) {
9816                mSleeping = true;
9817                mStackSupervisor.goingToSleepLocked();
9818
9819                // Initialize the wake times of all processes.
9820                checkExcessivePowerUsageLocked(false);
9821                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9822                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9823                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9824            }
9825        }
9826    }
9827
9828    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9829        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9830            // Never persist the home stack.
9831            return;
9832        }
9833        mTaskPersister.wakeup(task, flush);
9834    }
9835
9836    @Override
9837    public boolean shutdown(int timeout) {
9838        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9839                != PackageManager.PERMISSION_GRANTED) {
9840            throw new SecurityException("Requires permission "
9841                    + android.Manifest.permission.SHUTDOWN);
9842        }
9843
9844        boolean timedout = false;
9845
9846        synchronized(this) {
9847            mShuttingDown = true;
9848            updateEventDispatchingLocked();
9849            timedout = mStackSupervisor.shutdownLocked(timeout);
9850        }
9851
9852        mAppOpsService.shutdown();
9853        if (mUsageStatsService != null) {
9854            mUsageStatsService.prepareShutdown();
9855        }
9856        mBatteryStatsService.shutdown();
9857        synchronized (this) {
9858            mProcessStats.shutdownLocked();
9859        }
9860        notifyTaskPersisterLocked(null, true);
9861
9862        return timedout;
9863    }
9864
9865    public final void activitySlept(IBinder token) {
9866        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9867
9868        final long origId = Binder.clearCallingIdentity();
9869
9870        synchronized (this) {
9871            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9872            if (r != null) {
9873                mStackSupervisor.activitySleptLocked(r);
9874            }
9875        }
9876
9877        Binder.restoreCallingIdentity(origId);
9878    }
9879
9880    void logLockScreen(String msg) {
9881        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9882                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9883                mWentToSleep + " mSleeping=" + mSleeping);
9884    }
9885
9886    private void comeOutOfSleepIfNeededLocked() {
9887        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9888            if (mSleeping) {
9889                mSleeping = false;
9890                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9891            }
9892        }
9893    }
9894
9895    void wakingUp() {
9896        synchronized(this) {
9897            mWentToSleep = false;
9898            updateEventDispatchingLocked();
9899            comeOutOfSleepIfNeededLocked();
9900        }
9901    }
9902
9903    void startRunningVoiceLocked() {
9904        if (!mRunningVoice) {
9905            mRunningVoice = true;
9906            comeOutOfSleepIfNeededLocked();
9907        }
9908    }
9909
9910    private void updateEventDispatchingLocked() {
9911        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9912    }
9913
9914    public void setLockScreenShown(boolean shown) {
9915        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9916                != PackageManager.PERMISSION_GRANTED) {
9917            throw new SecurityException("Requires permission "
9918                    + android.Manifest.permission.DEVICE_POWER);
9919        }
9920
9921        synchronized(this) {
9922            long ident = Binder.clearCallingIdentity();
9923            try {
9924                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9925                mLockScreenShown = shown;
9926                comeOutOfSleepIfNeededLocked();
9927            } finally {
9928                Binder.restoreCallingIdentity(ident);
9929            }
9930        }
9931    }
9932
9933    @Override
9934    public void stopAppSwitches() {
9935        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9936                != PackageManager.PERMISSION_GRANTED) {
9937            throw new SecurityException("Requires permission "
9938                    + android.Manifest.permission.STOP_APP_SWITCHES);
9939        }
9940
9941        synchronized(this) {
9942            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9943                    + APP_SWITCH_DELAY_TIME;
9944            mDidAppSwitch = false;
9945            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9946            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9947            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9948        }
9949    }
9950
9951    public void resumeAppSwitches() {
9952        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9953                != PackageManager.PERMISSION_GRANTED) {
9954            throw new SecurityException("Requires permission "
9955                    + android.Manifest.permission.STOP_APP_SWITCHES);
9956        }
9957
9958        synchronized(this) {
9959            // Note that we don't execute any pending app switches... we will
9960            // let those wait until either the timeout, or the next start
9961            // activity request.
9962            mAppSwitchesAllowedTime = 0;
9963        }
9964    }
9965
9966    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9967            String name) {
9968        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9969            return true;
9970        }
9971
9972        final int perm = checkComponentPermission(
9973                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9974                callingUid, -1, true);
9975        if (perm == PackageManager.PERMISSION_GRANTED) {
9976            return true;
9977        }
9978
9979        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9980        return false;
9981    }
9982
9983    public void setDebugApp(String packageName, boolean waitForDebugger,
9984            boolean persistent) {
9985        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9986                "setDebugApp()");
9987
9988        long ident = Binder.clearCallingIdentity();
9989        try {
9990            // Note that this is not really thread safe if there are multiple
9991            // callers into it at the same time, but that's not a situation we
9992            // care about.
9993            if (persistent) {
9994                final ContentResolver resolver = mContext.getContentResolver();
9995                Settings.Global.putString(
9996                    resolver, Settings.Global.DEBUG_APP,
9997                    packageName);
9998                Settings.Global.putInt(
9999                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10000                    waitForDebugger ? 1 : 0);
10001            }
10002
10003            synchronized (this) {
10004                if (!persistent) {
10005                    mOrigDebugApp = mDebugApp;
10006                    mOrigWaitForDebugger = mWaitForDebugger;
10007                }
10008                mDebugApp = packageName;
10009                mWaitForDebugger = waitForDebugger;
10010                mDebugTransient = !persistent;
10011                if (packageName != null) {
10012                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10013                            false, UserHandle.USER_ALL, "set debug app");
10014                }
10015            }
10016        } finally {
10017            Binder.restoreCallingIdentity(ident);
10018        }
10019    }
10020
10021    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10022        synchronized (this) {
10023            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10024            if (!isDebuggable) {
10025                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10026                    throw new SecurityException("Process not debuggable: " + app.packageName);
10027                }
10028            }
10029
10030            mOpenGlTraceApp = processName;
10031        }
10032    }
10033
10034    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10035        synchronized (this) {
10036            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10037            if (!isDebuggable) {
10038                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10039                    throw new SecurityException("Process not debuggable: " + app.packageName);
10040                }
10041            }
10042            mProfileApp = processName;
10043            mProfileFile = profilerInfo.profileFile;
10044            if (mProfileFd != null) {
10045                try {
10046                    mProfileFd.close();
10047                } catch (IOException e) {
10048                }
10049                mProfileFd = null;
10050            }
10051            mProfileFd = profilerInfo.profileFd;
10052            mSamplingInterval = profilerInfo.samplingInterval;
10053            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10054            mProfileType = 0;
10055        }
10056    }
10057
10058    @Override
10059    public void setAlwaysFinish(boolean enabled) {
10060        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10061                "setAlwaysFinish()");
10062
10063        Settings.Global.putInt(
10064                mContext.getContentResolver(),
10065                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10066
10067        synchronized (this) {
10068            mAlwaysFinishActivities = enabled;
10069        }
10070    }
10071
10072    @Override
10073    public void setActivityController(IActivityController controller) {
10074        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10075                "setActivityController()");
10076        synchronized (this) {
10077            mController = controller;
10078            Watchdog.getInstance().setActivityController(controller);
10079        }
10080    }
10081
10082    @Override
10083    public void setUserIsMonkey(boolean userIsMonkey) {
10084        synchronized (this) {
10085            synchronized (mPidsSelfLocked) {
10086                final int callingPid = Binder.getCallingPid();
10087                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10088                if (precessRecord == null) {
10089                    throw new SecurityException("Unknown process: " + callingPid);
10090                }
10091                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10092                    throw new SecurityException("Only an instrumentation process "
10093                            + "with a UiAutomation can call setUserIsMonkey");
10094                }
10095            }
10096            mUserIsMonkey = userIsMonkey;
10097        }
10098    }
10099
10100    @Override
10101    public boolean isUserAMonkey() {
10102        synchronized (this) {
10103            // If there is a controller also implies the user is a monkey.
10104            return (mUserIsMonkey || mController != null);
10105        }
10106    }
10107
10108    public void requestBugReport() {
10109        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10110        SystemProperties.set("ctl.start", "bugreport");
10111    }
10112
10113    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10114        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10115    }
10116
10117    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10118        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10119            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10120        }
10121        return KEY_DISPATCHING_TIMEOUT;
10122    }
10123
10124    @Override
10125    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10126        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10127                != PackageManager.PERMISSION_GRANTED) {
10128            throw new SecurityException("Requires permission "
10129                    + android.Manifest.permission.FILTER_EVENTS);
10130        }
10131        ProcessRecord proc;
10132        long timeout;
10133        synchronized (this) {
10134            synchronized (mPidsSelfLocked) {
10135                proc = mPidsSelfLocked.get(pid);
10136            }
10137            timeout = getInputDispatchingTimeoutLocked(proc);
10138        }
10139
10140        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10141            return -1;
10142        }
10143
10144        return timeout;
10145    }
10146
10147    /**
10148     * Handle input dispatching timeouts.
10149     * Returns whether input dispatching should be aborted or not.
10150     */
10151    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10152            final ActivityRecord activity, final ActivityRecord parent,
10153            final boolean aboveSystem, String reason) {
10154        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10155                != PackageManager.PERMISSION_GRANTED) {
10156            throw new SecurityException("Requires permission "
10157                    + android.Manifest.permission.FILTER_EVENTS);
10158        }
10159
10160        final String annotation;
10161        if (reason == null) {
10162            annotation = "Input dispatching timed out";
10163        } else {
10164            annotation = "Input dispatching timed out (" + reason + ")";
10165        }
10166
10167        if (proc != null) {
10168            synchronized (this) {
10169                if (proc.debugging) {
10170                    return false;
10171                }
10172
10173                if (mDidDexOpt) {
10174                    // Give more time since we were dexopting.
10175                    mDidDexOpt = false;
10176                    return false;
10177                }
10178
10179                if (proc.instrumentationClass != null) {
10180                    Bundle info = new Bundle();
10181                    info.putString("shortMsg", "keyDispatchingTimedOut");
10182                    info.putString("longMsg", annotation);
10183                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10184                    return true;
10185                }
10186            }
10187            mHandler.post(new Runnable() {
10188                @Override
10189                public void run() {
10190                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10191                }
10192            });
10193        }
10194
10195        return true;
10196    }
10197
10198    public Bundle getAssistContextExtras(int requestType) {
10199        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10200                "getAssistContextExtras()");
10201        PendingAssistExtras pae;
10202        Bundle extras = new Bundle();
10203        synchronized (this) {
10204            ActivityRecord activity = getFocusedStack().mResumedActivity;
10205            if (activity == null) {
10206                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10207                return null;
10208            }
10209            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10210            if (activity.app == null || activity.app.thread == null) {
10211                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10212                return extras;
10213            }
10214            if (activity.app.pid == Binder.getCallingPid()) {
10215                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10216                return extras;
10217            }
10218            pae = new PendingAssistExtras(activity);
10219            try {
10220                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10221                        requestType);
10222                mPendingAssistExtras.add(pae);
10223                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10224            } catch (RemoteException e) {
10225                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10226                return extras;
10227            }
10228        }
10229        synchronized (pae) {
10230            while (!pae.haveResult) {
10231                try {
10232                    pae.wait();
10233                } catch (InterruptedException e) {
10234                }
10235            }
10236            if (pae.result != null) {
10237                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10238            }
10239        }
10240        synchronized (this) {
10241            mPendingAssistExtras.remove(pae);
10242            mHandler.removeCallbacks(pae);
10243        }
10244        return extras;
10245    }
10246
10247    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10248        PendingAssistExtras pae = (PendingAssistExtras)token;
10249        synchronized (pae) {
10250            pae.result = extras;
10251            pae.haveResult = true;
10252            pae.notifyAll();
10253        }
10254    }
10255
10256    public void registerProcessObserver(IProcessObserver observer) {
10257        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10258                "registerProcessObserver()");
10259        synchronized (this) {
10260            mProcessObservers.register(observer);
10261        }
10262    }
10263
10264    @Override
10265    public void unregisterProcessObserver(IProcessObserver observer) {
10266        synchronized (this) {
10267            mProcessObservers.unregister(observer);
10268        }
10269    }
10270
10271    @Override
10272    public boolean convertFromTranslucent(IBinder token) {
10273        final long origId = Binder.clearCallingIdentity();
10274        try {
10275            synchronized (this) {
10276                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10277                if (r == null) {
10278                    return false;
10279                }
10280                if (r.changeWindowTranslucency(true)) {
10281                    mWindowManager.setAppFullscreen(token, true);
10282                    r.task.stack.releaseBackgroundResources();
10283                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10284                    return true;
10285                }
10286                return false;
10287            }
10288        } finally {
10289            Binder.restoreCallingIdentity(origId);
10290        }
10291    }
10292
10293    @Override
10294    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10295        final long origId = Binder.clearCallingIdentity();
10296        try {
10297            synchronized (this) {
10298                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10299                if (r == null) {
10300                    return false;
10301                }
10302                int index = r.task.mActivities.lastIndexOf(r);
10303                if (index > 0) {
10304                    ActivityRecord under = r.task.mActivities.get(index - 1);
10305                    under.returningOptions = options;
10306                }
10307                if (r.changeWindowTranslucency(false)) {
10308                    r.task.stack.convertToTranslucent(r);
10309                    mWindowManager.setAppFullscreen(token, false);
10310                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10311                    return true;
10312                } else {
10313                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10314                    return false;
10315                }
10316            }
10317        } finally {
10318            Binder.restoreCallingIdentity(origId);
10319        }
10320    }
10321
10322    @Override
10323    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10324        final long origId = Binder.clearCallingIdentity();
10325        try {
10326            synchronized (this) {
10327                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10328                if (r != null) {
10329                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10330                }
10331            }
10332            return false;
10333        } finally {
10334            Binder.restoreCallingIdentity(origId);
10335        }
10336    }
10337
10338    @Override
10339    public boolean isBackgroundVisibleBehind(IBinder token) {
10340        final long origId = Binder.clearCallingIdentity();
10341        try {
10342            synchronized (this) {
10343                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10344                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10345                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10346                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10347                return visible;
10348            }
10349        } finally {
10350            Binder.restoreCallingIdentity(origId);
10351        }
10352    }
10353
10354    @Override
10355    public ActivityOptions getActivityOptions(IBinder token) {
10356        final long origId = Binder.clearCallingIdentity();
10357        try {
10358            synchronized (this) {
10359                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10360                if (r != null) {
10361                    final ActivityOptions activityOptions = r.pendingOptions;
10362                    r.pendingOptions = null;
10363                    return activityOptions;
10364                }
10365                return null;
10366            }
10367        } finally {
10368            Binder.restoreCallingIdentity(origId);
10369        }
10370    }
10371
10372    @Override
10373    public void setImmersive(IBinder token, boolean immersive) {
10374        synchronized(this) {
10375            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10376            if (r == null) {
10377                throw new IllegalArgumentException();
10378            }
10379            r.immersive = immersive;
10380
10381            // update associated state if we're frontmost
10382            if (r == mFocusedActivity) {
10383                if (DEBUG_IMMERSIVE) {
10384                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10385                }
10386                applyUpdateLockStateLocked(r);
10387            }
10388        }
10389    }
10390
10391    @Override
10392    public boolean isImmersive(IBinder token) {
10393        synchronized (this) {
10394            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10395            if (r == null) {
10396                throw new IllegalArgumentException();
10397            }
10398            return r.immersive;
10399        }
10400    }
10401
10402    public boolean isTopActivityImmersive() {
10403        enforceNotIsolatedCaller("startActivity");
10404        synchronized (this) {
10405            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10406            return (r != null) ? r.immersive : false;
10407        }
10408    }
10409
10410    @Override
10411    public boolean isTopOfTask(IBinder token) {
10412        synchronized (this) {
10413            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10414            if (r == null) {
10415                throw new IllegalArgumentException();
10416            }
10417            return r.task.getTopActivity() == r;
10418        }
10419    }
10420
10421    public final void enterSafeMode() {
10422        synchronized(this) {
10423            // It only makes sense to do this before the system is ready
10424            // and started launching other packages.
10425            if (!mSystemReady) {
10426                try {
10427                    AppGlobals.getPackageManager().enterSafeMode();
10428                } catch (RemoteException e) {
10429                }
10430            }
10431
10432            mSafeMode = true;
10433        }
10434    }
10435
10436    public final void showSafeModeOverlay() {
10437        View v = LayoutInflater.from(mContext).inflate(
10438                com.android.internal.R.layout.safe_mode, null);
10439        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10440        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10441        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10442        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10443        lp.gravity = Gravity.BOTTOM | Gravity.START;
10444        lp.format = v.getBackground().getOpacity();
10445        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10446                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10447        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10448        ((WindowManager)mContext.getSystemService(
10449                Context.WINDOW_SERVICE)).addView(v, lp);
10450    }
10451
10452    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10453        if (!(sender instanceof PendingIntentRecord)) {
10454            return;
10455        }
10456        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10457        synchronized (stats) {
10458            if (mBatteryStatsService.isOnBattery()) {
10459                mBatteryStatsService.enforceCallingPermission();
10460                PendingIntentRecord rec = (PendingIntentRecord)sender;
10461                int MY_UID = Binder.getCallingUid();
10462                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10463                BatteryStatsImpl.Uid.Pkg pkg =
10464                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10465                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10466                pkg.incWakeupsLocked();
10467            }
10468        }
10469    }
10470
10471    public boolean killPids(int[] pids, String pReason, boolean secure) {
10472        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10473            throw new SecurityException("killPids only available to the system");
10474        }
10475        String reason = (pReason == null) ? "Unknown" : pReason;
10476        // XXX Note: don't acquire main activity lock here, because the window
10477        // manager calls in with its locks held.
10478
10479        boolean killed = false;
10480        synchronized (mPidsSelfLocked) {
10481            int[] types = new int[pids.length];
10482            int worstType = 0;
10483            for (int i=0; i<pids.length; i++) {
10484                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10485                if (proc != null) {
10486                    int type = proc.setAdj;
10487                    types[i] = type;
10488                    if (type > worstType) {
10489                        worstType = type;
10490                    }
10491                }
10492            }
10493
10494            // If the worst oom_adj is somewhere in the cached proc LRU range,
10495            // then constrain it so we will kill all cached procs.
10496            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10497                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10498                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10499            }
10500
10501            // If this is not a secure call, don't let it kill processes that
10502            // are important.
10503            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10504                worstType = ProcessList.SERVICE_ADJ;
10505            }
10506
10507            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10508            for (int i=0; i<pids.length; i++) {
10509                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10510                if (proc == null) {
10511                    continue;
10512                }
10513                int adj = proc.setAdj;
10514                if (adj >= worstType && !proc.killedByAm) {
10515                    proc.kill(reason, true);
10516                    killed = true;
10517                }
10518            }
10519        }
10520        return killed;
10521    }
10522
10523    @Override
10524    public void killUid(int uid, String reason) {
10525        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10526            throw new SecurityException("killUid only available to the system");
10527        }
10528        synchronized (this) {
10529            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10530                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10531                    reason != null ? reason : "kill uid");
10532        }
10533    }
10534
10535    @Override
10536    public boolean killProcessesBelowForeground(String reason) {
10537        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10538            throw new SecurityException("killProcessesBelowForeground() only available to system");
10539        }
10540
10541        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10542    }
10543
10544    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10545        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10546            throw new SecurityException("killProcessesBelowAdj() only available to system");
10547        }
10548
10549        boolean killed = false;
10550        synchronized (mPidsSelfLocked) {
10551            final int size = mPidsSelfLocked.size();
10552            for (int i = 0; i < size; i++) {
10553                final int pid = mPidsSelfLocked.keyAt(i);
10554                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10555                if (proc == null) continue;
10556
10557                final int adj = proc.setAdj;
10558                if (adj > belowAdj && !proc.killedByAm) {
10559                    proc.kill(reason, true);
10560                    killed = true;
10561                }
10562            }
10563        }
10564        return killed;
10565    }
10566
10567    @Override
10568    public void hang(final IBinder who, boolean allowRestart) {
10569        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10570                != PackageManager.PERMISSION_GRANTED) {
10571            throw new SecurityException("Requires permission "
10572                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10573        }
10574
10575        final IBinder.DeathRecipient death = new DeathRecipient() {
10576            @Override
10577            public void binderDied() {
10578                synchronized (this) {
10579                    notifyAll();
10580                }
10581            }
10582        };
10583
10584        try {
10585            who.linkToDeath(death, 0);
10586        } catch (RemoteException e) {
10587            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10588            return;
10589        }
10590
10591        synchronized (this) {
10592            Watchdog.getInstance().setAllowRestart(allowRestart);
10593            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10594            synchronized (death) {
10595                while (who.isBinderAlive()) {
10596                    try {
10597                        death.wait();
10598                    } catch (InterruptedException e) {
10599                    }
10600                }
10601            }
10602            Watchdog.getInstance().setAllowRestart(true);
10603        }
10604    }
10605
10606    @Override
10607    public void restart() {
10608        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10609                != PackageManager.PERMISSION_GRANTED) {
10610            throw new SecurityException("Requires permission "
10611                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10612        }
10613
10614        Log.i(TAG, "Sending shutdown broadcast...");
10615
10616        BroadcastReceiver br = new BroadcastReceiver() {
10617            @Override public void onReceive(Context context, Intent intent) {
10618                // Now the broadcast is done, finish up the low-level shutdown.
10619                Log.i(TAG, "Shutting down activity manager...");
10620                shutdown(10000);
10621                Log.i(TAG, "Shutdown complete, restarting!");
10622                Process.killProcess(Process.myPid());
10623                System.exit(10);
10624            }
10625        };
10626
10627        // First send the high-level shut down broadcast.
10628        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10629        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10630        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10631        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10632        mContext.sendOrderedBroadcastAsUser(intent,
10633                UserHandle.ALL, null, br, mHandler, 0, null, null);
10634        */
10635        br.onReceive(mContext, intent);
10636    }
10637
10638    private long getLowRamTimeSinceIdle(long now) {
10639        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10640    }
10641
10642    @Override
10643    public void performIdleMaintenance() {
10644        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10645                != PackageManager.PERMISSION_GRANTED) {
10646            throw new SecurityException("Requires permission "
10647                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10648        }
10649
10650        synchronized (this) {
10651            final long now = SystemClock.uptimeMillis();
10652            final long timeSinceLastIdle = now - mLastIdleTime;
10653            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10654            mLastIdleTime = now;
10655            mLowRamTimeSinceLastIdle = 0;
10656            if (mLowRamStartTime != 0) {
10657                mLowRamStartTime = now;
10658            }
10659
10660            StringBuilder sb = new StringBuilder(128);
10661            sb.append("Idle maintenance over ");
10662            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10663            sb.append(" low RAM for ");
10664            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10665            Slog.i(TAG, sb.toString());
10666
10667            // If at least 1/3 of our time since the last idle period has been spent
10668            // with RAM low, then we want to kill processes.
10669            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10670
10671            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10672                ProcessRecord proc = mLruProcesses.get(i);
10673                if (proc.notCachedSinceIdle) {
10674                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10675                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10676                        if (doKilling && proc.initialIdlePss != 0
10677                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10678                            proc.kill("idle maint (pss " + proc.lastPss
10679                                    + " from " + proc.initialIdlePss + ")", true);
10680                        }
10681                    }
10682                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10683                    proc.notCachedSinceIdle = true;
10684                    proc.initialIdlePss = 0;
10685                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10686                            isSleeping(), now);
10687                }
10688            }
10689
10690            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10691            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10692        }
10693    }
10694
10695    private void retrieveSettings() {
10696        final ContentResolver resolver = mContext.getContentResolver();
10697        String debugApp = Settings.Global.getString(
10698            resolver, Settings.Global.DEBUG_APP);
10699        boolean waitForDebugger = Settings.Global.getInt(
10700            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10701        boolean alwaysFinishActivities = Settings.Global.getInt(
10702            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10703        boolean forceRtl = Settings.Global.getInt(
10704                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10705        // Transfer any global setting for forcing RTL layout, into a System Property
10706        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10707
10708        Configuration configuration = new Configuration();
10709        Settings.System.getConfiguration(resolver, configuration);
10710        if (forceRtl) {
10711            // This will take care of setting the correct layout direction flags
10712            configuration.setLayoutDirection(configuration.locale);
10713        }
10714
10715        synchronized (this) {
10716            mDebugApp = mOrigDebugApp = debugApp;
10717            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10718            mAlwaysFinishActivities = alwaysFinishActivities;
10719            // This happens before any activities are started, so we can
10720            // change mConfiguration in-place.
10721            updateConfigurationLocked(configuration, null, false, true);
10722            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10723        }
10724    }
10725
10726    /** Loads resources after the current configuration has been set. */
10727    private void loadResourcesOnSystemReady() {
10728        final Resources res = mContext.getResources();
10729        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10730        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10731        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10732    }
10733
10734    public boolean testIsSystemReady() {
10735        // no need to synchronize(this) just to read & return the value
10736        return mSystemReady;
10737    }
10738
10739    private static File getCalledPreBootReceiversFile() {
10740        File dataDir = Environment.getDataDirectory();
10741        File systemDir = new File(dataDir, "system");
10742        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10743        return fname;
10744    }
10745
10746    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10747        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10748        File file = getCalledPreBootReceiversFile();
10749        FileInputStream fis = null;
10750        try {
10751            fis = new FileInputStream(file);
10752            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10753            int fvers = dis.readInt();
10754            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10755                String vers = dis.readUTF();
10756                String codename = dis.readUTF();
10757                String build = dis.readUTF();
10758                if (android.os.Build.VERSION.RELEASE.equals(vers)
10759                        && android.os.Build.VERSION.CODENAME.equals(codename)
10760                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10761                    int num = dis.readInt();
10762                    while (num > 0) {
10763                        num--;
10764                        String pkg = dis.readUTF();
10765                        String cls = dis.readUTF();
10766                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10767                    }
10768                }
10769            }
10770        } catch (FileNotFoundException e) {
10771        } catch (IOException e) {
10772            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10773        } finally {
10774            if (fis != null) {
10775                try {
10776                    fis.close();
10777                } catch (IOException e) {
10778                }
10779            }
10780        }
10781        return lastDoneReceivers;
10782    }
10783
10784    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10785        File file = getCalledPreBootReceiversFile();
10786        FileOutputStream fos = null;
10787        DataOutputStream dos = null;
10788        try {
10789            fos = new FileOutputStream(file);
10790            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10791            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10792            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10793            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10794            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10795            dos.writeInt(list.size());
10796            for (int i=0; i<list.size(); i++) {
10797                dos.writeUTF(list.get(i).getPackageName());
10798                dos.writeUTF(list.get(i).getClassName());
10799            }
10800        } catch (IOException e) {
10801            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10802            file.delete();
10803        } finally {
10804            FileUtils.sync(fos);
10805            if (dos != null) {
10806                try {
10807                    dos.close();
10808                } catch (IOException e) {
10809                    // TODO Auto-generated catch block
10810                    e.printStackTrace();
10811                }
10812            }
10813        }
10814    }
10815
10816    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10817            ArrayList<ComponentName> doneReceivers, int userId) {
10818        boolean waitingUpdate = false;
10819        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10820        List<ResolveInfo> ris = null;
10821        try {
10822            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10823                    intent, null, 0, userId);
10824        } catch (RemoteException e) {
10825        }
10826        if (ris != null) {
10827            for (int i=ris.size()-1; i>=0; i--) {
10828                if ((ris.get(i).activityInfo.applicationInfo.flags
10829                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10830                    ris.remove(i);
10831                }
10832            }
10833            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10834
10835            // For User 0, load the version number. When delivering to a new user, deliver
10836            // to all receivers.
10837            if (userId == UserHandle.USER_OWNER) {
10838                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10839                for (int i=0; i<ris.size(); i++) {
10840                    ActivityInfo ai = ris.get(i).activityInfo;
10841                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10842                    if (lastDoneReceivers.contains(comp)) {
10843                        // We already did the pre boot receiver for this app with the current
10844                        // platform version, so don't do it again...
10845                        ris.remove(i);
10846                        i--;
10847                        // ...however, do keep it as one that has been done, so we don't
10848                        // forget about it when rewriting the file of last done receivers.
10849                        doneReceivers.add(comp);
10850                    }
10851                }
10852            }
10853
10854            // If primary user, send broadcast to all available users, else just to userId
10855            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10856                    : new int[] { userId };
10857            for (int i = 0; i < ris.size(); i++) {
10858                ActivityInfo ai = ris.get(i).activityInfo;
10859                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10860                doneReceivers.add(comp);
10861                intent.setComponent(comp);
10862                for (int j=0; j<users.length; j++) {
10863                    IIntentReceiver finisher = null;
10864                    // On last receiver and user, set up a completion callback
10865                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10866                        finisher = new IIntentReceiver.Stub() {
10867                            public void performReceive(Intent intent, int resultCode,
10868                                    String data, Bundle extras, boolean ordered,
10869                                    boolean sticky, int sendingUser) {
10870                                // The raw IIntentReceiver interface is called
10871                                // with the AM lock held, so redispatch to
10872                                // execute our code without the lock.
10873                                mHandler.post(onFinishCallback);
10874                            }
10875                        };
10876                    }
10877                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10878                            + " for user " + users[j]);
10879                    broadcastIntentLocked(null, null, intent, null, finisher,
10880                            0, null, null, null, AppOpsManager.OP_NONE,
10881                            true, false, MY_PID, Process.SYSTEM_UID,
10882                            users[j]);
10883                    if (finisher != null) {
10884                        waitingUpdate = true;
10885                    }
10886                }
10887            }
10888        }
10889
10890        return waitingUpdate;
10891    }
10892
10893    public void systemReady(final Runnable goingCallback) {
10894        synchronized(this) {
10895            if (mSystemReady) {
10896                // If we're done calling all the receivers, run the next "boot phase" passed in
10897                // by the SystemServer
10898                if (goingCallback != null) {
10899                    goingCallback.run();
10900                }
10901                return;
10902            }
10903
10904            // Make sure we have the current profile info, since it is needed for
10905            // security checks.
10906            updateCurrentProfileIdsLocked();
10907
10908            if (mRecentTasks == null) {
10909                mRecentTasks = mTaskPersister.restoreTasksLocked();
10910                if (!mRecentTasks.isEmpty()) {
10911                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10912                }
10913                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10914                mTaskPersister.startPersisting();
10915            }
10916
10917            // Check to see if there are any update receivers to run.
10918            if (!mDidUpdate) {
10919                if (mWaitingUpdate) {
10920                    return;
10921                }
10922                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10923                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10924                    public void run() {
10925                        synchronized (ActivityManagerService.this) {
10926                            mDidUpdate = true;
10927                        }
10928                        writeLastDonePreBootReceivers(doneReceivers);
10929                        showBootMessage(mContext.getText(
10930                                R.string.android_upgrading_complete),
10931                                false);
10932                        systemReady(goingCallback);
10933                    }
10934                }, doneReceivers, UserHandle.USER_OWNER);
10935
10936                if (mWaitingUpdate) {
10937                    return;
10938                }
10939                mDidUpdate = true;
10940            }
10941
10942            mAppOpsService.systemReady();
10943            mSystemReady = true;
10944        }
10945
10946        ArrayList<ProcessRecord> procsToKill = null;
10947        synchronized(mPidsSelfLocked) {
10948            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10949                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10950                if (!isAllowedWhileBooting(proc.info)){
10951                    if (procsToKill == null) {
10952                        procsToKill = new ArrayList<ProcessRecord>();
10953                    }
10954                    procsToKill.add(proc);
10955                }
10956            }
10957        }
10958
10959        synchronized(this) {
10960            if (procsToKill != null) {
10961                for (int i=procsToKill.size()-1; i>=0; i--) {
10962                    ProcessRecord proc = procsToKill.get(i);
10963                    Slog.i(TAG, "Removing system update proc: " + proc);
10964                    removeProcessLocked(proc, true, false, "system update done");
10965                }
10966            }
10967
10968            // Now that we have cleaned up any update processes, we
10969            // are ready to start launching real processes and know that
10970            // we won't trample on them any more.
10971            mProcessesReady = true;
10972        }
10973
10974        Slog.i(TAG, "System now ready");
10975        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10976            SystemClock.uptimeMillis());
10977
10978        synchronized(this) {
10979            // Make sure we have no pre-ready processes sitting around.
10980
10981            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10982                ResolveInfo ri = mContext.getPackageManager()
10983                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10984                                STOCK_PM_FLAGS);
10985                CharSequence errorMsg = null;
10986                if (ri != null) {
10987                    ActivityInfo ai = ri.activityInfo;
10988                    ApplicationInfo app = ai.applicationInfo;
10989                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10990                        mTopAction = Intent.ACTION_FACTORY_TEST;
10991                        mTopData = null;
10992                        mTopComponent = new ComponentName(app.packageName,
10993                                ai.name);
10994                    } else {
10995                        errorMsg = mContext.getResources().getText(
10996                                com.android.internal.R.string.factorytest_not_system);
10997                    }
10998                } else {
10999                    errorMsg = mContext.getResources().getText(
11000                            com.android.internal.R.string.factorytest_no_action);
11001                }
11002                if (errorMsg != null) {
11003                    mTopAction = null;
11004                    mTopData = null;
11005                    mTopComponent = null;
11006                    Message msg = Message.obtain();
11007                    msg.what = SHOW_FACTORY_ERROR_MSG;
11008                    msg.getData().putCharSequence("msg", errorMsg);
11009                    mHandler.sendMessage(msg);
11010                }
11011            }
11012        }
11013
11014        retrieveSettings();
11015        loadResourcesOnSystemReady();
11016
11017        synchronized (this) {
11018            readGrantedUriPermissionsLocked();
11019        }
11020
11021        if (goingCallback != null) goingCallback.run();
11022
11023        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11024                Integer.toString(mCurrentUserId), mCurrentUserId);
11025        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11026                Integer.toString(mCurrentUserId), mCurrentUserId);
11027        mSystemServiceManager.startUser(mCurrentUserId);
11028
11029        synchronized (this) {
11030            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11031                try {
11032                    List apps = AppGlobals.getPackageManager().
11033                        getPersistentApplications(STOCK_PM_FLAGS);
11034                    if (apps != null) {
11035                        int N = apps.size();
11036                        int i;
11037                        for (i=0; i<N; i++) {
11038                            ApplicationInfo info
11039                                = (ApplicationInfo)apps.get(i);
11040                            if (info != null &&
11041                                    !info.packageName.equals("android")) {
11042                                addAppLocked(info, false, null /* ABI override */);
11043                            }
11044                        }
11045                    }
11046                } catch (RemoteException ex) {
11047                    // pm is in same process, this will never happen.
11048                }
11049            }
11050
11051            // Start up initial activity.
11052            mBooting = true;
11053
11054            try {
11055                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11056                    Message msg = Message.obtain();
11057                    msg.what = SHOW_UID_ERROR_MSG;
11058                    mHandler.sendMessage(msg);
11059                }
11060            } catch (RemoteException e) {
11061            }
11062
11063            long ident = Binder.clearCallingIdentity();
11064            try {
11065                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11066                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11067                        | Intent.FLAG_RECEIVER_FOREGROUND);
11068                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11069                broadcastIntentLocked(null, null, intent,
11070                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11071                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11072                intent = new Intent(Intent.ACTION_USER_STARTING);
11073                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11074                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11075                broadcastIntentLocked(null, null, intent,
11076                        null, new IIntentReceiver.Stub() {
11077                            @Override
11078                            public void performReceive(Intent intent, int resultCode, String data,
11079                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11080                                    throws RemoteException {
11081                            }
11082                        }, 0, null, null,
11083                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11084                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11085            } catch (Throwable t) {
11086                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11087            } finally {
11088                Binder.restoreCallingIdentity(ident);
11089            }
11090            mStackSupervisor.resumeTopActivitiesLocked();
11091            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11092        }
11093    }
11094
11095    private boolean makeAppCrashingLocked(ProcessRecord app,
11096            String shortMsg, String longMsg, String stackTrace) {
11097        app.crashing = true;
11098        app.crashingReport = generateProcessError(app,
11099                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11100        startAppProblemLocked(app);
11101        app.stopFreezingAllLocked();
11102        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11103    }
11104
11105    private void makeAppNotRespondingLocked(ProcessRecord app,
11106            String activity, String shortMsg, String longMsg) {
11107        app.notResponding = true;
11108        app.notRespondingReport = generateProcessError(app,
11109                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11110                activity, shortMsg, longMsg, null);
11111        startAppProblemLocked(app);
11112        app.stopFreezingAllLocked();
11113    }
11114
11115    /**
11116     * Generate a process error record, suitable for attachment to a ProcessRecord.
11117     *
11118     * @param app The ProcessRecord in which the error occurred.
11119     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11120     *                      ActivityManager.AppErrorStateInfo
11121     * @param activity The activity associated with the crash, if known.
11122     * @param shortMsg Short message describing the crash.
11123     * @param longMsg Long message describing the crash.
11124     * @param stackTrace Full crash stack trace, may be null.
11125     *
11126     * @return Returns a fully-formed AppErrorStateInfo record.
11127     */
11128    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11129            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11130        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11131
11132        report.condition = condition;
11133        report.processName = app.processName;
11134        report.pid = app.pid;
11135        report.uid = app.info.uid;
11136        report.tag = activity;
11137        report.shortMsg = shortMsg;
11138        report.longMsg = longMsg;
11139        report.stackTrace = stackTrace;
11140
11141        return report;
11142    }
11143
11144    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11145        synchronized (this) {
11146            app.crashing = false;
11147            app.crashingReport = null;
11148            app.notResponding = false;
11149            app.notRespondingReport = null;
11150            if (app.anrDialog == fromDialog) {
11151                app.anrDialog = null;
11152            }
11153            if (app.waitDialog == fromDialog) {
11154                app.waitDialog = null;
11155            }
11156            if (app.pid > 0 && app.pid != MY_PID) {
11157                handleAppCrashLocked(app, null, null, null);
11158                app.kill("user request after error", true);
11159            }
11160        }
11161    }
11162
11163    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11164            String stackTrace) {
11165        long now = SystemClock.uptimeMillis();
11166
11167        Long crashTime;
11168        if (!app.isolated) {
11169            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11170        } else {
11171            crashTime = null;
11172        }
11173        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11174            // This process loses!
11175            Slog.w(TAG, "Process " + app.info.processName
11176                    + " has crashed too many times: killing!");
11177            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11178                    app.userId, app.info.processName, app.uid);
11179            mStackSupervisor.handleAppCrashLocked(app);
11180            if (!app.persistent) {
11181                // We don't want to start this process again until the user
11182                // explicitly does so...  but for persistent process, we really
11183                // need to keep it running.  If a persistent process is actually
11184                // repeatedly crashing, then badness for everyone.
11185                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11186                        app.info.processName);
11187                if (!app.isolated) {
11188                    // XXX We don't have a way to mark isolated processes
11189                    // as bad, since they don't have a peristent identity.
11190                    mBadProcesses.put(app.info.processName, app.uid,
11191                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11192                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11193                }
11194                app.bad = true;
11195                app.removed = true;
11196                // Don't let services in this process be restarted and potentially
11197                // annoy the user repeatedly.  Unless it is persistent, since those
11198                // processes run critical code.
11199                removeProcessLocked(app, false, false, "crash");
11200                mStackSupervisor.resumeTopActivitiesLocked();
11201                return false;
11202            }
11203            mStackSupervisor.resumeTopActivitiesLocked();
11204        } else {
11205            mStackSupervisor.finishTopRunningActivityLocked(app);
11206        }
11207
11208        // Bump up the crash count of any services currently running in the proc.
11209        for (int i=app.services.size()-1; i>=0; i--) {
11210            // Any services running in the application need to be placed
11211            // back in the pending list.
11212            ServiceRecord sr = app.services.valueAt(i);
11213            sr.crashCount++;
11214        }
11215
11216        // If the crashing process is what we consider to be the "home process" and it has been
11217        // replaced by a third-party app, clear the package preferred activities from packages
11218        // with a home activity running in the process to prevent a repeatedly crashing app
11219        // from blocking the user to manually clear the list.
11220        final ArrayList<ActivityRecord> activities = app.activities;
11221        if (app == mHomeProcess && activities.size() > 0
11222                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11223            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11224                final ActivityRecord r = activities.get(activityNdx);
11225                if (r.isHomeActivity()) {
11226                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11227                    try {
11228                        ActivityThread.getPackageManager()
11229                                .clearPackagePreferredActivities(r.packageName);
11230                    } catch (RemoteException c) {
11231                        // pm is in same process, this will never happen.
11232                    }
11233                }
11234            }
11235        }
11236
11237        if (!app.isolated) {
11238            // XXX Can't keep track of crash times for isolated processes,
11239            // because they don't have a perisistent identity.
11240            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11241        }
11242
11243        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11244        return true;
11245    }
11246
11247    void startAppProblemLocked(ProcessRecord app) {
11248        // If this app is not running under the current user, then we
11249        // can't give it a report button because that would require
11250        // launching the report UI under a different user.
11251        app.errorReportReceiver = null;
11252
11253        for (int userId : mCurrentProfileIds) {
11254            if (app.userId == userId) {
11255                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11256                        mContext, app.info.packageName, app.info.flags);
11257            }
11258        }
11259        skipCurrentReceiverLocked(app);
11260    }
11261
11262    void skipCurrentReceiverLocked(ProcessRecord app) {
11263        for (BroadcastQueue queue : mBroadcastQueues) {
11264            queue.skipCurrentReceiverLocked(app);
11265        }
11266    }
11267
11268    /**
11269     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11270     * The application process will exit immediately after this call returns.
11271     * @param app object of the crashing app, null for the system server
11272     * @param crashInfo describing the exception
11273     */
11274    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11275        ProcessRecord r = findAppProcess(app, "Crash");
11276        final String processName = app == null ? "system_server"
11277                : (r == null ? "unknown" : r.processName);
11278
11279        handleApplicationCrashInner("crash", r, processName, crashInfo);
11280    }
11281
11282    /* Native crash reporting uses this inner version because it needs to be somewhat
11283     * decoupled from the AM-managed cleanup lifecycle
11284     */
11285    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11286            ApplicationErrorReport.CrashInfo crashInfo) {
11287        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11288                UserHandle.getUserId(Binder.getCallingUid()), processName,
11289                r == null ? -1 : r.info.flags,
11290                crashInfo.exceptionClassName,
11291                crashInfo.exceptionMessage,
11292                crashInfo.throwFileName,
11293                crashInfo.throwLineNumber);
11294
11295        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11296
11297        crashApplication(r, crashInfo);
11298    }
11299
11300    public void handleApplicationStrictModeViolation(
11301            IBinder app,
11302            int violationMask,
11303            StrictMode.ViolationInfo info) {
11304        ProcessRecord r = findAppProcess(app, "StrictMode");
11305        if (r == null) {
11306            return;
11307        }
11308
11309        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11310            Integer stackFingerprint = info.hashCode();
11311            boolean logIt = true;
11312            synchronized (mAlreadyLoggedViolatedStacks) {
11313                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11314                    logIt = false;
11315                    // TODO: sub-sample into EventLog for these, with
11316                    // the info.durationMillis?  Then we'd get
11317                    // the relative pain numbers, without logging all
11318                    // the stack traces repeatedly.  We'd want to do
11319                    // likewise in the client code, which also does
11320                    // dup suppression, before the Binder call.
11321                } else {
11322                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11323                        mAlreadyLoggedViolatedStacks.clear();
11324                    }
11325                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11326                }
11327            }
11328            if (logIt) {
11329                logStrictModeViolationToDropBox(r, info);
11330            }
11331        }
11332
11333        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11334            AppErrorResult result = new AppErrorResult();
11335            synchronized (this) {
11336                final long origId = Binder.clearCallingIdentity();
11337
11338                Message msg = Message.obtain();
11339                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11340                HashMap<String, Object> data = new HashMap<String, Object>();
11341                data.put("result", result);
11342                data.put("app", r);
11343                data.put("violationMask", violationMask);
11344                data.put("info", info);
11345                msg.obj = data;
11346                mHandler.sendMessage(msg);
11347
11348                Binder.restoreCallingIdentity(origId);
11349            }
11350            int res = result.get();
11351            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11352        }
11353    }
11354
11355    // Depending on the policy in effect, there could be a bunch of
11356    // these in quick succession so we try to batch these together to
11357    // minimize disk writes, number of dropbox entries, and maximize
11358    // compression, by having more fewer, larger records.
11359    private void logStrictModeViolationToDropBox(
11360            ProcessRecord process,
11361            StrictMode.ViolationInfo info) {
11362        if (info == null) {
11363            return;
11364        }
11365        final boolean isSystemApp = process == null ||
11366                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11367                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11368        final String processName = process == null ? "unknown" : process.processName;
11369        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11370        final DropBoxManager dbox = (DropBoxManager)
11371                mContext.getSystemService(Context.DROPBOX_SERVICE);
11372
11373        // Exit early if the dropbox isn't configured to accept this report type.
11374        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11375
11376        boolean bufferWasEmpty;
11377        boolean needsFlush;
11378        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11379        synchronized (sb) {
11380            bufferWasEmpty = sb.length() == 0;
11381            appendDropBoxProcessHeaders(process, processName, sb);
11382            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11383            sb.append("System-App: ").append(isSystemApp).append("\n");
11384            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11385            if (info.violationNumThisLoop != 0) {
11386                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11387            }
11388            if (info.numAnimationsRunning != 0) {
11389                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11390            }
11391            if (info.broadcastIntentAction != null) {
11392                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11393            }
11394            if (info.durationMillis != -1) {
11395                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11396            }
11397            if (info.numInstances != -1) {
11398                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11399            }
11400            if (info.tags != null) {
11401                for (String tag : info.tags) {
11402                    sb.append("Span-Tag: ").append(tag).append("\n");
11403                }
11404            }
11405            sb.append("\n");
11406            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11407                sb.append(info.crashInfo.stackTrace);
11408            }
11409            sb.append("\n");
11410
11411            // Only buffer up to ~64k.  Various logging bits truncate
11412            // things at 128k.
11413            needsFlush = (sb.length() > 64 * 1024);
11414        }
11415
11416        // Flush immediately if the buffer's grown too large, or this
11417        // is a non-system app.  Non-system apps are isolated with a
11418        // different tag & policy and not batched.
11419        //
11420        // Batching is useful during internal testing with
11421        // StrictMode settings turned up high.  Without batching,
11422        // thousands of separate files could be created on boot.
11423        if (!isSystemApp || needsFlush) {
11424            new Thread("Error dump: " + dropboxTag) {
11425                @Override
11426                public void run() {
11427                    String report;
11428                    synchronized (sb) {
11429                        report = sb.toString();
11430                        sb.delete(0, sb.length());
11431                        sb.trimToSize();
11432                    }
11433                    if (report.length() != 0) {
11434                        dbox.addText(dropboxTag, report);
11435                    }
11436                }
11437            }.start();
11438            return;
11439        }
11440
11441        // System app batching:
11442        if (!bufferWasEmpty) {
11443            // An existing dropbox-writing thread is outstanding, so
11444            // we don't need to start it up.  The existing thread will
11445            // catch the buffer appends we just did.
11446            return;
11447        }
11448
11449        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11450        // (After this point, we shouldn't access AMS internal data structures.)
11451        new Thread("Error dump: " + dropboxTag) {
11452            @Override
11453            public void run() {
11454                // 5 second sleep to let stacks arrive and be batched together
11455                try {
11456                    Thread.sleep(5000);  // 5 seconds
11457                } catch (InterruptedException e) {}
11458
11459                String errorReport;
11460                synchronized (mStrictModeBuffer) {
11461                    errorReport = mStrictModeBuffer.toString();
11462                    if (errorReport.length() == 0) {
11463                        return;
11464                    }
11465                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11466                    mStrictModeBuffer.trimToSize();
11467                }
11468                dbox.addText(dropboxTag, errorReport);
11469            }
11470        }.start();
11471    }
11472
11473    /**
11474     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11475     * @param app object of the crashing app, null for the system server
11476     * @param tag reported by the caller
11477     * @param system whether this wtf is coming from the system
11478     * @param crashInfo describing the context of the error
11479     * @return true if the process should exit immediately (WTF is fatal)
11480     */
11481    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11482            final ApplicationErrorReport.CrashInfo crashInfo) {
11483        final ProcessRecord r = findAppProcess(app, "WTF");
11484        final String processName = app == null ? "system_server"
11485                : (r == null ? "unknown" : r.processName);
11486
11487        EventLog.writeEvent(EventLogTags.AM_WTF,
11488                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11489                processName,
11490                r == null ? -1 : r.info.flags,
11491                tag, crashInfo.exceptionMessage);
11492
11493        if (system) {
11494            // If this is coming from the system, we could very well have low-level
11495            // system locks held, so we want to do this all asynchronously.  And we
11496            // never want this to become fatal, so there is that too.
11497            mHandler.post(new Runnable() {
11498                @Override public void run() {
11499                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11500                            crashInfo);
11501                }
11502            });
11503            return false;
11504        }
11505
11506        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11507
11508        if (r != null && r.pid != Process.myPid() &&
11509                Settings.Global.getInt(mContext.getContentResolver(),
11510                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11511            crashApplication(r, crashInfo);
11512            return true;
11513        } else {
11514            return false;
11515        }
11516    }
11517
11518    /**
11519     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11520     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11521     */
11522    private ProcessRecord findAppProcess(IBinder app, String reason) {
11523        if (app == null) {
11524            return null;
11525        }
11526
11527        synchronized (this) {
11528            final int NP = mProcessNames.getMap().size();
11529            for (int ip=0; ip<NP; ip++) {
11530                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11531                final int NA = apps.size();
11532                for (int ia=0; ia<NA; ia++) {
11533                    ProcessRecord p = apps.valueAt(ia);
11534                    if (p.thread != null && p.thread.asBinder() == app) {
11535                        return p;
11536                    }
11537                }
11538            }
11539
11540            Slog.w(TAG, "Can't find mystery application for " + reason
11541                    + " from pid=" + Binder.getCallingPid()
11542                    + " uid=" + Binder.getCallingUid() + ": " + app);
11543            return null;
11544        }
11545    }
11546
11547    /**
11548     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11549     * to append various headers to the dropbox log text.
11550     */
11551    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11552            StringBuilder sb) {
11553        // Watchdog thread ends up invoking this function (with
11554        // a null ProcessRecord) to add the stack file to dropbox.
11555        // Do not acquire a lock on this (am) in such cases, as it
11556        // could cause a potential deadlock, if and when watchdog
11557        // is invoked due to unavailability of lock on am and it
11558        // would prevent watchdog from killing system_server.
11559        if (process == null) {
11560            sb.append("Process: ").append(processName).append("\n");
11561            return;
11562        }
11563        // Note: ProcessRecord 'process' is guarded by the service
11564        // instance.  (notably process.pkgList, which could otherwise change
11565        // concurrently during execution of this method)
11566        synchronized (this) {
11567            sb.append("Process: ").append(processName).append("\n");
11568            int flags = process.info.flags;
11569            IPackageManager pm = AppGlobals.getPackageManager();
11570            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11571            for (int ip=0; ip<process.pkgList.size(); ip++) {
11572                String pkg = process.pkgList.keyAt(ip);
11573                sb.append("Package: ").append(pkg);
11574                try {
11575                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11576                    if (pi != null) {
11577                        sb.append(" v").append(pi.versionCode);
11578                        if (pi.versionName != null) {
11579                            sb.append(" (").append(pi.versionName).append(")");
11580                        }
11581                    }
11582                } catch (RemoteException e) {
11583                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11584                }
11585                sb.append("\n");
11586            }
11587        }
11588    }
11589
11590    private static String processClass(ProcessRecord process) {
11591        if (process == null || process.pid == MY_PID) {
11592            return "system_server";
11593        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11594            return "system_app";
11595        } else {
11596            return "data_app";
11597        }
11598    }
11599
11600    /**
11601     * Write a description of an error (crash, WTF, ANR) to the drop box.
11602     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11603     * @param process which caused the error, null means the system server
11604     * @param activity which triggered the error, null if unknown
11605     * @param parent activity related to the error, null if unknown
11606     * @param subject line related to the error, null if absent
11607     * @param report in long form describing the error, null if absent
11608     * @param logFile to include in the report, null if none
11609     * @param crashInfo giving an application stack trace, null if absent
11610     */
11611    public void addErrorToDropBox(String eventType,
11612            ProcessRecord process, String processName, ActivityRecord activity,
11613            ActivityRecord parent, String subject,
11614            final String report, final File logFile,
11615            final ApplicationErrorReport.CrashInfo crashInfo) {
11616        // NOTE -- this must never acquire the ActivityManagerService lock,
11617        // otherwise the watchdog may be prevented from resetting the system.
11618
11619        final String dropboxTag = processClass(process) + "_" + eventType;
11620        final DropBoxManager dbox = (DropBoxManager)
11621                mContext.getSystemService(Context.DROPBOX_SERVICE);
11622
11623        // Exit early if the dropbox isn't configured to accept this report type.
11624        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11625
11626        final StringBuilder sb = new StringBuilder(1024);
11627        appendDropBoxProcessHeaders(process, processName, sb);
11628        if (activity != null) {
11629            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11630        }
11631        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11632            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11633        }
11634        if (parent != null && parent != activity) {
11635            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11636        }
11637        if (subject != null) {
11638            sb.append("Subject: ").append(subject).append("\n");
11639        }
11640        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11641        if (Debug.isDebuggerConnected()) {
11642            sb.append("Debugger: Connected\n");
11643        }
11644        sb.append("\n");
11645
11646        // Do the rest in a worker thread to avoid blocking the caller on I/O
11647        // (After this point, we shouldn't access AMS internal data structures.)
11648        Thread worker = new Thread("Error dump: " + dropboxTag) {
11649            @Override
11650            public void run() {
11651                if (report != null) {
11652                    sb.append(report);
11653                }
11654                if (logFile != null) {
11655                    try {
11656                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11657                                    "\n\n[[TRUNCATED]]"));
11658                    } catch (IOException e) {
11659                        Slog.e(TAG, "Error reading " + logFile, e);
11660                    }
11661                }
11662                if (crashInfo != null && crashInfo.stackTrace != null) {
11663                    sb.append(crashInfo.stackTrace);
11664                }
11665
11666                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11667                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11668                if (lines > 0) {
11669                    sb.append("\n");
11670
11671                    // Merge several logcat streams, and take the last N lines
11672                    InputStreamReader input = null;
11673                    try {
11674                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11675                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11676                                "-b", "crash",
11677                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11678
11679                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11680                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11681                        input = new InputStreamReader(logcat.getInputStream());
11682
11683                        int num;
11684                        char[] buf = new char[8192];
11685                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11686                    } catch (IOException e) {
11687                        Slog.e(TAG, "Error running logcat", e);
11688                    } finally {
11689                        if (input != null) try { input.close(); } catch (IOException e) {}
11690                    }
11691                }
11692
11693                dbox.addText(dropboxTag, sb.toString());
11694            }
11695        };
11696
11697        if (process == null) {
11698            // If process is null, we are being called from some internal code
11699            // and may be about to die -- run this synchronously.
11700            worker.run();
11701        } else {
11702            worker.start();
11703        }
11704    }
11705
11706    /**
11707     * Bring up the "unexpected error" dialog box for a crashing app.
11708     * Deal with edge cases (intercepts from instrumented applications,
11709     * ActivityController, error intent receivers, that sort of thing).
11710     * @param r the application crashing
11711     * @param crashInfo describing the failure
11712     */
11713    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11714        long timeMillis = System.currentTimeMillis();
11715        String shortMsg = crashInfo.exceptionClassName;
11716        String longMsg = crashInfo.exceptionMessage;
11717        String stackTrace = crashInfo.stackTrace;
11718        if (shortMsg != null && longMsg != null) {
11719            longMsg = shortMsg + ": " + longMsg;
11720        } else if (shortMsg != null) {
11721            longMsg = shortMsg;
11722        }
11723
11724        AppErrorResult result = new AppErrorResult();
11725        synchronized (this) {
11726            if (mController != null) {
11727                try {
11728                    String name = r != null ? r.processName : null;
11729                    int pid = r != null ? r.pid : Binder.getCallingPid();
11730                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11731                    if (!mController.appCrashed(name, pid,
11732                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11733                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11734                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11735                            Slog.w(TAG, "Skip killing native crashed app " + name
11736                                    + "(" + pid + ") during testing");
11737                        } else {
11738                            Slog.w(TAG, "Force-killing crashed app " + name
11739                                    + " at watcher's request");
11740                            if (r != null) {
11741                                r.kill("crash", true);
11742                            } else {
11743                                // Huh.
11744                                Process.killProcess(pid);
11745                                Process.killProcessGroup(uid, pid);
11746                            }
11747                        }
11748                        return;
11749                    }
11750                } catch (RemoteException e) {
11751                    mController = null;
11752                    Watchdog.getInstance().setActivityController(null);
11753                }
11754            }
11755
11756            final long origId = Binder.clearCallingIdentity();
11757
11758            // If this process is running instrumentation, finish it.
11759            if (r != null && r.instrumentationClass != null) {
11760                Slog.w(TAG, "Error in app " + r.processName
11761                      + " running instrumentation " + r.instrumentationClass + ":");
11762                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11763                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11764                Bundle info = new Bundle();
11765                info.putString("shortMsg", shortMsg);
11766                info.putString("longMsg", longMsg);
11767                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11768                Binder.restoreCallingIdentity(origId);
11769                return;
11770            }
11771
11772            // If we can't identify the process or it's already exceeded its crash quota,
11773            // quit right away without showing a crash dialog.
11774            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11775                Binder.restoreCallingIdentity(origId);
11776                return;
11777            }
11778
11779            Message msg = Message.obtain();
11780            msg.what = SHOW_ERROR_MSG;
11781            HashMap data = new HashMap();
11782            data.put("result", result);
11783            data.put("app", r);
11784            msg.obj = data;
11785            mHandler.sendMessage(msg);
11786
11787            Binder.restoreCallingIdentity(origId);
11788        }
11789
11790        int res = result.get();
11791
11792        Intent appErrorIntent = null;
11793        synchronized (this) {
11794            if (r != null && !r.isolated) {
11795                // XXX Can't keep track of crash time for isolated processes,
11796                // since they don't have a persistent identity.
11797                mProcessCrashTimes.put(r.info.processName, r.uid,
11798                        SystemClock.uptimeMillis());
11799            }
11800            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11801                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11802            }
11803        }
11804
11805        if (appErrorIntent != null) {
11806            try {
11807                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11808            } catch (ActivityNotFoundException e) {
11809                Slog.w(TAG, "bug report receiver dissappeared", e);
11810            }
11811        }
11812    }
11813
11814    Intent createAppErrorIntentLocked(ProcessRecord r,
11815            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11816        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11817        if (report == null) {
11818            return null;
11819        }
11820        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11821        result.setComponent(r.errorReportReceiver);
11822        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11823        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11824        return result;
11825    }
11826
11827    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11828            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11829        if (r.errorReportReceiver == null) {
11830            return null;
11831        }
11832
11833        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11834            return null;
11835        }
11836
11837        ApplicationErrorReport report = new ApplicationErrorReport();
11838        report.packageName = r.info.packageName;
11839        report.installerPackageName = r.errorReportReceiver.getPackageName();
11840        report.processName = r.processName;
11841        report.time = timeMillis;
11842        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11843
11844        if (r.crashing || r.forceCrashReport) {
11845            report.type = ApplicationErrorReport.TYPE_CRASH;
11846            report.crashInfo = crashInfo;
11847        } else if (r.notResponding) {
11848            report.type = ApplicationErrorReport.TYPE_ANR;
11849            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11850
11851            report.anrInfo.activity = r.notRespondingReport.tag;
11852            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11853            report.anrInfo.info = r.notRespondingReport.longMsg;
11854        }
11855
11856        return report;
11857    }
11858
11859    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11860        enforceNotIsolatedCaller("getProcessesInErrorState");
11861        // assume our apps are happy - lazy create the list
11862        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11863
11864        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11865                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11866        int userId = UserHandle.getUserId(Binder.getCallingUid());
11867
11868        synchronized (this) {
11869
11870            // iterate across all processes
11871            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11872                ProcessRecord app = mLruProcesses.get(i);
11873                if (!allUsers && app.userId != userId) {
11874                    continue;
11875                }
11876                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11877                    // This one's in trouble, so we'll generate a report for it
11878                    // crashes are higher priority (in case there's a crash *and* an anr)
11879                    ActivityManager.ProcessErrorStateInfo report = null;
11880                    if (app.crashing) {
11881                        report = app.crashingReport;
11882                    } else if (app.notResponding) {
11883                        report = app.notRespondingReport;
11884                    }
11885
11886                    if (report != null) {
11887                        if (errList == null) {
11888                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11889                        }
11890                        errList.add(report);
11891                    } else {
11892                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11893                                " crashing = " + app.crashing +
11894                                " notResponding = " + app.notResponding);
11895                    }
11896                }
11897            }
11898        }
11899
11900        return errList;
11901    }
11902
11903    static int procStateToImportance(int procState, int memAdj,
11904            ActivityManager.RunningAppProcessInfo currApp) {
11905        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11906        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11907            currApp.lru = memAdj;
11908        } else {
11909            currApp.lru = 0;
11910        }
11911        return imp;
11912    }
11913
11914    private void fillInProcMemInfo(ProcessRecord app,
11915            ActivityManager.RunningAppProcessInfo outInfo) {
11916        outInfo.pid = app.pid;
11917        outInfo.uid = app.info.uid;
11918        if (mHeavyWeightProcess == app) {
11919            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11920        }
11921        if (app.persistent) {
11922            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11923        }
11924        if (app.activities.size() > 0) {
11925            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11926        }
11927        outInfo.lastTrimLevel = app.trimMemoryLevel;
11928        int adj = app.curAdj;
11929        int procState = app.curProcState;
11930        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11931        outInfo.importanceReasonCode = app.adjTypeCode;
11932        outInfo.processState = app.curProcState;
11933    }
11934
11935    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11936        enforceNotIsolatedCaller("getRunningAppProcesses");
11937        // Lazy instantiation of list
11938        List<ActivityManager.RunningAppProcessInfo> runList = null;
11939        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11940                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11941        int userId = UserHandle.getUserId(Binder.getCallingUid());
11942        synchronized (this) {
11943            // Iterate across all processes
11944            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11945                ProcessRecord app = mLruProcesses.get(i);
11946                if (!allUsers && app.userId != userId) {
11947                    continue;
11948                }
11949                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11950                    // Generate process state info for running application
11951                    ActivityManager.RunningAppProcessInfo currApp =
11952                        new ActivityManager.RunningAppProcessInfo(app.processName,
11953                                app.pid, app.getPackageList());
11954                    fillInProcMemInfo(app, currApp);
11955                    if (app.adjSource instanceof ProcessRecord) {
11956                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11957                        currApp.importanceReasonImportance =
11958                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11959                                        app.adjSourceProcState);
11960                    } else if (app.adjSource instanceof ActivityRecord) {
11961                        ActivityRecord r = (ActivityRecord)app.adjSource;
11962                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11963                    }
11964                    if (app.adjTarget instanceof ComponentName) {
11965                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11966                    }
11967                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11968                    //        + " lru=" + currApp.lru);
11969                    if (runList == null) {
11970                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11971                    }
11972                    runList.add(currApp);
11973                }
11974            }
11975        }
11976        return runList;
11977    }
11978
11979    public List<ApplicationInfo> getRunningExternalApplications() {
11980        enforceNotIsolatedCaller("getRunningExternalApplications");
11981        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11982        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11983        if (runningApps != null && runningApps.size() > 0) {
11984            Set<String> extList = new HashSet<String>();
11985            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11986                if (app.pkgList != null) {
11987                    for (String pkg : app.pkgList) {
11988                        extList.add(pkg);
11989                    }
11990                }
11991            }
11992            IPackageManager pm = AppGlobals.getPackageManager();
11993            for (String pkg : extList) {
11994                try {
11995                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11996                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11997                        retList.add(info);
11998                    }
11999                } catch (RemoteException e) {
12000                }
12001            }
12002        }
12003        return retList;
12004    }
12005
12006    @Override
12007    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12008        enforceNotIsolatedCaller("getMyMemoryState");
12009        synchronized (this) {
12010            ProcessRecord proc;
12011            synchronized (mPidsSelfLocked) {
12012                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12013            }
12014            fillInProcMemInfo(proc, outInfo);
12015        }
12016    }
12017
12018    @Override
12019    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12020        if (checkCallingPermission(android.Manifest.permission.DUMP)
12021                != PackageManager.PERMISSION_GRANTED) {
12022            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12023                    + Binder.getCallingPid()
12024                    + ", uid=" + Binder.getCallingUid()
12025                    + " without permission "
12026                    + android.Manifest.permission.DUMP);
12027            return;
12028        }
12029
12030        boolean dumpAll = false;
12031        boolean dumpClient = false;
12032        String dumpPackage = null;
12033
12034        int opti = 0;
12035        while (opti < args.length) {
12036            String opt = args[opti];
12037            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12038                break;
12039            }
12040            opti++;
12041            if ("-a".equals(opt)) {
12042                dumpAll = true;
12043            } else if ("-c".equals(opt)) {
12044                dumpClient = true;
12045            } else if ("-h".equals(opt)) {
12046                pw.println("Activity manager dump options:");
12047                pw.println("  [-a] [-c] [-h] [cmd] ...");
12048                pw.println("  cmd may be one of:");
12049                pw.println("    a[ctivities]: activity stack state");
12050                pw.println("    r[recents]: recent activities state");
12051                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12052                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12053                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12054                pw.println("    o[om]: out of memory management");
12055                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12056                pw.println("    provider [COMP_SPEC]: provider client-side state");
12057                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12058                pw.println("    service [COMP_SPEC]: service client-side state");
12059                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12060                pw.println("    all: dump all activities");
12061                pw.println("    top: dump the top activity");
12062                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12063                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12064                pw.println("    a partial substring in a component name, a");
12065                pw.println("    hex object identifier.");
12066                pw.println("  -a: include all available server state.");
12067                pw.println("  -c: include client state.");
12068                return;
12069            } else {
12070                pw.println("Unknown argument: " + opt + "; use -h for help");
12071            }
12072        }
12073
12074        long origId = Binder.clearCallingIdentity();
12075        boolean more = false;
12076        // Is the caller requesting to dump a particular piece of data?
12077        if (opti < args.length) {
12078            String cmd = args[opti];
12079            opti++;
12080            if ("activities".equals(cmd) || "a".equals(cmd)) {
12081                synchronized (this) {
12082                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12083                }
12084            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12085                synchronized (this) {
12086                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12087                }
12088            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12089                String[] newArgs;
12090                String name;
12091                if (opti >= args.length) {
12092                    name = null;
12093                    newArgs = EMPTY_STRING_ARRAY;
12094                } else {
12095                    name = args[opti];
12096                    opti++;
12097                    newArgs = new String[args.length - opti];
12098                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12099                            args.length - opti);
12100                }
12101                synchronized (this) {
12102                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12103                }
12104            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12105                String[] newArgs;
12106                String name;
12107                if (opti >= args.length) {
12108                    name = null;
12109                    newArgs = EMPTY_STRING_ARRAY;
12110                } else {
12111                    name = args[opti];
12112                    opti++;
12113                    newArgs = new String[args.length - opti];
12114                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12115                            args.length - opti);
12116                }
12117                synchronized (this) {
12118                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12119                }
12120            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12121                String[] newArgs;
12122                String name;
12123                if (opti >= args.length) {
12124                    name = null;
12125                    newArgs = EMPTY_STRING_ARRAY;
12126                } else {
12127                    name = args[opti];
12128                    opti++;
12129                    newArgs = new String[args.length - opti];
12130                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12131                            args.length - opti);
12132                }
12133                synchronized (this) {
12134                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12135                }
12136            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12137                synchronized (this) {
12138                    dumpOomLocked(fd, pw, args, opti, true);
12139                }
12140            } else if ("provider".equals(cmd)) {
12141                String[] newArgs;
12142                String name;
12143                if (opti >= args.length) {
12144                    name = null;
12145                    newArgs = EMPTY_STRING_ARRAY;
12146                } else {
12147                    name = args[opti];
12148                    opti++;
12149                    newArgs = new String[args.length - opti];
12150                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12151                }
12152                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12153                    pw.println("No providers match: " + name);
12154                    pw.println("Use -h for help.");
12155                }
12156            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12157                synchronized (this) {
12158                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12159                }
12160            } else if ("service".equals(cmd)) {
12161                String[] newArgs;
12162                String name;
12163                if (opti >= args.length) {
12164                    name = null;
12165                    newArgs = EMPTY_STRING_ARRAY;
12166                } else {
12167                    name = args[opti];
12168                    opti++;
12169                    newArgs = new String[args.length - opti];
12170                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12171                            args.length - opti);
12172                }
12173                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12174                    pw.println("No services match: " + name);
12175                    pw.println("Use -h for help.");
12176                }
12177            } else if ("package".equals(cmd)) {
12178                String[] newArgs;
12179                if (opti >= args.length) {
12180                    pw.println("package: no package name specified");
12181                    pw.println("Use -h for help.");
12182                } else {
12183                    dumpPackage = args[opti];
12184                    opti++;
12185                    newArgs = new String[args.length - opti];
12186                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12187                            args.length - opti);
12188                    args = newArgs;
12189                    opti = 0;
12190                    more = true;
12191                }
12192            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12193                synchronized (this) {
12194                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12195                }
12196            } else {
12197                // Dumping a single activity?
12198                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12199                    pw.println("Bad activity command, or no activities match: " + cmd);
12200                    pw.println("Use -h for help.");
12201                }
12202            }
12203            if (!more) {
12204                Binder.restoreCallingIdentity(origId);
12205                return;
12206            }
12207        }
12208
12209        // No piece of data specified, dump everything.
12210        synchronized (this) {
12211            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12212            pw.println();
12213            if (dumpAll) {
12214                pw.println("-------------------------------------------------------------------------------");
12215            }
12216            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12217            pw.println();
12218            if (dumpAll) {
12219                pw.println("-------------------------------------------------------------------------------");
12220            }
12221            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12222            pw.println();
12223            if (dumpAll) {
12224                pw.println("-------------------------------------------------------------------------------");
12225            }
12226            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12227            pw.println();
12228            if (dumpAll) {
12229                pw.println("-------------------------------------------------------------------------------");
12230            }
12231            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12232            pw.println();
12233            if (dumpAll) {
12234                pw.println("-------------------------------------------------------------------------------");
12235            }
12236            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12237            pw.println();
12238            if (dumpAll) {
12239                pw.println("-------------------------------------------------------------------------------");
12240            }
12241            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12242        }
12243        Binder.restoreCallingIdentity(origId);
12244    }
12245
12246    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12247            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12248        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12249
12250        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12251                dumpPackage);
12252        boolean needSep = printedAnything;
12253
12254        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12255                dumpPackage, needSep, "  mFocusedActivity: ");
12256        if (printed) {
12257            printedAnything = true;
12258            needSep = false;
12259        }
12260
12261        if (dumpPackage == null) {
12262            if (needSep) {
12263                pw.println();
12264            }
12265            needSep = true;
12266            printedAnything = true;
12267            mStackSupervisor.dump(pw, "  ");
12268        }
12269
12270        if (!printedAnything) {
12271            pw.println("  (nothing)");
12272        }
12273    }
12274
12275    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12276            int opti, boolean dumpAll, String dumpPackage) {
12277        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12278
12279        boolean printedAnything = false;
12280
12281        if (mRecentTasks.size() > 0) {
12282            boolean printedHeader = false;
12283
12284            final int N = mRecentTasks.size();
12285            for (int i=0; i<N; i++) {
12286                TaskRecord tr = mRecentTasks.get(i);
12287                if (dumpPackage != null) {
12288                    if (tr.realActivity == null ||
12289                            !dumpPackage.equals(tr.realActivity)) {
12290                        continue;
12291                    }
12292                }
12293                if (!printedHeader) {
12294                    pw.println("  Recent tasks:");
12295                    printedHeader = true;
12296                    printedAnything = true;
12297                }
12298                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12299                        pw.println(tr);
12300                if (dumpAll) {
12301                    mRecentTasks.get(i).dump(pw, "    ");
12302                }
12303            }
12304        }
12305
12306        if (!printedAnything) {
12307            pw.println("  (nothing)");
12308        }
12309    }
12310
12311    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12312            int opti, boolean dumpAll, String dumpPackage) {
12313        boolean needSep = false;
12314        boolean printedAnything = false;
12315        int numPers = 0;
12316
12317        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12318
12319        if (dumpAll) {
12320            final int NP = mProcessNames.getMap().size();
12321            for (int ip=0; ip<NP; ip++) {
12322                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12323                final int NA = procs.size();
12324                for (int ia=0; ia<NA; ia++) {
12325                    ProcessRecord r = procs.valueAt(ia);
12326                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12327                        continue;
12328                    }
12329                    if (!needSep) {
12330                        pw.println("  All known processes:");
12331                        needSep = true;
12332                        printedAnything = true;
12333                    }
12334                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12335                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12336                        pw.print(" "); pw.println(r);
12337                    r.dump(pw, "    ");
12338                    if (r.persistent) {
12339                        numPers++;
12340                    }
12341                }
12342            }
12343        }
12344
12345        if (mIsolatedProcesses.size() > 0) {
12346            boolean printed = false;
12347            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12348                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12349                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12350                    continue;
12351                }
12352                if (!printed) {
12353                    if (needSep) {
12354                        pw.println();
12355                    }
12356                    pw.println("  Isolated process list (sorted by uid):");
12357                    printedAnything = true;
12358                    printed = true;
12359                    needSep = true;
12360                }
12361                pw.println(String.format("%sIsolated #%2d: %s",
12362                        "    ", i, r.toString()));
12363            }
12364        }
12365
12366        if (mLruProcesses.size() > 0) {
12367            if (needSep) {
12368                pw.println();
12369            }
12370            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12371                    pw.print(" total, non-act at ");
12372                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12373                    pw.print(", non-svc at ");
12374                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12375                    pw.println("):");
12376            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12377            needSep = true;
12378            printedAnything = true;
12379        }
12380
12381        if (dumpAll || dumpPackage != null) {
12382            synchronized (mPidsSelfLocked) {
12383                boolean printed = false;
12384                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12385                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12386                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12387                        continue;
12388                    }
12389                    if (!printed) {
12390                        if (needSep) pw.println();
12391                        needSep = true;
12392                        pw.println("  PID mappings:");
12393                        printed = true;
12394                        printedAnything = true;
12395                    }
12396                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12397                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12398                }
12399            }
12400        }
12401
12402        if (mForegroundProcesses.size() > 0) {
12403            synchronized (mPidsSelfLocked) {
12404                boolean printed = false;
12405                for (int i=0; i<mForegroundProcesses.size(); i++) {
12406                    ProcessRecord r = mPidsSelfLocked.get(
12407                            mForegroundProcesses.valueAt(i).pid);
12408                    if (dumpPackage != null && (r == null
12409                            || !r.pkgList.containsKey(dumpPackage))) {
12410                        continue;
12411                    }
12412                    if (!printed) {
12413                        if (needSep) pw.println();
12414                        needSep = true;
12415                        pw.println("  Foreground Processes:");
12416                        printed = true;
12417                        printedAnything = true;
12418                    }
12419                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12420                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12421                }
12422            }
12423        }
12424
12425        if (mPersistentStartingProcesses.size() > 0) {
12426            if (needSep) pw.println();
12427            needSep = true;
12428            printedAnything = true;
12429            pw.println("  Persisent processes that are starting:");
12430            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12431                    "Starting Norm", "Restarting PERS", dumpPackage);
12432        }
12433
12434        if (mRemovedProcesses.size() > 0) {
12435            if (needSep) pw.println();
12436            needSep = true;
12437            printedAnything = true;
12438            pw.println("  Processes that are being removed:");
12439            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12440                    "Removed Norm", "Removed PERS", dumpPackage);
12441        }
12442
12443        if (mProcessesOnHold.size() > 0) {
12444            if (needSep) pw.println();
12445            needSep = true;
12446            printedAnything = true;
12447            pw.println("  Processes that are on old until the system is ready:");
12448            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12449                    "OnHold Norm", "OnHold PERS", dumpPackage);
12450        }
12451
12452        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12453
12454        if (mProcessCrashTimes.getMap().size() > 0) {
12455            boolean printed = false;
12456            long now = SystemClock.uptimeMillis();
12457            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12458            final int NP = pmap.size();
12459            for (int ip=0; ip<NP; ip++) {
12460                String pname = pmap.keyAt(ip);
12461                SparseArray<Long> uids = pmap.valueAt(ip);
12462                final int N = uids.size();
12463                for (int i=0; i<N; i++) {
12464                    int puid = uids.keyAt(i);
12465                    ProcessRecord r = mProcessNames.get(pname, puid);
12466                    if (dumpPackage != null && (r == null
12467                            || !r.pkgList.containsKey(dumpPackage))) {
12468                        continue;
12469                    }
12470                    if (!printed) {
12471                        if (needSep) pw.println();
12472                        needSep = true;
12473                        pw.println("  Time since processes crashed:");
12474                        printed = true;
12475                        printedAnything = true;
12476                    }
12477                    pw.print("    Process "); pw.print(pname);
12478                            pw.print(" uid "); pw.print(puid);
12479                            pw.print(": last crashed ");
12480                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12481                            pw.println(" ago");
12482                }
12483            }
12484        }
12485
12486        if (mBadProcesses.getMap().size() > 0) {
12487            boolean printed = false;
12488            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12489            final int NP = pmap.size();
12490            for (int ip=0; ip<NP; ip++) {
12491                String pname = pmap.keyAt(ip);
12492                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12493                final int N = uids.size();
12494                for (int i=0; i<N; i++) {
12495                    int puid = uids.keyAt(i);
12496                    ProcessRecord r = mProcessNames.get(pname, puid);
12497                    if (dumpPackage != null && (r == null
12498                            || !r.pkgList.containsKey(dumpPackage))) {
12499                        continue;
12500                    }
12501                    if (!printed) {
12502                        if (needSep) pw.println();
12503                        needSep = true;
12504                        pw.println("  Bad processes:");
12505                        printedAnything = true;
12506                    }
12507                    BadProcessInfo info = uids.valueAt(i);
12508                    pw.print("    Bad process "); pw.print(pname);
12509                            pw.print(" uid "); pw.print(puid);
12510                            pw.print(": crashed at time "); pw.println(info.time);
12511                    if (info.shortMsg != null) {
12512                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12513                    }
12514                    if (info.longMsg != null) {
12515                        pw.print("      Long msg: "); pw.println(info.longMsg);
12516                    }
12517                    if (info.stack != null) {
12518                        pw.println("      Stack:");
12519                        int lastPos = 0;
12520                        for (int pos=0; pos<info.stack.length(); pos++) {
12521                            if (info.stack.charAt(pos) == '\n') {
12522                                pw.print("        ");
12523                                pw.write(info.stack, lastPos, pos-lastPos);
12524                                pw.println();
12525                                lastPos = pos+1;
12526                            }
12527                        }
12528                        if (lastPos < info.stack.length()) {
12529                            pw.print("        ");
12530                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12531                            pw.println();
12532                        }
12533                    }
12534                }
12535            }
12536        }
12537
12538        if (dumpPackage == null) {
12539            pw.println();
12540            needSep = false;
12541            pw.println("  mStartedUsers:");
12542            for (int i=0; i<mStartedUsers.size(); i++) {
12543                UserStartedState uss = mStartedUsers.valueAt(i);
12544                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12545                        pw.print(": "); uss.dump("", pw);
12546            }
12547            pw.print("  mStartedUserArray: [");
12548            for (int i=0; i<mStartedUserArray.length; i++) {
12549                if (i > 0) pw.print(", ");
12550                pw.print(mStartedUserArray[i]);
12551            }
12552            pw.println("]");
12553            pw.print("  mUserLru: [");
12554            for (int i=0; i<mUserLru.size(); i++) {
12555                if (i > 0) pw.print(", ");
12556                pw.print(mUserLru.get(i));
12557            }
12558            pw.println("]");
12559            if (dumpAll) {
12560                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12561            }
12562            synchronized (mUserProfileGroupIdsSelfLocked) {
12563                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12564                    pw.println("  mUserProfileGroupIds:");
12565                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12566                        pw.print("    User #");
12567                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12568                        pw.print(" -> profile #");
12569                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12570                    }
12571                }
12572            }
12573        }
12574        if (mHomeProcess != null && (dumpPackage == null
12575                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12576            if (needSep) {
12577                pw.println();
12578                needSep = false;
12579            }
12580            pw.println("  mHomeProcess: " + mHomeProcess);
12581        }
12582        if (mPreviousProcess != null && (dumpPackage == null
12583                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12584            if (needSep) {
12585                pw.println();
12586                needSep = false;
12587            }
12588            pw.println("  mPreviousProcess: " + mPreviousProcess);
12589        }
12590        if (dumpAll) {
12591            StringBuilder sb = new StringBuilder(128);
12592            sb.append("  mPreviousProcessVisibleTime: ");
12593            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12594            pw.println(sb);
12595        }
12596        if (mHeavyWeightProcess != null && (dumpPackage == null
12597                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12598            if (needSep) {
12599                pw.println();
12600                needSep = false;
12601            }
12602            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12603        }
12604        if (dumpPackage == null) {
12605            pw.println("  mConfiguration: " + mConfiguration);
12606        }
12607        if (dumpAll) {
12608            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12609            if (mCompatModePackages.getPackages().size() > 0) {
12610                boolean printed = false;
12611                for (Map.Entry<String, Integer> entry
12612                        : mCompatModePackages.getPackages().entrySet()) {
12613                    String pkg = entry.getKey();
12614                    int mode = entry.getValue();
12615                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12616                        continue;
12617                    }
12618                    if (!printed) {
12619                        pw.println("  mScreenCompatPackages:");
12620                        printed = true;
12621                    }
12622                    pw.print("    "); pw.print(pkg); pw.print(": ");
12623                            pw.print(mode); pw.println();
12624                }
12625            }
12626        }
12627        if (dumpPackage == null) {
12628            if (mSleeping || mWentToSleep || mLockScreenShown) {
12629                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12630                        + " mLockScreenShown " + mLockScreenShown);
12631            }
12632            if (mShuttingDown || mRunningVoice) {
12633                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12634            }
12635        }
12636        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12637                || mOrigWaitForDebugger) {
12638            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12639                    || dumpPackage.equals(mOrigDebugApp)) {
12640                if (needSep) {
12641                    pw.println();
12642                    needSep = false;
12643                }
12644                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12645                        + " mDebugTransient=" + mDebugTransient
12646                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12647            }
12648        }
12649        if (mOpenGlTraceApp != null) {
12650            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12651                if (needSep) {
12652                    pw.println();
12653                    needSep = false;
12654                }
12655                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12656            }
12657        }
12658        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12659                || mProfileFd != null) {
12660            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12661                if (needSep) {
12662                    pw.println();
12663                    needSep = false;
12664                }
12665                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12666                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12667                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12668                        + mAutoStopProfiler);
12669                pw.println("  mProfileType=" + mProfileType);
12670            }
12671        }
12672        if (dumpPackage == null) {
12673            if (mAlwaysFinishActivities || mController != null) {
12674                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12675                        + " mController=" + mController);
12676            }
12677            if (dumpAll) {
12678                pw.println("  Total persistent processes: " + numPers);
12679                pw.println("  mProcessesReady=" + mProcessesReady
12680                        + " mSystemReady=" + mSystemReady);
12681                pw.println("  mBooting=" + mBooting
12682                        + " mBooted=" + mBooted
12683                        + " mFactoryTest=" + mFactoryTest);
12684                pw.print("  mLastPowerCheckRealtime=");
12685                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12686                        pw.println("");
12687                pw.print("  mLastPowerCheckUptime=");
12688                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12689                        pw.println("");
12690                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12691                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12692                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12693                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12694                        + " (" + mLruProcesses.size() + " total)"
12695                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12696                        + " mNumServiceProcs=" + mNumServiceProcs
12697                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12698                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12699                        + " mLastMemoryLevel" + mLastMemoryLevel
12700                        + " mLastNumProcesses" + mLastNumProcesses);
12701                long now = SystemClock.uptimeMillis();
12702                pw.print("  mLastIdleTime=");
12703                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12704                        pw.print(" mLowRamSinceLastIdle=");
12705                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12706                        pw.println();
12707            }
12708        }
12709
12710        if (!printedAnything) {
12711            pw.println("  (nothing)");
12712        }
12713    }
12714
12715    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12716            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12717        if (mProcessesToGc.size() > 0) {
12718            boolean printed = false;
12719            long now = SystemClock.uptimeMillis();
12720            for (int i=0; i<mProcessesToGc.size(); i++) {
12721                ProcessRecord proc = mProcessesToGc.get(i);
12722                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12723                    continue;
12724                }
12725                if (!printed) {
12726                    if (needSep) pw.println();
12727                    needSep = true;
12728                    pw.println("  Processes that are waiting to GC:");
12729                    printed = true;
12730                }
12731                pw.print("    Process "); pw.println(proc);
12732                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12733                        pw.print(", last gced=");
12734                        pw.print(now-proc.lastRequestedGc);
12735                        pw.print(" ms ago, last lowMem=");
12736                        pw.print(now-proc.lastLowMemory);
12737                        pw.println(" ms ago");
12738
12739            }
12740        }
12741        return needSep;
12742    }
12743
12744    void printOomLevel(PrintWriter pw, String name, int adj) {
12745        pw.print("    ");
12746        if (adj >= 0) {
12747            pw.print(' ');
12748            if (adj < 10) pw.print(' ');
12749        } else {
12750            if (adj > -10) pw.print(' ');
12751        }
12752        pw.print(adj);
12753        pw.print(": ");
12754        pw.print(name);
12755        pw.print(" (");
12756        pw.print(mProcessList.getMemLevel(adj)/1024);
12757        pw.println(" kB)");
12758    }
12759
12760    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12761            int opti, boolean dumpAll) {
12762        boolean needSep = false;
12763
12764        if (mLruProcesses.size() > 0) {
12765            if (needSep) pw.println();
12766            needSep = true;
12767            pw.println("  OOM levels:");
12768            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12769            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12770            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12771            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12772            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12773            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12774            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12775            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12776            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12777            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12778            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12779            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12780            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12781
12782            if (needSep) pw.println();
12783            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12784                    pw.print(" total, non-act at ");
12785                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12786                    pw.print(", non-svc at ");
12787                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12788                    pw.println("):");
12789            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12790            needSep = true;
12791        }
12792
12793        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12794
12795        pw.println();
12796        pw.println("  mHomeProcess: " + mHomeProcess);
12797        pw.println("  mPreviousProcess: " + mPreviousProcess);
12798        if (mHeavyWeightProcess != null) {
12799            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12800        }
12801
12802        return true;
12803    }
12804
12805    /**
12806     * There are three ways to call this:
12807     *  - no provider specified: dump all the providers
12808     *  - a flattened component name that matched an existing provider was specified as the
12809     *    first arg: dump that one provider
12810     *  - the first arg isn't the flattened component name of an existing provider:
12811     *    dump all providers whose component contains the first arg as a substring
12812     */
12813    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12814            int opti, boolean dumpAll) {
12815        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12816    }
12817
12818    static class ItemMatcher {
12819        ArrayList<ComponentName> components;
12820        ArrayList<String> strings;
12821        ArrayList<Integer> objects;
12822        boolean all;
12823
12824        ItemMatcher() {
12825            all = true;
12826        }
12827
12828        void build(String name) {
12829            ComponentName componentName = ComponentName.unflattenFromString(name);
12830            if (componentName != null) {
12831                if (components == null) {
12832                    components = new ArrayList<ComponentName>();
12833                }
12834                components.add(componentName);
12835                all = false;
12836            } else {
12837                int objectId = 0;
12838                // Not a '/' separated full component name; maybe an object ID?
12839                try {
12840                    objectId = Integer.parseInt(name, 16);
12841                    if (objects == null) {
12842                        objects = new ArrayList<Integer>();
12843                    }
12844                    objects.add(objectId);
12845                    all = false;
12846                } catch (RuntimeException e) {
12847                    // Not an integer; just do string match.
12848                    if (strings == null) {
12849                        strings = new ArrayList<String>();
12850                    }
12851                    strings.add(name);
12852                    all = false;
12853                }
12854            }
12855        }
12856
12857        int build(String[] args, int opti) {
12858            for (; opti<args.length; opti++) {
12859                String name = args[opti];
12860                if ("--".equals(name)) {
12861                    return opti+1;
12862                }
12863                build(name);
12864            }
12865            return opti;
12866        }
12867
12868        boolean match(Object object, ComponentName comp) {
12869            if (all) {
12870                return true;
12871            }
12872            if (components != null) {
12873                for (int i=0; i<components.size(); i++) {
12874                    if (components.get(i).equals(comp)) {
12875                        return true;
12876                    }
12877                }
12878            }
12879            if (objects != null) {
12880                for (int i=0; i<objects.size(); i++) {
12881                    if (System.identityHashCode(object) == objects.get(i)) {
12882                        return true;
12883                    }
12884                }
12885            }
12886            if (strings != null) {
12887                String flat = comp.flattenToString();
12888                for (int i=0; i<strings.size(); i++) {
12889                    if (flat.contains(strings.get(i))) {
12890                        return true;
12891                    }
12892                }
12893            }
12894            return false;
12895        }
12896    }
12897
12898    /**
12899     * There are three things that cmd can be:
12900     *  - a flattened component name that matches an existing activity
12901     *  - the cmd arg isn't the flattened component name of an existing activity:
12902     *    dump all activity whose component contains the cmd as a substring
12903     *  - A hex number of the ActivityRecord object instance.
12904     */
12905    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12906            int opti, boolean dumpAll) {
12907        ArrayList<ActivityRecord> activities;
12908
12909        synchronized (this) {
12910            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12911        }
12912
12913        if (activities.size() <= 0) {
12914            return false;
12915        }
12916
12917        String[] newArgs = new String[args.length - opti];
12918        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12919
12920        TaskRecord lastTask = null;
12921        boolean needSep = false;
12922        for (int i=activities.size()-1; i>=0; i--) {
12923            ActivityRecord r = activities.get(i);
12924            if (needSep) {
12925                pw.println();
12926            }
12927            needSep = true;
12928            synchronized (this) {
12929                if (lastTask != r.task) {
12930                    lastTask = r.task;
12931                    pw.print("TASK "); pw.print(lastTask.affinity);
12932                            pw.print(" id="); pw.println(lastTask.taskId);
12933                    if (dumpAll) {
12934                        lastTask.dump(pw, "  ");
12935                    }
12936                }
12937            }
12938            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12939        }
12940        return true;
12941    }
12942
12943    /**
12944     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12945     * there is a thread associated with the activity.
12946     */
12947    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12948            final ActivityRecord r, String[] args, boolean dumpAll) {
12949        String innerPrefix = prefix + "  ";
12950        synchronized (this) {
12951            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12952                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12953                    pw.print(" pid=");
12954                    if (r.app != null) pw.println(r.app.pid);
12955                    else pw.println("(not running)");
12956            if (dumpAll) {
12957                r.dump(pw, innerPrefix);
12958            }
12959        }
12960        if (r.app != null && r.app.thread != null) {
12961            // flush anything that is already in the PrintWriter since the thread is going
12962            // to write to the file descriptor directly
12963            pw.flush();
12964            try {
12965                TransferPipe tp = new TransferPipe();
12966                try {
12967                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12968                            r.appToken, innerPrefix, args);
12969                    tp.go(fd);
12970                } finally {
12971                    tp.kill();
12972                }
12973            } catch (IOException e) {
12974                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12975            } catch (RemoteException e) {
12976                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12977            }
12978        }
12979    }
12980
12981    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12982            int opti, boolean dumpAll, String dumpPackage) {
12983        boolean needSep = false;
12984        boolean onlyHistory = false;
12985        boolean printedAnything = false;
12986
12987        if ("history".equals(dumpPackage)) {
12988            if (opti < args.length && "-s".equals(args[opti])) {
12989                dumpAll = false;
12990            }
12991            onlyHistory = true;
12992            dumpPackage = null;
12993        }
12994
12995        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12996        if (!onlyHistory && dumpAll) {
12997            if (mRegisteredReceivers.size() > 0) {
12998                boolean printed = false;
12999                Iterator it = mRegisteredReceivers.values().iterator();
13000                while (it.hasNext()) {
13001                    ReceiverList r = (ReceiverList)it.next();
13002                    if (dumpPackage != null && (r.app == null ||
13003                            !dumpPackage.equals(r.app.info.packageName))) {
13004                        continue;
13005                    }
13006                    if (!printed) {
13007                        pw.println("  Registered Receivers:");
13008                        needSep = true;
13009                        printed = true;
13010                        printedAnything = true;
13011                    }
13012                    pw.print("  * "); pw.println(r);
13013                    r.dump(pw, "    ");
13014                }
13015            }
13016
13017            if (mReceiverResolver.dump(pw, needSep ?
13018                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13019                    "    ", dumpPackage, false)) {
13020                needSep = true;
13021                printedAnything = true;
13022            }
13023        }
13024
13025        for (BroadcastQueue q : mBroadcastQueues) {
13026            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13027            printedAnything |= needSep;
13028        }
13029
13030        needSep = true;
13031
13032        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13033            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13034                if (needSep) {
13035                    pw.println();
13036                }
13037                needSep = true;
13038                printedAnything = true;
13039                pw.print("  Sticky broadcasts for user ");
13040                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13041                StringBuilder sb = new StringBuilder(128);
13042                for (Map.Entry<String, ArrayList<Intent>> ent
13043                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13044                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13045                    if (dumpAll) {
13046                        pw.println(":");
13047                        ArrayList<Intent> intents = ent.getValue();
13048                        final int N = intents.size();
13049                        for (int i=0; i<N; i++) {
13050                            sb.setLength(0);
13051                            sb.append("    Intent: ");
13052                            intents.get(i).toShortString(sb, false, true, false, false);
13053                            pw.println(sb.toString());
13054                            Bundle bundle = intents.get(i).getExtras();
13055                            if (bundle != null) {
13056                                pw.print("      ");
13057                                pw.println(bundle.toString());
13058                            }
13059                        }
13060                    } else {
13061                        pw.println("");
13062                    }
13063                }
13064            }
13065        }
13066
13067        if (!onlyHistory && dumpAll) {
13068            pw.println();
13069            for (BroadcastQueue queue : mBroadcastQueues) {
13070                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13071                        + queue.mBroadcastsScheduled);
13072            }
13073            pw.println("  mHandler:");
13074            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13075            needSep = true;
13076            printedAnything = true;
13077        }
13078
13079        if (!printedAnything) {
13080            pw.println("  (nothing)");
13081        }
13082    }
13083
13084    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13085            int opti, boolean dumpAll, String dumpPackage) {
13086        boolean needSep;
13087        boolean printedAnything = false;
13088
13089        ItemMatcher matcher = new ItemMatcher();
13090        matcher.build(args, opti);
13091
13092        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13093
13094        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13095        printedAnything |= needSep;
13096
13097        if (mLaunchingProviders.size() > 0) {
13098            boolean printed = false;
13099            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13100                ContentProviderRecord r = mLaunchingProviders.get(i);
13101                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13102                    continue;
13103                }
13104                if (!printed) {
13105                    if (needSep) pw.println();
13106                    needSep = true;
13107                    pw.println("  Launching content providers:");
13108                    printed = true;
13109                    printedAnything = true;
13110                }
13111                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13112                        pw.println(r);
13113            }
13114        }
13115
13116        if (mGrantedUriPermissions.size() > 0) {
13117            boolean printed = false;
13118            int dumpUid = -2;
13119            if (dumpPackage != null) {
13120                try {
13121                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13122                } catch (NameNotFoundException e) {
13123                    dumpUid = -1;
13124                }
13125            }
13126            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13127                int uid = mGrantedUriPermissions.keyAt(i);
13128                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13129                    continue;
13130                }
13131                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13132                if (!printed) {
13133                    if (needSep) pw.println();
13134                    needSep = true;
13135                    pw.println("  Granted Uri Permissions:");
13136                    printed = true;
13137                    printedAnything = true;
13138                }
13139                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13140                for (UriPermission perm : perms.values()) {
13141                    pw.print("    "); pw.println(perm);
13142                    if (dumpAll) {
13143                        perm.dump(pw, "      ");
13144                    }
13145                }
13146            }
13147        }
13148
13149        if (!printedAnything) {
13150            pw.println("  (nothing)");
13151        }
13152    }
13153
13154    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13155            int opti, boolean dumpAll, String dumpPackage) {
13156        boolean printed = false;
13157
13158        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13159
13160        if (mIntentSenderRecords.size() > 0) {
13161            Iterator<WeakReference<PendingIntentRecord>> it
13162                    = mIntentSenderRecords.values().iterator();
13163            while (it.hasNext()) {
13164                WeakReference<PendingIntentRecord> ref = it.next();
13165                PendingIntentRecord rec = ref != null ? ref.get(): null;
13166                if (dumpPackage != null && (rec == null
13167                        || !dumpPackage.equals(rec.key.packageName))) {
13168                    continue;
13169                }
13170                printed = true;
13171                if (rec != null) {
13172                    pw.print("  * "); pw.println(rec);
13173                    if (dumpAll) {
13174                        rec.dump(pw, "    ");
13175                    }
13176                } else {
13177                    pw.print("  * "); pw.println(ref);
13178                }
13179            }
13180        }
13181
13182        if (!printed) {
13183            pw.println("  (nothing)");
13184        }
13185    }
13186
13187    private static final int dumpProcessList(PrintWriter pw,
13188            ActivityManagerService service, List list,
13189            String prefix, String normalLabel, String persistentLabel,
13190            String dumpPackage) {
13191        int numPers = 0;
13192        final int N = list.size()-1;
13193        for (int i=N; i>=0; i--) {
13194            ProcessRecord r = (ProcessRecord)list.get(i);
13195            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13196                continue;
13197            }
13198            pw.println(String.format("%s%s #%2d: %s",
13199                    prefix, (r.persistent ? persistentLabel : normalLabel),
13200                    i, r.toString()));
13201            if (r.persistent) {
13202                numPers++;
13203            }
13204        }
13205        return numPers;
13206    }
13207
13208    private static final boolean dumpProcessOomList(PrintWriter pw,
13209            ActivityManagerService service, List<ProcessRecord> origList,
13210            String prefix, String normalLabel, String persistentLabel,
13211            boolean inclDetails, String dumpPackage) {
13212
13213        ArrayList<Pair<ProcessRecord, Integer>> list
13214                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13215        for (int i=0; i<origList.size(); i++) {
13216            ProcessRecord r = origList.get(i);
13217            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13218                continue;
13219            }
13220            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13221        }
13222
13223        if (list.size() <= 0) {
13224            return false;
13225        }
13226
13227        Comparator<Pair<ProcessRecord, Integer>> comparator
13228                = new Comparator<Pair<ProcessRecord, Integer>>() {
13229            @Override
13230            public int compare(Pair<ProcessRecord, Integer> object1,
13231                    Pair<ProcessRecord, Integer> object2) {
13232                if (object1.first.setAdj != object2.first.setAdj) {
13233                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13234                }
13235                if (object1.second.intValue() != object2.second.intValue()) {
13236                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13237                }
13238                return 0;
13239            }
13240        };
13241
13242        Collections.sort(list, comparator);
13243
13244        final long curRealtime = SystemClock.elapsedRealtime();
13245        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13246        final long curUptime = SystemClock.uptimeMillis();
13247        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13248
13249        for (int i=list.size()-1; i>=0; i--) {
13250            ProcessRecord r = list.get(i).first;
13251            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13252            char schedGroup;
13253            switch (r.setSchedGroup) {
13254                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13255                    schedGroup = 'B';
13256                    break;
13257                case Process.THREAD_GROUP_DEFAULT:
13258                    schedGroup = 'F';
13259                    break;
13260                default:
13261                    schedGroup = '?';
13262                    break;
13263            }
13264            char foreground;
13265            if (r.foregroundActivities) {
13266                foreground = 'A';
13267            } else if (r.foregroundServices) {
13268                foreground = 'S';
13269            } else {
13270                foreground = ' ';
13271            }
13272            String procState = ProcessList.makeProcStateString(r.curProcState);
13273            pw.print(prefix);
13274            pw.print(r.persistent ? persistentLabel : normalLabel);
13275            pw.print(" #");
13276            int num = (origList.size()-1)-list.get(i).second;
13277            if (num < 10) pw.print(' ');
13278            pw.print(num);
13279            pw.print(": ");
13280            pw.print(oomAdj);
13281            pw.print(' ');
13282            pw.print(schedGroup);
13283            pw.print('/');
13284            pw.print(foreground);
13285            pw.print('/');
13286            pw.print(procState);
13287            pw.print(" trm:");
13288            if (r.trimMemoryLevel < 10) pw.print(' ');
13289            pw.print(r.trimMemoryLevel);
13290            pw.print(' ');
13291            pw.print(r.toShortString());
13292            pw.print(" (");
13293            pw.print(r.adjType);
13294            pw.println(')');
13295            if (r.adjSource != null || r.adjTarget != null) {
13296                pw.print(prefix);
13297                pw.print("    ");
13298                if (r.adjTarget instanceof ComponentName) {
13299                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13300                } else if (r.adjTarget != null) {
13301                    pw.print(r.adjTarget.toString());
13302                } else {
13303                    pw.print("{null}");
13304                }
13305                pw.print("<=");
13306                if (r.adjSource instanceof ProcessRecord) {
13307                    pw.print("Proc{");
13308                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13309                    pw.println("}");
13310                } else if (r.adjSource != null) {
13311                    pw.println(r.adjSource.toString());
13312                } else {
13313                    pw.println("{null}");
13314                }
13315            }
13316            if (inclDetails) {
13317                pw.print(prefix);
13318                pw.print("    ");
13319                pw.print("oom: max="); pw.print(r.maxAdj);
13320                pw.print(" curRaw="); pw.print(r.curRawAdj);
13321                pw.print(" setRaw="); pw.print(r.setRawAdj);
13322                pw.print(" cur="); pw.print(r.curAdj);
13323                pw.print(" set="); pw.println(r.setAdj);
13324                pw.print(prefix);
13325                pw.print("    ");
13326                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13327                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13328                pw.print(" lastPss="); pw.print(r.lastPss);
13329                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13330                pw.print(prefix);
13331                pw.print("    ");
13332                pw.print("cached="); pw.print(r.cached);
13333                pw.print(" empty="); pw.print(r.empty);
13334                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13335
13336                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13337                    if (r.lastWakeTime != 0) {
13338                        long wtime;
13339                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13340                        synchronized (stats) {
13341                            wtime = stats.getProcessWakeTime(r.info.uid,
13342                                    r.pid, curRealtime);
13343                        }
13344                        long timeUsed = wtime - r.lastWakeTime;
13345                        pw.print(prefix);
13346                        pw.print("    ");
13347                        pw.print("keep awake over ");
13348                        TimeUtils.formatDuration(realtimeSince, pw);
13349                        pw.print(" used ");
13350                        TimeUtils.formatDuration(timeUsed, pw);
13351                        pw.print(" (");
13352                        pw.print((timeUsed*100)/realtimeSince);
13353                        pw.println("%)");
13354                    }
13355                    if (r.lastCpuTime != 0) {
13356                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13357                        pw.print(prefix);
13358                        pw.print("    ");
13359                        pw.print("run cpu over ");
13360                        TimeUtils.formatDuration(uptimeSince, pw);
13361                        pw.print(" used ");
13362                        TimeUtils.formatDuration(timeUsed, pw);
13363                        pw.print(" (");
13364                        pw.print((timeUsed*100)/uptimeSince);
13365                        pw.println("%)");
13366                    }
13367                }
13368            }
13369        }
13370        return true;
13371    }
13372
13373    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13374        ArrayList<ProcessRecord> procs;
13375        synchronized (this) {
13376            if (args != null && args.length > start
13377                    && args[start].charAt(0) != '-') {
13378                procs = new ArrayList<ProcessRecord>();
13379                int pid = -1;
13380                try {
13381                    pid = Integer.parseInt(args[start]);
13382                } catch (NumberFormatException e) {
13383                }
13384                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13385                    ProcessRecord proc = mLruProcesses.get(i);
13386                    if (proc.pid == pid) {
13387                        procs.add(proc);
13388                    } else if (proc.processName.equals(args[start])) {
13389                        procs.add(proc);
13390                    }
13391                }
13392                if (procs.size() <= 0) {
13393                    return null;
13394                }
13395            } else {
13396                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13397            }
13398        }
13399        return procs;
13400    }
13401
13402    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13403            PrintWriter pw, String[] args) {
13404        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13405        if (procs == null) {
13406            pw.println("No process found for: " + args[0]);
13407            return;
13408        }
13409
13410        long uptime = SystemClock.uptimeMillis();
13411        long realtime = SystemClock.elapsedRealtime();
13412        pw.println("Applications Graphics Acceleration Info:");
13413        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13414
13415        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13416            ProcessRecord r = procs.get(i);
13417            if (r.thread != null) {
13418                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13419                pw.flush();
13420                try {
13421                    TransferPipe tp = new TransferPipe();
13422                    try {
13423                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13424                        tp.go(fd);
13425                    } finally {
13426                        tp.kill();
13427                    }
13428                } catch (IOException e) {
13429                    pw.println("Failure while dumping the app: " + r);
13430                    pw.flush();
13431                } catch (RemoteException e) {
13432                    pw.println("Got a RemoteException while dumping the app " + r);
13433                    pw.flush();
13434                }
13435            }
13436        }
13437    }
13438
13439    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13440        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13441        if (procs == null) {
13442            pw.println("No process found for: " + args[0]);
13443            return;
13444        }
13445
13446        pw.println("Applications Database Info:");
13447
13448        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13449            ProcessRecord r = procs.get(i);
13450            if (r.thread != null) {
13451                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13452                pw.flush();
13453                try {
13454                    TransferPipe tp = new TransferPipe();
13455                    try {
13456                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13457                        tp.go(fd);
13458                    } finally {
13459                        tp.kill();
13460                    }
13461                } catch (IOException e) {
13462                    pw.println("Failure while dumping the app: " + r);
13463                    pw.flush();
13464                } catch (RemoteException e) {
13465                    pw.println("Got a RemoteException while dumping the app " + r);
13466                    pw.flush();
13467                }
13468            }
13469        }
13470    }
13471
13472    final static class MemItem {
13473        final boolean isProc;
13474        final String label;
13475        final String shortLabel;
13476        final long pss;
13477        final int id;
13478        final boolean hasActivities;
13479        ArrayList<MemItem> subitems;
13480
13481        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13482                boolean _hasActivities) {
13483            isProc = true;
13484            label = _label;
13485            shortLabel = _shortLabel;
13486            pss = _pss;
13487            id = _id;
13488            hasActivities = _hasActivities;
13489        }
13490
13491        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13492            isProc = false;
13493            label = _label;
13494            shortLabel = _shortLabel;
13495            pss = _pss;
13496            id = _id;
13497            hasActivities = false;
13498        }
13499    }
13500
13501    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13502            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13503        if (sort && !isCompact) {
13504            Collections.sort(items, new Comparator<MemItem>() {
13505                @Override
13506                public int compare(MemItem lhs, MemItem rhs) {
13507                    if (lhs.pss < rhs.pss) {
13508                        return 1;
13509                    } else if (lhs.pss > rhs.pss) {
13510                        return -1;
13511                    }
13512                    return 0;
13513                }
13514            });
13515        }
13516
13517        for (int i=0; i<items.size(); i++) {
13518            MemItem mi = items.get(i);
13519            if (!isCompact) {
13520                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13521            } else if (mi.isProc) {
13522                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13523                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13524                pw.println(mi.hasActivities ? ",a" : ",e");
13525            } else {
13526                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13527                pw.println(mi.pss);
13528            }
13529            if (mi.subitems != null) {
13530                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13531                        true, isCompact);
13532            }
13533        }
13534    }
13535
13536    // These are in KB.
13537    static final long[] DUMP_MEM_BUCKETS = new long[] {
13538        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13539        120*1024, 160*1024, 200*1024,
13540        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13541        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13542    };
13543
13544    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13545            boolean stackLike) {
13546        int start = label.lastIndexOf('.');
13547        if (start >= 0) start++;
13548        else start = 0;
13549        int end = label.length();
13550        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13551            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13552                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13553                out.append(bucket);
13554                out.append(stackLike ? "MB." : "MB ");
13555                out.append(label, start, end);
13556                return;
13557            }
13558        }
13559        out.append(memKB/1024);
13560        out.append(stackLike ? "MB." : "MB ");
13561        out.append(label, start, end);
13562    }
13563
13564    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13565            ProcessList.NATIVE_ADJ,
13566            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13567            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13568            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13569            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13570            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13571    };
13572    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13573            "Native",
13574            "System", "Persistent", "Foreground",
13575            "Visible", "Perceptible",
13576            "Heavy Weight", "Backup",
13577            "A Services", "Home",
13578            "Previous", "B Services", "Cached"
13579    };
13580    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13581            "native",
13582            "sys", "pers", "fore",
13583            "vis", "percept",
13584            "heavy", "backup",
13585            "servicea", "home",
13586            "prev", "serviceb", "cached"
13587    };
13588
13589    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13590            long realtime, boolean isCheckinRequest, boolean isCompact) {
13591        if (isCheckinRequest || isCompact) {
13592            // short checkin version
13593            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13594        } else {
13595            pw.println("Applications Memory Usage (kB):");
13596            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13597        }
13598    }
13599
13600    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13601            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13602        boolean dumpDetails = false;
13603        boolean dumpFullDetails = false;
13604        boolean dumpDalvik = false;
13605        boolean oomOnly = false;
13606        boolean isCompact = false;
13607        boolean localOnly = false;
13608
13609        int opti = 0;
13610        while (opti < args.length) {
13611            String opt = args[opti];
13612            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13613                break;
13614            }
13615            opti++;
13616            if ("-a".equals(opt)) {
13617                dumpDetails = true;
13618                dumpFullDetails = true;
13619                dumpDalvik = true;
13620            } else if ("-d".equals(opt)) {
13621                dumpDalvik = true;
13622            } else if ("-c".equals(opt)) {
13623                isCompact = true;
13624            } else if ("--oom".equals(opt)) {
13625                oomOnly = true;
13626            } else if ("--local".equals(opt)) {
13627                localOnly = true;
13628            } else if ("-h".equals(opt)) {
13629                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13630                pw.println("  -a: include all available information for each process.");
13631                pw.println("  -d: include dalvik details when dumping process details.");
13632                pw.println("  -c: dump in a compact machine-parseable representation.");
13633                pw.println("  --oom: only show processes organized by oom adj.");
13634                pw.println("  --local: only collect details locally, don't call process.");
13635                pw.println("If [process] is specified it can be the name or ");
13636                pw.println("pid of a specific process to dump.");
13637                return;
13638            } else {
13639                pw.println("Unknown argument: " + opt + "; use -h for help");
13640            }
13641        }
13642
13643        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13644        long uptime = SystemClock.uptimeMillis();
13645        long realtime = SystemClock.elapsedRealtime();
13646        final long[] tmpLong = new long[1];
13647
13648        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13649        if (procs == null) {
13650            // No Java processes.  Maybe they want to print a native process.
13651            if (args != null && args.length > opti
13652                    && args[opti].charAt(0) != '-') {
13653                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13654                        = new ArrayList<ProcessCpuTracker.Stats>();
13655                updateCpuStatsNow();
13656                int findPid = -1;
13657                try {
13658                    findPid = Integer.parseInt(args[opti]);
13659                } catch (NumberFormatException e) {
13660                }
13661                synchronized (mProcessCpuThread) {
13662                    final int N = mProcessCpuTracker.countStats();
13663                    for (int i=0; i<N; i++) {
13664                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13665                        if (st.pid == findPid || (st.baseName != null
13666                                && st.baseName.equals(args[opti]))) {
13667                            nativeProcs.add(st);
13668                        }
13669                    }
13670                }
13671                if (nativeProcs.size() > 0) {
13672                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13673                            isCompact);
13674                    Debug.MemoryInfo mi = null;
13675                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13676                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13677                        final int pid = r.pid;
13678                        if (!isCheckinRequest && dumpDetails) {
13679                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13680                        }
13681                        if (mi == null) {
13682                            mi = new Debug.MemoryInfo();
13683                        }
13684                        if (dumpDetails || (!brief && !oomOnly)) {
13685                            Debug.getMemoryInfo(pid, mi);
13686                        } else {
13687                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13688                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13689                        }
13690                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13691                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13692                        if (isCheckinRequest) {
13693                            pw.println();
13694                        }
13695                    }
13696                    return;
13697                }
13698            }
13699            pw.println("No process found for: " + args[opti]);
13700            return;
13701        }
13702
13703        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13704            dumpDetails = true;
13705        }
13706
13707        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13708
13709        String[] innerArgs = new String[args.length-opti];
13710        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13711
13712        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13713        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13714        long nativePss=0, dalvikPss=0, otherPss=0;
13715        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13716
13717        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13718        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13719                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13720
13721        long totalPss = 0;
13722        long cachedPss = 0;
13723
13724        Debug.MemoryInfo mi = null;
13725        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13726            final ProcessRecord r = procs.get(i);
13727            final IApplicationThread thread;
13728            final int pid;
13729            final int oomAdj;
13730            final boolean hasActivities;
13731            synchronized (this) {
13732                thread = r.thread;
13733                pid = r.pid;
13734                oomAdj = r.getSetAdjWithServices();
13735                hasActivities = r.activities.size() > 0;
13736            }
13737            if (thread != null) {
13738                if (!isCheckinRequest && dumpDetails) {
13739                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13740                }
13741                if (mi == null) {
13742                    mi = new Debug.MemoryInfo();
13743                }
13744                if (dumpDetails || (!brief && !oomOnly)) {
13745                    Debug.getMemoryInfo(pid, mi);
13746                } else {
13747                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13748                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13749                }
13750                if (dumpDetails) {
13751                    if (localOnly) {
13752                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13753                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13754                        if (isCheckinRequest) {
13755                            pw.println();
13756                        }
13757                    } else {
13758                        try {
13759                            pw.flush();
13760                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13761                                    dumpDalvik, innerArgs);
13762                        } catch (RemoteException e) {
13763                            if (!isCheckinRequest) {
13764                                pw.println("Got RemoteException!");
13765                                pw.flush();
13766                            }
13767                        }
13768                    }
13769                }
13770
13771                final long myTotalPss = mi.getTotalPss();
13772                final long myTotalUss = mi.getTotalUss();
13773
13774                synchronized (this) {
13775                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13776                        // Record this for posterity if the process has been stable.
13777                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13778                    }
13779                }
13780
13781                if (!isCheckinRequest && mi != null) {
13782                    totalPss += myTotalPss;
13783                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13784                            (hasActivities ? " / activities)" : ")"),
13785                            r.processName, myTotalPss, pid, hasActivities);
13786                    procMems.add(pssItem);
13787                    procMemsMap.put(pid, pssItem);
13788
13789                    nativePss += mi.nativePss;
13790                    dalvikPss += mi.dalvikPss;
13791                    otherPss += mi.otherPss;
13792                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13793                        long mem = mi.getOtherPss(j);
13794                        miscPss[j] += mem;
13795                        otherPss -= mem;
13796                    }
13797
13798                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13799                        cachedPss += myTotalPss;
13800                    }
13801
13802                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13803                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13804                                || oomIndex == (oomPss.length-1)) {
13805                            oomPss[oomIndex] += myTotalPss;
13806                            if (oomProcs[oomIndex] == null) {
13807                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13808                            }
13809                            oomProcs[oomIndex].add(pssItem);
13810                            break;
13811                        }
13812                    }
13813                }
13814            }
13815        }
13816
13817        long nativeProcTotalPss = 0;
13818
13819        if (!isCheckinRequest && procs.size() > 1) {
13820            // If we are showing aggregations, also look for native processes to
13821            // include so that our aggregations are more accurate.
13822            updateCpuStatsNow();
13823            synchronized (mProcessCpuThread) {
13824                final int N = mProcessCpuTracker.countStats();
13825                for (int i=0; i<N; i++) {
13826                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13827                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13828                        if (mi == null) {
13829                            mi = new Debug.MemoryInfo();
13830                        }
13831                        if (!brief && !oomOnly) {
13832                            Debug.getMemoryInfo(st.pid, mi);
13833                        } else {
13834                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13835                            mi.nativePrivateDirty = (int)tmpLong[0];
13836                        }
13837
13838                        final long myTotalPss = mi.getTotalPss();
13839                        totalPss += myTotalPss;
13840                        nativeProcTotalPss += myTotalPss;
13841
13842                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13843                                st.name, myTotalPss, st.pid, false);
13844                        procMems.add(pssItem);
13845
13846                        nativePss += mi.nativePss;
13847                        dalvikPss += mi.dalvikPss;
13848                        otherPss += mi.otherPss;
13849                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13850                            long mem = mi.getOtherPss(j);
13851                            miscPss[j] += mem;
13852                            otherPss -= mem;
13853                        }
13854                        oomPss[0] += myTotalPss;
13855                        if (oomProcs[0] == null) {
13856                            oomProcs[0] = new ArrayList<MemItem>();
13857                        }
13858                        oomProcs[0].add(pssItem);
13859                    }
13860                }
13861            }
13862
13863            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13864
13865            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13866            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13867            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13868            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13869                String label = Debug.MemoryInfo.getOtherLabel(j);
13870                catMems.add(new MemItem(label, label, miscPss[j], j));
13871            }
13872
13873            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13874            for (int j=0; j<oomPss.length; j++) {
13875                if (oomPss[j] != 0) {
13876                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13877                            : DUMP_MEM_OOM_LABEL[j];
13878                    MemItem item = new MemItem(label, label, oomPss[j],
13879                            DUMP_MEM_OOM_ADJ[j]);
13880                    item.subitems = oomProcs[j];
13881                    oomMems.add(item);
13882                }
13883            }
13884
13885            if (!brief && !oomOnly && !isCompact) {
13886                pw.println();
13887                pw.println("Total PSS by process:");
13888                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13889                pw.println();
13890            }
13891            if (!isCompact) {
13892                pw.println("Total PSS by OOM adjustment:");
13893            }
13894            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13895            if (!brief && !oomOnly) {
13896                PrintWriter out = categoryPw != null ? categoryPw : pw;
13897                if (!isCompact) {
13898                    out.println();
13899                    out.println("Total PSS by category:");
13900                }
13901                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13902            }
13903            if (!isCompact) {
13904                pw.println();
13905            }
13906            MemInfoReader memInfo = new MemInfoReader();
13907            memInfo.readMemInfo();
13908            if (nativeProcTotalPss > 0) {
13909                synchronized (this) {
13910                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13911                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13912                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13913                            nativeProcTotalPss);
13914                }
13915            }
13916            if (!brief) {
13917                if (!isCompact) {
13918                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13919                    pw.print(" kB (status ");
13920                    switch (mLastMemoryLevel) {
13921                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13922                            pw.println("normal)");
13923                            break;
13924                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13925                            pw.println("moderate)");
13926                            break;
13927                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13928                            pw.println("low)");
13929                            break;
13930                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13931                            pw.println("critical)");
13932                            break;
13933                        default:
13934                            pw.print(mLastMemoryLevel);
13935                            pw.println(")");
13936                            break;
13937                    }
13938                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13939                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13940                            pw.print(cachedPss); pw.print(" cached pss + ");
13941                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13942                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13943                } else {
13944                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13945                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13946                            + memInfo.getFreeSizeKb()); pw.print(",");
13947                    pw.println(totalPss - cachedPss);
13948                }
13949            }
13950            if (!isCompact) {
13951                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13952                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13953                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13954                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13955                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13956                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13957                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13958                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13959                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13960                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13961                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13962            }
13963            if (!brief) {
13964                if (memInfo.getZramTotalSizeKb() != 0) {
13965                    if (!isCompact) {
13966                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13967                                pw.print(" kB physical used for ");
13968                                pw.print(memInfo.getSwapTotalSizeKb()
13969                                        - memInfo.getSwapFreeSizeKb());
13970                                pw.print(" kB in swap (");
13971                                pw.print(memInfo.getSwapTotalSizeKb());
13972                                pw.println(" kB total swap)");
13973                    } else {
13974                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13975                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13976                                pw.println(memInfo.getSwapFreeSizeKb());
13977                    }
13978                }
13979                final int[] SINGLE_LONG_FORMAT = new int[] {
13980                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13981                };
13982                long[] longOut = new long[1];
13983                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13984                        SINGLE_LONG_FORMAT, null, longOut, null);
13985                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13986                longOut[0] = 0;
13987                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13988                        SINGLE_LONG_FORMAT, null, longOut, null);
13989                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13990                longOut[0] = 0;
13991                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13992                        SINGLE_LONG_FORMAT, null, longOut, null);
13993                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13994                longOut[0] = 0;
13995                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13996                        SINGLE_LONG_FORMAT, null, longOut, null);
13997                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13998                if (!isCompact) {
13999                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14000                        pw.print("      KSM: "); pw.print(sharing);
14001                                pw.print(" kB saved from shared ");
14002                                pw.print(shared); pw.println(" kB");
14003                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14004                                pw.print(voltile); pw.println(" kB volatile");
14005                    }
14006                    pw.print("   Tuning: ");
14007                    pw.print(ActivityManager.staticGetMemoryClass());
14008                    pw.print(" (large ");
14009                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14010                    pw.print("), oom ");
14011                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14012                    pw.print(" kB");
14013                    pw.print(", restore limit ");
14014                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14015                    pw.print(" kB");
14016                    if (ActivityManager.isLowRamDeviceStatic()) {
14017                        pw.print(" (low-ram)");
14018                    }
14019                    if (ActivityManager.isHighEndGfx()) {
14020                        pw.print(" (high-end-gfx)");
14021                    }
14022                    pw.println();
14023                } else {
14024                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14025                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14026                    pw.println(voltile);
14027                    pw.print("tuning,");
14028                    pw.print(ActivityManager.staticGetMemoryClass());
14029                    pw.print(',');
14030                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14031                    pw.print(',');
14032                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14033                    if (ActivityManager.isLowRamDeviceStatic()) {
14034                        pw.print(",low-ram");
14035                    }
14036                    if (ActivityManager.isHighEndGfx()) {
14037                        pw.print(",high-end-gfx");
14038                    }
14039                    pw.println();
14040                }
14041            }
14042        }
14043    }
14044
14045    /**
14046     * Searches array of arguments for the specified string
14047     * @param args array of argument strings
14048     * @param value value to search for
14049     * @return true if the value is contained in the array
14050     */
14051    private static boolean scanArgs(String[] args, String value) {
14052        if (args != null) {
14053            for (String arg : args) {
14054                if (value.equals(arg)) {
14055                    return true;
14056                }
14057            }
14058        }
14059        return false;
14060    }
14061
14062    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14063            ContentProviderRecord cpr, boolean always) {
14064        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14065
14066        if (!inLaunching || always) {
14067            synchronized (cpr) {
14068                cpr.launchingApp = null;
14069                cpr.notifyAll();
14070            }
14071            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14072            String names[] = cpr.info.authority.split(";");
14073            for (int j = 0; j < names.length; j++) {
14074                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14075            }
14076        }
14077
14078        for (int i=0; i<cpr.connections.size(); i++) {
14079            ContentProviderConnection conn = cpr.connections.get(i);
14080            if (conn.waiting) {
14081                // If this connection is waiting for the provider, then we don't
14082                // need to mess with its process unless we are always removing
14083                // or for some reason the provider is not currently launching.
14084                if (inLaunching && !always) {
14085                    continue;
14086                }
14087            }
14088            ProcessRecord capp = conn.client;
14089            conn.dead = true;
14090            if (conn.stableCount > 0) {
14091                if (!capp.persistent && capp.thread != null
14092                        && capp.pid != 0
14093                        && capp.pid != MY_PID) {
14094                    capp.kill("depends on provider "
14095                            + cpr.name.flattenToShortString()
14096                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14097                }
14098            } else if (capp.thread != null && conn.provider.provider != null) {
14099                try {
14100                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14101                } catch (RemoteException e) {
14102                }
14103                // In the protocol here, we don't expect the client to correctly
14104                // clean up this connection, we'll just remove it.
14105                cpr.connections.remove(i);
14106                conn.client.conProviders.remove(conn);
14107            }
14108        }
14109
14110        if (inLaunching && always) {
14111            mLaunchingProviders.remove(cpr);
14112        }
14113        return inLaunching;
14114    }
14115
14116    /**
14117     * Main code for cleaning up a process when it has gone away.  This is
14118     * called both as a result of the process dying, or directly when stopping
14119     * a process when running in single process mode.
14120     */
14121    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14122            boolean restarting, boolean allowRestart, int index) {
14123        if (index >= 0) {
14124            removeLruProcessLocked(app);
14125            ProcessList.remove(app.pid);
14126        }
14127
14128        mProcessesToGc.remove(app);
14129        mPendingPssProcesses.remove(app);
14130
14131        // Dismiss any open dialogs.
14132        if (app.crashDialog != null && !app.forceCrashReport) {
14133            app.crashDialog.dismiss();
14134            app.crashDialog = null;
14135        }
14136        if (app.anrDialog != null) {
14137            app.anrDialog.dismiss();
14138            app.anrDialog = null;
14139        }
14140        if (app.waitDialog != null) {
14141            app.waitDialog.dismiss();
14142            app.waitDialog = null;
14143        }
14144
14145        app.crashing = false;
14146        app.notResponding = false;
14147
14148        app.resetPackageList(mProcessStats);
14149        app.unlinkDeathRecipient();
14150        app.makeInactive(mProcessStats);
14151        app.waitingToKill = null;
14152        app.forcingToForeground = null;
14153        updateProcessForegroundLocked(app, false, false);
14154        app.foregroundActivities = false;
14155        app.hasShownUi = false;
14156        app.treatLikeActivity = false;
14157        app.hasAboveClient = false;
14158        app.hasClientActivities = false;
14159
14160        mServices.killServicesLocked(app, allowRestart);
14161
14162        boolean restart = false;
14163
14164        // Remove published content providers.
14165        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14166            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14167            final boolean always = app.bad || !allowRestart;
14168            if (removeDyingProviderLocked(app, cpr, always) || always) {
14169                // We left the provider in the launching list, need to
14170                // restart it.
14171                restart = true;
14172            }
14173
14174            cpr.provider = null;
14175            cpr.proc = null;
14176        }
14177        app.pubProviders.clear();
14178
14179        // Take care of any launching providers waiting for this process.
14180        if (checkAppInLaunchingProvidersLocked(app, false)) {
14181            restart = true;
14182        }
14183
14184        // Unregister from connected content providers.
14185        if (!app.conProviders.isEmpty()) {
14186            for (int i=0; i<app.conProviders.size(); i++) {
14187                ContentProviderConnection conn = app.conProviders.get(i);
14188                conn.provider.connections.remove(conn);
14189            }
14190            app.conProviders.clear();
14191        }
14192
14193        // At this point there may be remaining entries in mLaunchingProviders
14194        // where we were the only one waiting, so they are no longer of use.
14195        // Look for these and clean up if found.
14196        // XXX Commented out for now.  Trying to figure out a way to reproduce
14197        // the actual situation to identify what is actually going on.
14198        if (false) {
14199            for (int i=0; i<mLaunchingProviders.size(); i++) {
14200                ContentProviderRecord cpr = (ContentProviderRecord)
14201                        mLaunchingProviders.get(i);
14202                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14203                    synchronized (cpr) {
14204                        cpr.launchingApp = null;
14205                        cpr.notifyAll();
14206                    }
14207                }
14208            }
14209        }
14210
14211        skipCurrentReceiverLocked(app);
14212
14213        // Unregister any receivers.
14214        for (int i=app.receivers.size()-1; i>=0; i--) {
14215            removeReceiverLocked(app.receivers.valueAt(i));
14216        }
14217        app.receivers.clear();
14218
14219        // If the app is undergoing backup, tell the backup manager about it
14220        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14221            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14222                    + mBackupTarget.appInfo + " died during backup");
14223            try {
14224                IBackupManager bm = IBackupManager.Stub.asInterface(
14225                        ServiceManager.getService(Context.BACKUP_SERVICE));
14226                bm.agentDisconnected(app.info.packageName);
14227            } catch (RemoteException e) {
14228                // can't happen; backup manager is local
14229            }
14230        }
14231
14232        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14233            ProcessChangeItem item = mPendingProcessChanges.get(i);
14234            if (item.pid == app.pid) {
14235                mPendingProcessChanges.remove(i);
14236                mAvailProcessChanges.add(item);
14237            }
14238        }
14239        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14240
14241        // If the caller is restarting this app, then leave it in its
14242        // current lists and let the caller take care of it.
14243        if (restarting) {
14244            return;
14245        }
14246
14247        if (!app.persistent || app.isolated) {
14248            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14249                    "Removing non-persistent process during cleanup: " + app);
14250            mProcessNames.remove(app.processName, app.uid);
14251            mIsolatedProcesses.remove(app.uid);
14252            if (mHeavyWeightProcess == app) {
14253                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14254                        mHeavyWeightProcess.userId, 0));
14255                mHeavyWeightProcess = null;
14256            }
14257        } else if (!app.removed) {
14258            // This app is persistent, so we need to keep its record around.
14259            // If it is not already on the pending app list, add it there
14260            // and start a new process for it.
14261            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14262                mPersistentStartingProcesses.add(app);
14263                restart = true;
14264            }
14265        }
14266        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14267                "Clean-up removing on hold: " + app);
14268        mProcessesOnHold.remove(app);
14269
14270        if (app == mHomeProcess) {
14271            mHomeProcess = null;
14272        }
14273        if (app == mPreviousProcess) {
14274            mPreviousProcess = null;
14275        }
14276
14277        if (restart && !app.isolated) {
14278            // We have components that still need to be running in the
14279            // process, so re-launch it.
14280            mProcessNames.put(app.processName, app.uid, app);
14281            startProcessLocked(app, "restart", app.processName);
14282        } else if (app.pid > 0 && app.pid != MY_PID) {
14283            // Goodbye!
14284            boolean removed;
14285            synchronized (mPidsSelfLocked) {
14286                mPidsSelfLocked.remove(app.pid);
14287                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14288            }
14289            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14290            if (app.isolated) {
14291                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14292            }
14293            app.setPid(0);
14294        }
14295    }
14296
14297    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14298        // Look through the content providers we are waiting to have launched,
14299        // and if any run in this process then either schedule a restart of
14300        // the process or kill the client waiting for it if this process has
14301        // gone bad.
14302        int NL = mLaunchingProviders.size();
14303        boolean restart = false;
14304        for (int i=0; i<NL; i++) {
14305            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14306            if (cpr.launchingApp == app) {
14307                if (!alwaysBad && !app.bad) {
14308                    restart = true;
14309                } else {
14310                    removeDyingProviderLocked(app, cpr, true);
14311                    // cpr should have been removed from mLaunchingProviders
14312                    NL = mLaunchingProviders.size();
14313                    i--;
14314                }
14315            }
14316        }
14317        return restart;
14318    }
14319
14320    // =========================================================
14321    // SERVICES
14322    // =========================================================
14323
14324    @Override
14325    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14326            int flags) {
14327        enforceNotIsolatedCaller("getServices");
14328        synchronized (this) {
14329            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14330        }
14331    }
14332
14333    @Override
14334    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14335        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14336        synchronized (this) {
14337            return mServices.getRunningServiceControlPanelLocked(name);
14338        }
14339    }
14340
14341    @Override
14342    public ComponentName startService(IApplicationThread caller, Intent service,
14343            String resolvedType, int userId) {
14344        enforceNotIsolatedCaller("startService");
14345        // Refuse possible leaked file descriptors
14346        if (service != null && service.hasFileDescriptors() == true) {
14347            throw new IllegalArgumentException("File descriptors passed in Intent");
14348        }
14349
14350        if (DEBUG_SERVICE)
14351            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14352        synchronized(this) {
14353            final int callingPid = Binder.getCallingPid();
14354            final int callingUid = Binder.getCallingUid();
14355            final long origId = Binder.clearCallingIdentity();
14356            ComponentName res = mServices.startServiceLocked(caller, service,
14357                    resolvedType, callingPid, callingUid, userId);
14358            Binder.restoreCallingIdentity(origId);
14359            return res;
14360        }
14361    }
14362
14363    ComponentName startServiceInPackage(int uid,
14364            Intent service, String resolvedType, int userId) {
14365        synchronized(this) {
14366            if (DEBUG_SERVICE)
14367                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14368            final long origId = Binder.clearCallingIdentity();
14369            ComponentName res = mServices.startServiceLocked(null, service,
14370                    resolvedType, -1, uid, userId);
14371            Binder.restoreCallingIdentity(origId);
14372            return res;
14373        }
14374    }
14375
14376    @Override
14377    public int stopService(IApplicationThread caller, Intent service,
14378            String resolvedType, int userId) {
14379        enforceNotIsolatedCaller("stopService");
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        synchronized(this) {
14386            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14387        }
14388    }
14389
14390    @Override
14391    public IBinder peekService(Intent service, String resolvedType) {
14392        enforceNotIsolatedCaller("peekService");
14393        // Refuse possible leaked file descriptors
14394        if (service != null && service.hasFileDescriptors() == true) {
14395            throw new IllegalArgumentException("File descriptors passed in Intent");
14396        }
14397        synchronized(this) {
14398            return mServices.peekServiceLocked(service, resolvedType);
14399        }
14400    }
14401
14402    @Override
14403    public boolean stopServiceToken(ComponentName className, IBinder token,
14404            int startId) {
14405        synchronized(this) {
14406            return mServices.stopServiceTokenLocked(className, token, startId);
14407        }
14408    }
14409
14410    @Override
14411    public void setServiceForeground(ComponentName className, IBinder token,
14412            int id, Notification notification, boolean removeNotification) {
14413        synchronized(this) {
14414            mServices.setServiceForegroundLocked(className, token, id, notification,
14415                    removeNotification);
14416        }
14417    }
14418
14419    @Override
14420    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14421            boolean requireFull, String name, String callerPackage) {
14422        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14423                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14424    }
14425
14426    int unsafeConvertIncomingUser(int userId) {
14427        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14428                ? mCurrentUserId : userId;
14429    }
14430
14431    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14432            int allowMode, String name, String callerPackage) {
14433        final int callingUserId = UserHandle.getUserId(callingUid);
14434        if (callingUserId == userId) {
14435            return userId;
14436        }
14437
14438        // Note that we may be accessing mCurrentUserId outside of a lock...
14439        // shouldn't be a big deal, if this is being called outside
14440        // of a locked context there is intrinsically a race with
14441        // the value the caller will receive and someone else changing it.
14442        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14443        // we will switch to the calling user if access to the current user fails.
14444        int targetUserId = unsafeConvertIncomingUser(userId);
14445
14446        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14447            final boolean allow;
14448            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14449                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14450                // If the caller has this permission, they always pass go.  And collect $200.
14451                allow = true;
14452            } else if (allowMode == ALLOW_FULL_ONLY) {
14453                // We require full access, sucks to be you.
14454                allow = false;
14455            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14456                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14457                // If the caller does not have either permission, they are always doomed.
14458                allow = false;
14459            } else if (allowMode == ALLOW_NON_FULL) {
14460                // We are blanket allowing non-full access, you lucky caller!
14461                allow = true;
14462            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14463                // We may or may not allow this depending on whether the two users are
14464                // in the same profile.
14465                synchronized (mUserProfileGroupIdsSelfLocked) {
14466                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14467                            UserInfo.NO_PROFILE_GROUP_ID);
14468                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14469                            UserInfo.NO_PROFILE_GROUP_ID);
14470                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14471                            && callingProfile == targetProfile;
14472                }
14473            } else {
14474                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14475            }
14476            if (!allow) {
14477                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14478                    // In this case, they would like to just execute as their
14479                    // owner user instead of failing.
14480                    targetUserId = callingUserId;
14481                } else {
14482                    StringBuilder builder = new StringBuilder(128);
14483                    builder.append("Permission Denial: ");
14484                    builder.append(name);
14485                    if (callerPackage != null) {
14486                        builder.append(" from ");
14487                        builder.append(callerPackage);
14488                    }
14489                    builder.append(" asks to run as user ");
14490                    builder.append(userId);
14491                    builder.append(" but is calling from user ");
14492                    builder.append(UserHandle.getUserId(callingUid));
14493                    builder.append("; this requires ");
14494                    builder.append(INTERACT_ACROSS_USERS_FULL);
14495                    if (allowMode != ALLOW_FULL_ONLY) {
14496                        builder.append(" or ");
14497                        builder.append(INTERACT_ACROSS_USERS);
14498                    }
14499                    String msg = builder.toString();
14500                    Slog.w(TAG, msg);
14501                    throw new SecurityException(msg);
14502                }
14503            }
14504        }
14505        if (!allowAll && targetUserId < 0) {
14506            throw new IllegalArgumentException(
14507                    "Call does not support special user #" + targetUserId);
14508        }
14509        return targetUserId;
14510    }
14511
14512    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14513            String className, int flags) {
14514        boolean result = false;
14515        // For apps that don't have pre-defined UIDs, check for permission
14516        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14517            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14518                if (ActivityManager.checkUidPermission(
14519                        INTERACT_ACROSS_USERS,
14520                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14521                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14522                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14523                            + " requests FLAG_SINGLE_USER, but app does not hold "
14524                            + INTERACT_ACROSS_USERS;
14525                    Slog.w(TAG, msg);
14526                    throw new SecurityException(msg);
14527                }
14528                // Permission passed
14529                result = true;
14530            }
14531        } else if ("system".equals(componentProcessName)) {
14532            result = true;
14533        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14534                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14535            // Phone app is allowed to export singleuser providers.
14536            result = true;
14537        } else {
14538            // App with pre-defined UID, check if it's a persistent app
14539            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14540        }
14541        if (DEBUG_MU) {
14542            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14543                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14544        }
14545        return result;
14546    }
14547
14548    /**
14549     * Checks to see if the caller is in the same app as the singleton
14550     * component, or the component is in a special app. It allows special apps
14551     * to export singleton components but prevents exporting singleton
14552     * components for regular apps.
14553     */
14554    boolean isValidSingletonCall(int callingUid, int componentUid) {
14555        int componentAppId = UserHandle.getAppId(componentUid);
14556        return UserHandle.isSameApp(callingUid, componentUid)
14557                || componentAppId == Process.SYSTEM_UID
14558                || componentAppId == Process.PHONE_UID
14559                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14560                        == PackageManager.PERMISSION_GRANTED;
14561    }
14562
14563    public int bindService(IApplicationThread caller, IBinder token,
14564            Intent service, String resolvedType,
14565            IServiceConnection connection, int flags, int userId) {
14566        enforceNotIsolatedCaller("bindService");
14567        // Refuse possible leaked file descriptors
14568        if (service != null && service.hasFileDescriptors() == true) {
14569            throw new IllegalArgumentException("File descriptors passed in Intent");
14570        }
14571
14572        synchronized(this) {
14573            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14574                    connection, flags, userId);
14575        }
14576    }
14577
14578    public boolean unbindService(IServiceConnection connection) {
14579        synchronized (this) {
14580            return mServices.unbindServiceLocked(connection);
14581        }
14582    }
14583
14584    public void publishService(IBinder token, Intent intent, IBinder service) {
14585        // Refuse possible leaked file descriptors
14586        if (intent != null && intent.hasFileDescriptors() == true) {
14587            throw new IllegalArgumentException("File descriptors passed in Intent");
14588        }
14589
14590        synchronized(this) {
14591            if (!(token instanceof ServiceRecord)) {
14592                throw new IllegalArgumentException("Invalid service token");
14593            }
14594            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14595        }
14596    }
14597
14598    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14599        // Refuse possible leaked file descriptors
14600        if (intent != null && intent.hasFileDescriptors() == true) {
14601            throw new IllegalArgumentException("File descriptors passed in Intent");
14602        }
14603
14604        synchronized(this) {
14605            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14606        }
14607    }
14608
14609    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14610        synchronized(this) {
14611            if (!(token instanceof ServiceRecord)) {
14612                throw new IllegalArgumentException("Invalid service token");
14613            }
14614            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14615        }
14616    }
14617
14618    // =========================================================
14619    // BACKUP AND RESTORE
14620    // =========================================================
14621
14622    // Cause the target app to be launched if necessary and its backup agent
14623    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14624    // activity manager to announce its creation.
14625    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14626        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14627        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14628
14629        synchronized(this) {
14630            // !!! TODO: currently no check here that we're already bound
14631            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14632            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14633            synchronized (stats) {
14634                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14635            }
14636
14637            // Backup agent is now in use, its package can't be stopped.
14638            try {
14639                AppGlobals.getPackageManager().setPackageStoppedState(
14640                        app.packageName, false, UserHandle.getUserId(app.uid));
14641            } catch (RemoteException e) {
14642            } catch (IllegalArgumentException e) {
14643                Slog.w(TAG, "Failed trying to unstop package "
14644                        + app.packageName + ": " + e);
14645            }
14646
14647            BackupRecord r = new BackupRecord(ss, app, backupMode);
14648            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14649                    ? new ComponentName(app.packageName, app.backupAgentName)
14650                    : new ComponentName("android", "FullBackupAgent");
14651            // startProcessLocked() returns existing proc's record if it's already running
14652            ProcessRecord proc = startProcessLocked(app.processName, app,
14653                    false, 0, "backup", hostingName, false, false, false);
14654            if (proc == null) {
14655                Slog.e(TAG, "Unable to start backup agent process " + r);
14656                return false;
14657            }
14658
14659            r.app = proc;
14660            mBackupTarget = r;
14661            mBackupAppName = app.packageName;
14662
14663            // Try not to kill the process during backup
14664            updateOomAdjLocked(proc);
14665
14666            // If the process is already attached, schedule the creation of the backup agent now.
14667            // If it is not yet live, this will be done when it attaches to the framework.
14668            if (proc.thread != null) {
14669                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14670                try {
14671                    proc.thread.scheduleCreateBackupAgent(app,
14672                            compatibilityInfoForPackageLocked(app), backupMode);
14673                } catch (RemoteException e) {
14674                    // Will time out on the backup manager side
14675                }
14676            } else {
14677                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14678            }
14679            // Invariants: at this point, the target app process exists and the application
14680            // is either already running or in the process of coming up.  mBackupTarget and
14681            // mBackupAppName describe the app, so that when it binds back to the AM we
14682            // know that it's scheduled for a backup-agent operation.
14683        }
14684
14685        return true;
14686    }
14687
14688    @Override
14689    public void clearPendingBackup() {
14690        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14691        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14692
14693        synchronized (this) {
14694            mBackupTarget = null;
14695            mBackupAppName = null;
14696        }
14697    }
14698
14699    // A backup agent has just come up
14700    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14701        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14702                + " = " + agent);
14703
14704        synchronized(this) {
14705            if (!agentPackageName.equals(mBackupAppName)) {
14706                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14707                return;
14708            }
14709        }
14710
14711        long oldIdent = Binder.clearCallingIdentity();
14712        try {
14713            IBackupManager bm = IBackupManager.Stub.asInterface(
14714                    ServiceManager.getService(Context.BACKUP_SERVICE));
14715            bm.agentConnected(agentPackageName, agent);
14716        } catch (RemoteException e) {
14717            // can't happen; the backup manager service is local
14718        } catch (Exception e) {
14719            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14720            e.printStackTrace();
14721        } finally {
14722            Binder.restoreCallingIdentity(oldIdent);
14723        }
14724    }
14725
14726    // done with this agent
14727    public void unbindBackupAgent(ApplicationInfo appInfo) {
14728        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14729        if (appInfo == null) {
14730            Slog.w(TAG, "unbind backup agent for null app");
14731            return;
14732        }
14733
14734        synchronized(this) {
14735            try {
14736                if (mBackupAppName == null) {
14737                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14738                    return;
14739                }
14740
14741                if (!mBackupAppName.equals(appInfo.packageName)) {
14742                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14743                    return;
14744                }
14745
14746                // Not backing this app up any more; reset its OOM adjustment
14747                final ProcessRecord proc = mBackupTarget.app;
14748                updateOomAdjLocked(proc);
14749
14750                // If the app crashed during backup, 'thread' will be null here
14751                if (proc.thread != null) {
14752                    try {
14753                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14754                                compatibilityInfoForPackageLocked(appInfo));
14755                    } catch (Exception e) {
14756                        Slog.e(TAG, "Exception when unbinding backup agent:");
14757                        e.printStackTrace();
14758                    }
14759                }
14760            } finally {
14761                mBackupTarget = null;
14762                mBackupAppName = null;
14763            }
14764        }
14765    }
14766    // =========================================================
14767    // BROADCASTS
14768    // =========================================================
14769
14770    private final List getStickiesLocked(String action, IntentFilter filter,
14771            List cur, int userId) {
14772        final ContentResolver resolver = mContext.getContentResolver();
14773        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14774        if (stickies == null) {
14775            return cur;
14776        }
14777        final ArrayList<Intent> list = stickies.get(action);
14778        if (list == null) {
14779            return cur;
14780        }
14781        int N = list.size();
14782        for (int i=0; i<N; i++) {
14783            Intent intent = list.get(i);
14784            if (filter.match(resolver, intent, true, TAG) >= 0) {
14785                if (cur == null) {
14786                    cur = new ArrayList<Intent>();
14787                }
14788                cur.add(intent);
14789            }
14790        }
14791        return cur;
14792    }
14793
14794    boolean isPendingBroadcastProcessLocked(int pid) {
14795        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14796                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14797    }
14798
14799    void skipPendingBroadcastLocked(int pid) {
14800            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14801            for (BroadcastQueue queue : mBroadcastQueues) {
14802                queue.skipPendingBroadcastLocked(pid);
14803            }
14804    }
14805
14806    // The app just attached; send any pending broadcasts that it should receive
14807    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14808        boolean didSomething = false;
14809        for (BroadcastQueue queue : mBroadcastQueues) {
14810            didSomething |= queue.sendPendingBroadcastsLocked(app);
14811        }
14812        return didSomething;
14813    }
14814
14815    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14816            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14817        enforceNotIsolatedCaller("registerReceiver");
14818        int callingUid;
14819        int callingPid;
14820        synchronized(this) {
14821            ProcessRecord callerApp = null;
14822            if (caller != null) {
14823                callerApp = getRecordForAppLocked(caller);
14824                if (callerApp == null) {
14825                    throw new SecurityException(
14826                            "Unable to find app for caller " + caller
14827                            + " (pid=" + Binder.getCallingPid()
14828                            + ") when registering receiver " + receiver);
14829                }
14830                if (callerApp.info.uid != Process.SYSTEM_UID &&
14831                        !callerApp.pkgList.containsKey(callerPackage) &&
14832                        !"android".equals(callerPackage)) {
14833                    throw new SecurityException("Given caller package " + callerPackage
14834                            + " is not running in process " + callerApp);
14835                }
14836                callingUid = callerApp.info.uid;
14837                callingPid = callerApp.pid;
14838            } else {
14839                callerPackage = null;
14840                callingUid = Binder.getCallingUid();
14841                callingPid = Binder.getCallingPid();
14842            }
14843
14844            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14845                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14846
14847            List allSticky = null;
14848
14849            // Look for any matching sticky broadcasts...
14850            Iterator actions = filter.actionsIterator();
14851            if (actions != null) {
14852                while (actions.hasNext()) {
14853                    String action = (String)actions.next();
14854                    allSticky = getStickiesLocked(action, filter, allSticky,
14855                            UserHandle.USER_ALL);
14856                    allSticky = getStickiesLocked(action, filter, allSticky,
14857                            UserHandle.getUserId(callingUid));
14858                }
14859            } else {
14860                allSticky = getStickiesLocked(null, filter, allSticky,
14861                        UserHandle.USER_ALL);
14862                allSticky = getStickiesLocked(null, filter, allSticky,
14863                        UserHandle.getUserId(callingUid));
14864            }
14865
14866            // The first sticky in the list is returned directly back to
14867            // the client.
14868            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14869
14870            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14871                    + ": " + sticky);
14872
14873            if (receiver == null) {
14874                return sticky;
14875            }
14876
14877            ReceiverList rl
14878                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14879            if (rl == null) {
14880                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14881                        userId, receiver);
14882                if (rl.app != null) {
14883                    rl.app.receivers.add(rl);
14884                } else {
14885                    try {
14886                        receiver.asBinder().linkToDeath(rl, 0);
14887                    } catch (RemoteException e) {
14888                        return sticky;
14889                    }
14890                    rl.linkedToDeath = true;
14891                }
14892                mRegisteredReceivers.put(receiver.asBinder(), rl);
14893            } else if (rl.uid != callingUid) {
14894                throw new IllegalArgumentException(
14895                        "Receiver requested to register for uid " + callingUid
14896                        + " was previously registered for uid " + rl.uid);
14897            } else if (rl.pid != callingPid) {
14898                throw new IllegalArgumentException(
14899                        "Receiver requested to register for pid " + callingPid
14900                        + " was previously registered for pid " + rl.pid);
14901            } else if (rl.userId != userId) {
14902                throw new IllegalArgumentException(
14903                        "Receiver requested to register for user " + userId
14904                        + " was previously registered for user " + rl.userId);
14905            }
14906            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14907                    permission, callingUid, userId);
14908            rl.add(bf);
14909            if (!bf.debugCheck()) {
14910                Slog.w(TAG, "==> For Dynamic broadast");
14911            }
14912            mReceiverResolver.addFilter(bf);
14913
14914            // Enqueue broadcasts for all existing stickies that match
14915            // this filter.
14916            if (allSticky != null) {
14917                ArrayList receivers = new ArrayList();
14918                receivers.add(bf);
14919
14920                int N = allSticky.size();
14921                for (int i=0; i<N; i++) {
14922                    Intent intent = (Intent)allSticky.get(i);
14923                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14924                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14925                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14926                            null, null, false, true, true, -1);
14927                    queue.enqueueParallelBroadcastLocked(r);
14928                    queue.scheduleBroadcastsLocked();
14929                }
14930            }
14931
14932            return sticky;
14933        }
14934    }
14935
14936    public void unregisterReceiver(IIntentReceiver receiver) {
14937        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14938
14939        final long origId = Binder.clearCallingIdentity();
14940        try {
14941            boolean doTrim = false;
14942
14943            synchronized(this) {
14944                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14945                if (rl != null) {
14946                    if (rl.curBroadcast != null) {
14947                        BroadcastRecord r = rl.curBroadcast;
14948                        final boolean doNext = finishReceiverLocked(
14949                                receiver.asBinder(), r.resultCode, r.resultData,
14950                                r.resultExtras, r.resultAbort);
14951                        if (doNext) {
14952                            doTrim = true;
14953                            r.queue.processNextBroadcast(false);
14954                        }
14955                    }
14956
14957                    if (rl.app != null) {
14958                        rl.app.receivers.remove(rl);
14959                    }
14960                    removeReceiverLocked(rl);
14961                    if (rl.linkedToDeath) {
14962                        rl.linkedToDeath = false;
14963                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14964                    }
14965                }
14966            }
14967
14968            // If we actually concluded any broadcasts, we might now be able
14969            // to trim the recipients' apps from our working set
14970            if (doTrim) {
14971                trimApplications();
14972                return;
14973            }
14974
14975        } finally {
14976            Binder.restoreCallingIdentity(origId);
14977        }
14978    }
14979
14980    void removeReceiverLocked(ReceiverList rl) {
14981        mRegisteredReceivers.remove(rl.receiver.asBinder());
14982        int N = rl.size();
14983        for (int i=0; i<N; i++) {
14984            mReceiverResolver.removeFilter(rl.get(i));
14985        }
14986    }
14987
14988    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14989        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14990            ProcessRecord r = mLruProcesses.get(i);
14991            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14992                try {
14993                    r.thread.dispatchPackageBroadcast(cmd, packages);
14994                } catch (RemoteException ex) {
14995                }
14996            }
14997        }
14998    }
14999
15000    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15001            int[] users) {
15002        List<ResolveInfo> receivers = null;
15003        try {
15004            HashSet<ComponentName> singleUserReceivers = null;
15005            boolean scannedFirstReceivers = false;
15006            for (int user : users) {
15007                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15008                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15009                if (user != 0 && newReceivers != null) {
15010                    // If this is not the primary user, we need to check for
15011                    // any receivers that should be filtered out.
15012                    for (int i=0; i<newReceivers.size(); i++) {
15013                        ResolveInfo ri = newReceivers.get(i);
15014                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15015                            newReceivers.remove(i);
15016                            i--;
15017                        }
15018                    }
15019                }
15020                if (newReceivers != null && newReceivers.size() == 0) {
15021                    newReceivers = null;
15022                }
15023                if (receivers == null) {
15024                    receivers = newReceivers;
15025                } else if (newReceivers != null) {
15026                    // We need to concatenate the additional receivers
15027                    // found with what we have do far.  This would be easy,
15028                    // but we also need to de-dup any receivers that are
15029                    // singleUser.
15030                    if (!scannedFirstReceivers) {
15031                        // Collect any single user receivers we had already retrieved.
15032                        scannedFirstReceivers = true;
15033                        for (int i=0; i<receivers.size(); i++) {
15034                            ResolveInfo ri = receivers.get(i);
15035                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15036                                ComponentName cn = new ComponentName(
15037                                        ri.activityInfo.packageName, ri.activityInfo.name);
15038                                if (singleUserReceivers == null) {
15039                                    singleUserReceivers = new HashSet<ComponentName>();
15040                                }
15041                                singleUserReceivers.add(cn);
15042                            }
15043                        }
15044                    }
15045                    // Add the new results to the existing results, tracking
15046                    // and de-dupping single user receivers.
15047                    for (int i=0; i<newReceivers.size(); i++) {
15048                        ResolveInfo ri = newReceivers.get(i);
15049                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15050                            ComponentName cn = new ComponentName(
15051                                    ri.activityInfo.packageName, ri.activityInfo.name);
15052                            if (singleUserReceivers == null) {
15053                                singleUserReceivers = new HashSet<ComponentName>();
15054                            }
15055                            if (!singleUserReceivers.contains(cn)) {
15056                                singleUserReceivers.add(cn);
15057                                receivers.add(ri);
15058                            }
15059                        } else {
15060                            receivers.add(ri);
15061                        }
15062                    }
15063                }
15064            }
15065        } catch (RemoteException ex) {
15066            // pm is in same process, this will never happen.
15067        }
15068        return receivers;
15069    }
15070
15071    private final int broadcastIntentLocked(ProcessRecord callerApp,
15072            String callerPackage, Intent intent, String resolvedType,
15073            IIntentReceiver resultTo, int resultCode, String resultData,
15074            Bundle map, String requiredPermission, int appOp,
15075            boolean ordered, boolean sticky, int callingPid, int callingUid,
15076            int userId) {
15077        intent = new Intent(intent);
15078
15079        // By default broadcasts do not go to stopped apps.
15080        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15081
15082        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15083            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15084            + " ordered=" + ordered + " userid=" + userId);
15085        if ((resultTo != null) && !ordered) {
15086            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15087        }
15088
15089        userId = handleIncomingUser(callingPid, callingUid, userId,
15090                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15091
15092        // Make sure that the user who is receiving this broadcast is started.
15093        // If not, we will just skip it.
15094
15095
15096        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15097            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15098                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15099                Slog.w(TAG, "Skipping broadcast of " + intent
15100                        + ": user " + userId + " is stopped");
15101                return ActivityManager.BROADCAST_SUCCESS;
15102            }
15103        }
15104
15105        /*
15106         * Prevent non-system code (defined here to be non-persistent
15107         * processes) from sending protected broadcasts.
15108         */
15109        int callingAppId = UserHandle.getAppId(callingUid);
15110        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15111            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15112            || callingAppId == Process.NFC_UID || callingUid == 0) {
15113            // Always okay.
15114        } else if (callerApp == null || !callerApp.persistent) {
15115            try {
15116                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15117                        intent.getAction())) {
15118                    String msg = "Permission Denial: not allowed to send broadcast "
15119                            + intent.getAction() + " from pid="
15120                            + callingPid + ", uid=" + callingUid;
15121                    Slog.w(TAG, msg);
15122                    throw new SecurityException(msg);
15123                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15124                    // Special case for compatibility: we don't want apps to send this,
15125                    // but historically it has not been protected and apps may be using it
15126                    // to poke their own app widget.  So, instead of making it protected,
15127                    // just limit it to the caller.
15128                    if (callerApp == null) {
15129                        String msg = "Permission Denial: not allowed to send broadcast "
15130                                + intent.getAction() + " from unknown caller.";
15131                        Slog.w(TAG, msg);
15132                        throw new SecurityException(msg);
15133                    } else if (intent.getComponent() != null) {
15134                        // They are good enough to send to an explicit component...  verify
15135                        // it is being sent to the calling app.
15136                        if (!intent.getComponent().getPackageName().equals(
15137                                callerApp.info.packageName)) {
15138                            String msg = "Permission Denial: not allowed to send broadcast "
15139                                    + intent.getAction() + " to "
15140                                    + intent.getComponent().getPackageName() + " from "
15141                                    + callerApp.info.packageName;
15142                            Slog.w(TAG, msg);
15143                            throw new SecurityException(msg);
15144                        }
15145                    } else {
15146                        // Limit broadcast to their own package.
15147                        intent.setPackage(callerApp.info.packageName);
15148                    }
15149                }
15150            } catch (RemoteException e) {
15151                Slog.w(TAG, "Remote exception", e);
15152                return ActivityManager.BROADCAST_SUCCESS;
15153            }
15154        }
15155
15156        // Handle special intents: if this broadcast is from the package
15157        // manager about a package being removed, we need to remove all of
15158        // its activities from the history stack.
15159        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15160                intent.getAction());
15161        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15162                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15163                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15164                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15165                || uidRemoved) {
15166            if (checkComponentPermission(
15167                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15168                    callingPid, callingUid, -1, true)
15169                    == PackageManager.PERMISSION_GRANTED) {
15170                if (uidRemoved) {
15171                    final Bundle intentExtras = intent.getExtras();
15172                    final int uid = intentExtras != null
15173                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15174                    if (uid >= 0) {
15175                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15176                        synchronized (bs) {
15177                            bs.removeUidStatsLocked(uid);
15178                        }
15179                        mAppOpsService.uidRemoved(uid);
15180                    }
15181                } else {
15182                    // If resources are unavailable just force stop all
15183                    // those packages and flush the attribute cache as well.
15184                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15185                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15186                        if (list != null && (list.length > 0)) {
15187                            for (String pkg : list) {
15188                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15189                                        "storage unmount");
15190                            }
15191                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15192                            sendPackageBroadcastLocked(
15193                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15194                        }
15195                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15196                            intent.getAction())) {
15197                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15198                    } else {
15199                        Uri data = intent.getData();
15200                        String ssp;
15201                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15202                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15203                                    intent.getAction());
15204                            boolean fullUninstall = removed &&
15205                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15206                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15207                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15208                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15209                                        false, fullUninstall, userId,
15210                                        removed ? "pkg removed" : "pkg changed");
15211                            }
15212                            if (removed) {
15213                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15214                                        new String[] {ssp}, userId);
15215                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15216                                    mAppOpsService.packageRemoved(
15217                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15218
15219                                    // Remove all permissions granted from/to this package
15220                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15221                                }
15222                            }
15223                        }
15224                    }
15225                }
15226            } else {
15227                String msg = "Permission Denial: " + intent.getAction()
15228                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15229                        + ", uid=" + callingUid + ")"
15230                        + " requires "
15231                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15232                Slog.w(TAG, msg);
15233                throw new SecurityException(msg);
15234            }
15235
15236        // Special case for adding a package: by default turn on compatibility
15237        // mode.
15238        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15239            Uri data = intent.getData();
15240            String ssp;
15241            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15242                mCompatModePackages.handlePackageAddedLocked(ssp,
15243                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15244            }
15245        }
15246
15247        /*
15248         * If this is the time zone changed action, queue up a message that will reset the timezone
15249         * of all currently running processes. This message will get queued up before the broadcast
15250         * happens.
15251         */
15252        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15253            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15254        }
15255
15256        /*
15257         * If the user set the time, let all running processes know.
15258         */
15259        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15260            final int is24Hour = intent.getBooleanExtra(
15261                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15262            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15263            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15264            synchronized (stats) {
15265                stats.noteCurrentTimeChangedLocked();
15266            }
15267        }
15268
15269        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15270            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15271        }
15272
15273        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15274            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15275            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15276        }
15277
15278        // Add to the sticky list if requested.
15279        if (sticky) {
15280            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15281                    callingPid, callingUid)
15282                    != PackageManager.PERMISSION_GRANTED) {
15283                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15284                        + callingPid + ", uid=" + callingUid
15285                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15286                Slog.w(TAG, msg);
15287                throw new SecurityException(msg);
15288            }
15289            if (requiredPermission != null) {
15290                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15291                        + " and enforce permission " + requiredPermission);
15292                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15293            }
15294            if (intent.getComponent() != null) {
15295                throw new SecurityException(
15296                        "Sticky broadcasts can't target a specific component");
15297            }
15298            // We use userId directly here, since the "all" target is maintained
15299            // as a separate set of sticky broadcasts.
15300            if (userId != UserHandle.USER_ALL) {
15301                // But first, if this is not a broadcast to all users, then
15302                // make sure it doesn't conflict with an existing broadcast to
15303                // all users.
15304                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15305                        UserHandle.USER_ALL);
15306                if (stickies != null) {
15307                    ArrayList<Intent> list = stickies.get(intent.getAction());
15308                    if (list != null) {
15309                        int N = list.size();
15310                        int i;
15311                        for (i=0; i<N; i++) {
15312                            if (intent.filterEquals(list.get(i))) {
15313                                throw new IllegalArgumentException(
15314                                        "Sticky broadcast " + intent + " for user "
15315                                        + userId + " conflicts with existing global broadcast");
15316                            }
15317                        }
15318                    }
15319                }
15320            }
15321            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15322            if (stickies == null) {
15323                stickies = new ArrayMap<String, ArrayList<Intent>>();
15324                mStickyBroadcasts.put(userId, stickies);
15325            }
15326            ArrayList<Intent> list = stickies.get(intent.getAction());
15327            if (list == null) {
15328                list = new ArrayList<Intent>();
15329                stickies.put(intent.getAction(), list);
15330            }
15331            int N = list.size();
15332            int i;
15333            for (i=0; i<N; i++) {
15334                if (intent.filterEquals(list.get(i))) {
15335                    // This sticky already exists, replace it.
15336                    list.set(i, new Intent(intent));
15337                    break;
15338                }
15339            }
15340            if (i >= N) {
15341                list.add(new Intent(intent));
15342            }
15343        }
15344
15345        int[] users;
15346        if (userId == UserHandle.USER_ALL) {
15347            // Caller wants broadcast to go to all started users.
15348            users = mStartedUserArray;
15349        } else {
15350            // Caller wants broadcast to go to one specific user.
15351            users = new int[] {userId};
15352        }
15353
15354        // Figure out who all will receive this broadcast.
15355        List receivers = null;
15356        List<BroadcastFilter> registeredReceivers = null;
15357        // Need to resolve the intent to interested receivers...
15358        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15359                 == 0) {
15360            receivers = collectReceiverComponents(intent, resolvedType, users);
15361        }
15362        if (intent.getComponent() == null) {
15363            registeredReceivers = mReceiverResolver.queryIntent(intent,
15364                    resolvedType, false, userId);
15365        }
15366
15367        final boolean replacePending =
15368                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15369
15370        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15371                + " replacePending=" + replacePending);
15372
15373        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15374        if (!ordered && NR > 0) {
15375            // If we are not serializing this broadcast, then send the
15376            // registered receivers separately so they don't wait for the
15377            // components to be launched.
15378            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15379            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15380                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15381                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15382                    ordered, sticky, false, userId);
15383            if (DEBUG_BROADCAST) Slog.v(
15384                    TAG, "Enqueueing parallel broadcast " + r);
15385            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15386            if (!replaced) {
15387                queue.enqueueParallelBroadcastLocked(r);
15388                queue.scheduleBroadcastsLocked();
15389            }
15390            registeredReceivers = null;
15391            NR = 0;
15392        }
15393
15394        // Merge into one list.
15395        int ir = 0;
15396        if (receivers != null) {
15397            // A special case for PACKAGE_ADDED: do not allow the package
15398            // being added to see this broadcast.  This prevents them from
15399            // using this as a back door to get run as soon as they are
15400            // installed.  Maybe in the future we want to have a special install
15401            // broadcast or such for apps, but we'd like to deliberately make
15402            // this decision.
15403            String skipPackages[] = null;
15404            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15405                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15406                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15407                Uri data = intent.getData();
15408                if (data != null) {
15409                    String pkgName = data.getSchemeSpecificPart();
15410                    if (pkgName != null) {
15411                        skipPackages = new String[] { pkgName };
15412                    }
15413                }
15414            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15415                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15416            }
15417            if (skipPackages != null && (skipPackages.length > 0)) {
15418                for (String skipPackage : skipPackages) {
15419                    if (skipPackage != null) {
15420                        int NT = receivers.size();
15421                        for (int it=0; it<NT; it++) {
15422                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15423                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15424                                receivers.remove(it);
15425                                it--;
15426                                NT--;
15427                            }
15428                        }
15429                    }
15430                }
15431            }
15432
15433            int NT = receivers != null ? receivers.size() : 0;
15434            int it = 0;
15435            ResolveInfo curt = null;
15436            BroadcastFilter curr = null;
15437            while (it < NT && ir < NR) {
15438                if (curt == null) {
15439                    curt = (ResolveInfo)receivers.get(it);
15440                }
15441                if (curr == null) {
15442                    curr = registeredReceivers.get(ir);
15443                }
15444                if (curr.getPriority() >= curt.priority) {
15445                    // Insert this broadcast record into the final list.
15446                    receivers.add(it, curr);
15447                    ir++;
15448                    curr = null;
15449                    it++;
15450                    NT++;
15451                } else {
15452                    // Skip to the next ResolveInfo in the final list.
15453                    it++;
15454                    curt = null;
15455                }
15456            }
15457        }
15458        while (ir < NR) {
15459            if (receivers == null) {
15460                receivers = new ArrayList();
15461            }
15462            receivers.add(registeredReceivers.get(ir));
15463            ir++;
15464        }
15465
15466        if ((receivers != null && receivers.size() > 0)
15467                || resultTo != null) {
15468            BroadcastQueue queue = broadcastQueueForIntent(intent);
15469            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15470                    callerPackage, callingPid, callingUid, resolvedType,
15471                    requiredPermission, appOp, receivers, resultTo, resultCode,
15472                    resultData, map, ordered, sticky, false, userId);
15473            if (DEBUG_BROADCAST) Slog.v(
15474                    TAG, "Enqueueing ordered broadcast " + r
15475                    + ": prev had " + queue.mOrderedBroadcasts.size());
15476            if (DEBUG_BROADCAST) {
15477                int seq = r.intent.getIntExtra("seq", -1);
15478                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15479            }
15480            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15481            if (!replaced) {
15482                queue.enqueueOrderedBroadcastLocked(r);
15483                queue.scheduleBroadcastsLocked();
15484            }
15485        }
15486
15487        return ActivityManager.BROADCAST_SUCCESS;
15488    }
15489
15490    final Intent verifyBroadcastLocked(Intent intent) {
15491        // Refuse possible leaked file descriptors
15492        if (intent != null && intent.hasFileDescriptors() == true) {
15493            throw new IllegalArgumentException("File descriptors passed in Intent");
15494        }
15495
15496        int flags = intent.getFlags();
15497
15498        if (!mProcessesReady) {
15499            // if the caller really truly claims to know what they're doing, go
15500            // ahead and allow the broadcast without launching any receivers
15501            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15502                intent = new Intent(intent);
15503                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15504            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15505                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15506                        + " before boot completion");
15507                throw new IllegalStateException("Cannot broadcast before boot completed");
15508            }
15509        }
15510
15511        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15512            throw new IllegalArgumentException(
15513                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15514        }
15515
15516        return intent;
15517    }
15518
15519    public final int broadcastIntent(IApplicationThread caller,
15520            Intent intent, String resolvedType, IIntentReceiver resultTo,
15521            int resultCode, String resultData, Bundle map,
15522            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15523        enforceNotIsolatedCaller("broadcastIntent");
15524        synchronized(this) {
15525            intent = verifyBroadcastLocked(intent);
15526
15527            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15528            final int callingPid = Binder.getCallingPid();
15529            final int callingUid = Binder.getCallingUid();
15530            final long origId = Binder.clearCallingIdentity();
15531            int res = broadcastIntentLocked(callerApp,
15532                    callerApp != null ? callerApp.info.packageName : null,
15533                    intent, resolvedType, resultTo,
15534                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15535                    callingPid, callingUid, userId);
15536            Binder.restoreCallingIdentity(origId);
15537            return res;
15538        }
15539    }
15540
15541    int broadcastIntentInPackage(String packageName, int uid,
15542            Intent intent, String resolvedType, IIntentReceiver resultTo,
15543            int resultCode, String resultData, Bundle map,
15544            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15545        synchronized(this) {
15546            intent = verifyBroadcastLocked(intent);
15547
15548            final long origId = Binder.clearCallingIdentity();
15549            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15550                    resultTo, resultCode, resultData, map, requiredPermission,
15551                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15552            Binder.restoreCallingIdentity(origId);
15553            return res;
15554        }
15555    }
15556
15557    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15558        // Refuse possible leaked file descriptors
15559        if (intent != null && intent.hasFileDescriptors() == true) {
15560            throw new IllegalArgumentException("File descriptors passed in Intent");
15561        }
15562
15563        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15564                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15565
15566        synchronized(this) {
15567            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15568                    != PackageManager.PERMISSION_GRANTED) {
15569                String msg = "Permission Denial: unbroadcastIntent() from pid="
15570                        + Binder.getCallingPid()
15571                        + ", uid=" + Binder.getCallingUid()
15572                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15573                Slog.w(TAG, msg);
15574                throw new SecurityException(msg);
15575            }
15576            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15577            if (stickies != null) {
15578                ArrayList<Intent> list = stickies.get(intent.getAction());
15579                if (list != null) {
15580                    int N = list.size();
15581                    int i;
15582                    for (i=0; i<N; i++) {
15583                        if (intent.filterEquals(list.get(i))) {
15584                            list.remove(i);
15585                            break;
15586                        }
15587                    }
15588                    if (list.size() <= 0) {
15589                        stickies.remove(intent.getAction());
15590                    }
15591                }
15592                if (stickies.size() <= 0) {
15593                    mStickyBroadcasts.remove(userId);
15594                }
15595            }
15596        }
15597    }
15598
15599    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15600            String resultData, Bundle resultExtras, boolean resultAbort) {
15601        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15602        if (r == null) {
15603            Slog.w(TAG, "finishReceiver called but not found on queue");
15604            return false;
15605        }
15606
15607        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15608    }
15609
15610    void backgroundServicesFinishedLocked(int userId) {
15611        for (BroadcastQueue queue : mBroadcastQueues) {
15612            queue.backgroundServicesFinishedLocked(userId);
15613        }
15614    }
15615
15616    public void finishReceiver(IBinder who, int resultCode, String resultData,
15617            Bundle resultExtras, boolean resultAbort) {
15618        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15619
15620        // Refuse possible leaked file descriptors
15621        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15622            throw new IllegalArgumentException("File descriptors passed in Bundle");
15623        }
15624
15625        final long origId = Binder.clearCallingIdentity();
15626        try {
15627            boolean doNext = false;
15628            BroadcastRecord r;
15629
15630            synchronized(this) {
15631                r = broadcastRecordForReceiverLocked(who);
15632                if (r != null) {
15633                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15634                        resultData, resultExtras, resultAbort, true);
15635                }
15636            }
15637
15638            if (doNext) {
15639                r.queue.processNextBroadcast(false);
15640            }
15641            trimApplications();
15642        } finally {
15643            Binder.restoreCallingIdentity(origId);
15644        }
15645    }
15646
15647    // =========================================================
15648    // INSTRUMENTATION
15649    // =========================================================
15650
15651    public boolean startInstrumentation(ComponentName className,
15652            String profileFile, int flags, Bundle arguments,
15653            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15654            int userId, String abiOverride) {
15655        enforceNotIsolatedCaller("startInstrumentation");
15656        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15657                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15658        // Refuse possible leaked file descriptors
15659        if (arguments != null && arguments.hasFileDescriptors()) {
15660            throw new IllegalArgumentException("File descriptors passed in Bundle");
15661        }
15662
15663        synchronized(this) {
15664            InstrumentationInfo ii = null;
15665            ApplicationInfo ai = null;
15666            try {
15667                ii = mContext.getPackageManager().getInstrumentationInfo(
15668                    className, STOCK_PM_FLAGS);
15669                ai = AppGlobals.getPackageManager().getApplicationInfo(
15670                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15671            } catch (PackageManager.NameNotFoundException e) {
15672            } catch (RemoteException e) {
15673            }
15674            if (ii == null) {
15675                reportStartInstrumentationFailure(watcher, className,
15676                        "Unable to find instrumentation info for: " + className);
15677                return false;
15678            }
15679            if (ai == null) {
15680                reportStartInstrumentationFailure(watcher, className,
15681                        "Unable to find instrumentation target package: " + ii.targetPackage);
15682                return false;
15683            }
15684
15685            int match = mContext.getPackageManager().checkSignatures(
15686                    ii.targetPackage, ii.packageName);
15687            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15688                String msg = "Permission Denial: starting instrumentation "
15689                        + className + " from pid="
15690                        + Binder.getCallingPid()
15691                        + ", uid=" + Binder.getCallingPid()
15692                        + " not allowed because package " + ii.packageName
15693                        + " does not have a signature matching the target "
15694                        + ii.targetPackage;
15695                reportStartInstrumentationFailure(watcher, className, msg);
15696                throw new SecurityException(msg);
15697            }
15698
15699            final long origId = Binder.clearCallingIdentity();
15700            // Instrumentation can kill and relaunch even persistent processes
15701            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15702                    "start instr");
15703            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15704            app.instrumentationClass = className;
15705            app.instrumentationInfo = ai;
15706            app.instrumentationProfileFile = profileFile;
15707            app.instrumentationArguments = arguments;
15708            app.instrumentationWatcher = watcher;
15709            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15710            app.instrumentationResultClass = className;
15711            Binder.restoreCallingIdentity(origId);
15712        }
15713
15714        return true;
15715    }
15716
15717    /**
15718     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15719     * error to the logs, but if somebody is watching, send the report there too.  This enables
15720     * the "am" command to report errors with more information.
15721     *
15722     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15723     * @param cn The component name of the instrumentation.
15724     * @param report The error report.
15725     */
15726    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15727            ComponentName cn, String report) {
15728        Slog.w(TAG, report);
15729        try {
15730            if (watcher != null) {
15731                Bundle results = new Bundle();
15732                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15733                results.putString("Error", report);
15734                watcher.instrumentationStatus(cn, -1, results);
15735            }
15736        } catch (RemoteException e) {
15737            Slog.w(TAG, e);
15738        }
15739    }
15740
15741    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15742        if (app.instrumentationWatcher != null) {
15743            try {
15744                // NOTE:  IInstrumentationWatcher *must* be oneway here
15745                app.instrumentationWatcher.instrumentationFinished(
15746                    app.instrumentationClass,
15747                    resultCode,
15748                    results);
15749            } catch (RemoteException e) {
15750            }
15751        }
15752        if (app.instrumentationUiAutomationConnection != null) {
15753            try {
15754                app.instrumentationUiAutomationConnection.shutdown();
15755            } catch (RemoteException re) {
15756                /* ignore */
15757            }
15758            // Only a UiAutomation can set this flag and now that
15759            // it is finished we make sure it is reset to its default.
15760            mUserIsMonkey = false;
15761        }
15762        app.instrumentationWatcher = null;
15763        app.instrumentationUiAutomationConnection = null;
15764        app.instrumentationClass = null;
15765        app.instrumentationInfo = null;
15766        app.instrumentationProfileFile = null;
15767        app.instrumentationArguments = null;
15768
15769        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15770                "finished inst");
15771    }
15772
15773    public void finishInstrumentation(IApplicationThread target,
15774            int resultCode, Bundle results) {
15775        int userId = UserHandle.getCallingUserId();
15776        // Refuse possible leaked file descriptors
15777        if (results != null && results.hasFileDescriptors()) {
15778            throw new IllegalArgumentException("File descriptors passed in Intent");
15779        }
15780
15781        synchronized(this) {
15782            ProcessRecord app = getRecordForAppLocked(target);
15783            if (app == null) {
15784                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15785                return;
15786            }
15787            final long origId = Binder.clearCallingIdentity();
15788            finishInstrumentationLocked(app, resultCode, results);
15789            Binder.restoreCallingIdentity(origId);
15790        }
15791    }
15792
15793    // =========================================================
15794    // CONFIGURATION
15795    // =========================================================
15796
15797    public ConfigurationInfo getDeviceConfigurationInfo() {
15798        ConfigurationInfo config = new ConfigurationInfo();
15799        synchronized (this) {
15800            config.reqTouchScreen = mConfiguration.touchscreen;
15801            config.reqKeyboardType = mConfiguration.keyboard;
15802            config.reqNavigation = mConfiguration.navigation;
15803            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15804                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15805                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15806            }
15807            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15808                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15809                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15810            }
15811            config.reqGlEsVersion = GL_ES_VERSION;
15812        }
15813        return config;
15814    }
15815
15816    ActivityStack getFocusedStack() {
15817        return mStackSupervisor.getFocusedStack();
15818    }
15819
15820    public Configuration getConfiguration() {
15821        Configuration ci;
15822        synchronized(this) {
15823            ci = new Configuration(mConfiguration);
15824        }
15825        return ci;
15826    }
15827
15828    public void updatePersistentConfiguration(Configuration values) {
15829        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15830                "updateConfiguration()");
15831        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15832                "updateConfiguration()");
15833        if (values == null) {
15834            throw new NullPointerException("Configuration must not be null");
15835        }
15836
15837        synchronized(this) {
15838            final long origId = Binder.clearCallingIdentity();
15839            updateConfigurationLocked(values, null, true, false);
15840            Binder.restoreCallingIdentity(origId);
15841        }
15842    }
15843
15844    public void updateConfiguration(Configuration values) {
15845        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15846                "updateConfiguration()");
15847
15848        synchronized(this) {
15849            if (values == null && mWindowManager != null) {
15850                // sentinel: fetch the current configuration from the window manager
15851                values = mWindowManager.computeNewConfiguration();
15852            }
15853
15854            if (mWindowManager != null) {
15855                mProcessList.applyDisplaySize(mWindowManager);
15856            }
15857
15858            final long origId = Binder.clearCallingIdentity();
15859            if (values != null) {
15860                Settings.System.clearConfiguration(values);
15861            }
15862            updateConfigurationLocked(values, null, false, false);
15863            Binder.restoreCallingIdentity(origId);
15864        }
15865    }
15866
15867    /**
15868     * Do either or both things: (1) change the current configuration, and (2)
15869     * make sure the given activity is running with the (now) current
15870     * configuration.  Returns true if the activity has been left running, or
15871     * false if <var>starting</var> is being destroyed to match the new
15872     * configuration.
15873     * @param persistent TODO
15874     */
15875    boolean updateConfigurationLocked(Configuration values,
15876            ActivityRecord starting, boolean persistent, boolean initLocale) {
15877        int changes = 0;
15878
15879        if (values != null) {
15880            Configuration newConfig = new Configuration(mConfiguration);
15881            changes = newConfig.updateFrom(values);
15882            if (changes != 0) {
15883                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15884                    Slog.i(TAG, "Updating configuration to: " + values);
15885                }
15886
15887                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15888
15889                if (values.locale != null && !initLocale) {
15890                    saveLocaleLocked(values.locale,
15891                                     !values.locale.equals(mConfiguration.locale),
15892                                     values.userSetLocale);
15893                }
15894
15895                mConfigurationSeq++;
15896                if (mConfigurationSeq <= 0) {
15897                    mConfigurationSeq = 1;
15898                }
15899                newConfig.seq = mConfigurationSeq;
15900                mConfiguration = newConfig;
15901                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15902                //mUsageStatsService.noteStartConfig(newConfig);
15903
15904                final Configuration configCopy = new Configuration(mConfiguration);
15905
15906                // TODO: If our config changes, should we auto dismiss any currently
15907                // showing dialogs?
15908                mShowDialogs = shouldShowDialogs(newConfig);
15909
15910                AttributeCache ac = AttributeCache.instance();
15911                if (ac != null) {
15912                    ac.updateConfiguration(configCopy);
15913                }
15914
15915                // Make sure all resources in our process are updated
15916                // right now, so that anyone who is going to retrieve
15917                // resource values after we return will be sure to get
15918                // the new ones.  This is especially important during
15919                // boot, where the first config change needs to guarantee
15920                // all resources have that config before following boot
15921                // code is executed.
15922                mSystemThread.applyConfigurationToResources(configCopy);
15923
15924                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15925                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15926                    msg.obj = new Configuration(configCopy);
15927                    mHandler.sendMessage(msg);
15928                }
15929
15930                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15931                    ProcessRecord app = mLruProcesses.get(i);
15932                    try {
15933                        if (app.thread != null) {
15934                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15935                                    + app.processName + " new config " + mConfiguration);
15936                            app.thread.scheduleConfigurationChanged(configCopy);
15937                        }
15938                    } catch (Exception e) {
15939                    }
15940                }
15941                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15942                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15943                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15944                        | Intent.FLAG_RECEIVER_FOREGROUND);
15945                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15946                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15947                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15948                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15949                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15950                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15951                    broadcastIntentLocked(null, null, intent,
15952                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15953                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15954                }
15955            }
15956        }
15957
15958        boolean kept = true;
15959        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15960        // mainStack is null during startup.
15961        if (mainStack != null) {
15962            if (changes != 0 && starting == null) {
15963                // If the configuration changed, and the caller is not already
15964                // in the process of starting an activity, then find the top
15965                // activity to check if its configuration needs to change.
15966                starting = mainStack.topRunningActivityLocked(null);
15967            }
15968
15969            if (starting != null) {
15970                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15971                // And we need to make sure at this point that all other activities
15972                // are made visible with the correct configuration.
15973                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15974            }
15975        }
15976
15977        if (values != null && mWindowManager != null) {
15978            mWindowManager.setNewConfiguration(mConfiguration);
15979        }
15980
15981        return kept;
15982    }
15983
15984    /**
15985     * Decide based on the configuration whether we should shouw the ANR,
15986     * crash, etc dialogs.  The idea is that if there is no affordnace to
15987     * press the on-screen buttons, we shouldn't show the dialog.
15988     *
15989     * A thought: SystemUI might also want to get told about this, the Power
15990     * dialog / global actions also might want different behaviors.
15991     */
15992    private static final boolean shouldShowDialogs(Configuration config) {
15993        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15994                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15995    }
15996
15997    /**
15998     * Save the locale.  You must be inside a synchronized (this) block.
15999     */
16000    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16001        if(isDiff) {
16002            SystemProperties.set("user.language", l.getLanguage());
16003            SystemProperties.set("user.region", l.getCountry());
16004        }
16005
16006        if(isPersist) {
16007            SystemProperties.set("persist.sys.language", l.getLanguage());
16008            SystemProperties.set("persist.sys.country", l.getCountry());
16009            SystemProperties.set("persist.sys.localevar", l.getVariant());
16010        }
16011    }
16012
16013    @Override
16014    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16015        synchronized (this) {
16016            ActivityRecord srec = ActivityRecord.forToken(token);
16017            if (srec.task != null && srec.task.stack != null) {
16018                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16019            }
16020        }
16021        return false;
16022    }
16023
16024    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16025            Intent resultData) {
16026
16027        synchronized (this) {
16028            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16029            if (stack != null) {
16030                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16031            }
16032            return false;
16033        }
16034    }
16035
16036    public int getLaunchedFromUid(IBinder activityToken) {
16037        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16038        if (srec == null) {
16039            return -1;
16040        }
16041        return srec.launchedFromUid;
16042    }
16043
16044    public String getLaunchedFromPackage(IBinder activityToken) {
16045        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16046        if (srec == null) {
16047            return null;
16048        }
16049        return srec.launchedFromPackage;
16050    }
16051
16052    // =========================================================
16053    // LIFETIME MANAGEMENT
16054    // =========================================================
16055
16056    // Returns which broadcast queue the app is the current [or imminent] receiver
16057    // on, or 'null' if the app is not an active broadcast recipient.
16058    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16059        BroadcastRecord r = app.curReceiver;
16060        if (r != null) {
16061            return r.queue;
16062        }
16063
16064        // It's not the current receiver, but it might be starting up to become one
16065        synchronized (this) {
16066            for (BroadcastQueue queue : mBroadcastQueues) {
16067                r = queue.mPendingBroadcast;
16068                if (r != null && r.curApp == app) {
16069                    // found it; report which queue it's in
16070                    return queue;
16071                }
16072            }
16073        }
16074
16075        return null;
16076    }
16077
16078    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16079            boolean doingAll, long now) {
16080        if (mAdjSeq == app.adjSeq) {
16081            // This adjustment has already been computed.
16082            return app.curRawAdj;
16083        }
16084
16085        if (app.thread == null) {
16086            app.adjSeq = mAdjSeq;
16087            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16088            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16089            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16090        }
16091
16092        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16093        app.adjSource = null;
16094        app.adjTarget = null;
16095        app.empty = false;
16096        app.cached = false;
16097
16098        final int activitiesSize = app.activities.size();
16099
16100        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16101            // The max adjustment doesn't allow this app to be anything
16102            // below foreground, so it is not worth doing work for it.
16103            app.adjType = "fixed";
16104            app.adjSeq = mAdjSeq;
16105            app.curRawAdj = app.maxAdj;
16106            app.foregroundActivities = false;
16107            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16108            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16109            // System processes can do UI, and when they do we want to have
16110            // them trim their memory after the user leaves the UI.  To
16111            // facilitate this, here we need to determine whether or not it
16112            // is currently showing UI.
16113            app.systemNoUi = true;
16114            if (app == TOP_APP) {
16115                app.systemNoUi = false;
16116            } else if (activitiesSize > 0) {
16117                for (int j = 0; j < activitiesSize; j++) {
16118                    final ActivityRecord r = app.activities.get(j);
16119                    if (r.visible) {
16120                        app.systemNoUi = false;
16121                    }
16122                }
16123            }
16124            if (!app.systemNoUi) {
16125                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16126            }
16127            return (app.curAdj=app.maxAdj);
16128        }
16129
16130        app.systemNoUi = false;
16131
16132        // Determine the importance of the process, starting with most
16133        // important to least, and assign an appropriate OOM adjustment.
16134        int adj;
16135        int schedGroup;
16136        int procState;
16137        boolean foregroundActivities = false;
16138        BroadcastQueue queue;
16139        if (app == TOP_APP) {
16140            // The last app on the list is the foreground app.
16141            adj = ProcessList.FOREGROUND_APP_ADJ;
16142            schedGroup = Process.THREAD_GROUP_DEFAULT;
16143            app.adjType = "top-activity";
16144            foregroundActivities = true;
16145            procState = ActivityManager.PROCESS_STATE_TOP;
16146        } else if (app.instrumentationClass != null) {
16147            // Don't want to kill running instrumentation.
16148            adj = ProcessList.FOREGROUND_APP_ADJ;
16149            schedGroup = Process.THREAD_GROUP_DEFAULT;
16150            app.adjType = "instrumentation";
16151            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16152        } else if ((queue = isReceivingBroadcast(app)) != null) {
16153            // An app that is currently receiving a broadcast also
16154            // counts as being in the foreground for OOM killer purposes.
16155            // It's placed in a sched group based on the nature of the
16156            // broadcast as reflected by which queue it's active in.
16157            adj = ProcessList.FOREGROUND_APP_ADJ;
16158            schedGroup = (queue == mFgBroadcastQueue)
16159                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16160            app.adjType = "broadcast";
16161            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16162        } else if (app.executingServices.size() > 0) {
16163            // An app that is currently executing a service callback also
16164            // counts as being in the foreground.
16165            adj = ProcessList.FOREGROUND_APP_ADJ;
16166            schedGroup = app.execServicesFg ?
16167                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16168            app.adjType = "exec-service";
16169            procState = ActivityManager.PROCESS_STATE_SERVICE;
16170            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16171        } else {
16172            // As far as we know the process is empty.  We may change our mind later.
16173            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16174            // At this point we don't actually know the adjustment.  Use the cached adj
16175            // value that the caller wants us to.
16176            adj = cachedAdj;
16177            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16178            app.cached = true;
16179            app.empty = true;
16180            app.adjType = "cch-empty";
16181        }
16182
16183        // Examine all activities if not already foreground.
16184        if (!foregroundActivities && activitiesSize > 0) {
16185            for (int j = 0; j < activitiesSize; j++) {
16186                final ActivityRecord r = app.activities.get(j);
16187                if (r.app != app) {
16188                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16189                            + app + "?!?");
16190                    continue;
16191                }
16192                if (r.visible) {
16193                    // App has a visible activity; only upgrade adjustment.
16194                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16195                        adj = ProcessList.VISIBLE_APP_ADJ;
16196                        app.adjType = "visible";
16197                    }
16198                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16199                        procState = ActivityManager.PROCESS_STATE_TOP;
16200                    }
16201                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16202                    app.cached = false;
16203                    app.empty = false;
16204                    foregroundActivities = true;
16205                    break;
16206                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16207                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16208                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16209                        app.adjType = "pausing";
16210                    }
16211                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16212                        procState = ActivityManager.PROCESS_STATE_TOP;
16213                    }
16214                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16215                    app.cached = false;
16216                    app.empty = false;
16217                    foregroundActivities = true;
16218                } else if (r.state == ActivityState.STOPPING) {
16219                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16220                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16221                        app.adjType = "stopping";
16222                    }
16223                    // For the process state, we will at this point consider the
16224                    // process to be cached.  It will be cached either as an activity
16225                    // or empty depending on whether the activity is finishing.  We do
16226                    // this so that we can treat the process as cached for purposes of
16227                    // memory trimming (determing current memory level, trim command to
16228                    // send to process) since there can be an arbitrary number of stopping
16229                    // processes and they should soon all go into the cached state.
16230                    if (!r.finishing) {
16231                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16232                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16233                        }
16234                    }
16235                    app.cached = false;
16236                    app.empty = false;
16237                    foregroundActivities = true;
16238                } else {
16239                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16240                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16241                        app.adjType = "cch-act";
16242                    }
16243                }
16244            }
16245        }
16246
16247        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16248            if (app.foregroundServices) {
16249                // The user is aware of this app, so make it visible.
16250                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16251                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16252                app.cached = false;
16253                app.adjType = "fg-service";
16254                schedGroup = Process.THREAD_GROUP_DEFAULT;
16255            } else if (app.forcingToForeground != null) {
16256                // The user is aware of this app, so make it visible.
16257                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16258                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16259                app.cached = false;
16260                app.adjType = "force-fg";
16261                app.adjSource = app.forcingToForeground;
16262                schedGroup = Process.THREAD_GROUP_DEFAULT;
16263            }
16264        }
16265
16266        if (app == mHeavyWeightProcess) {
16267            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16268                // We don't want to kill the current heavy-weight process.
16269                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16270                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16271                app.cached = false;
16272                app.adjType = "heavy";
16273            }
16274            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16275                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16276            }
16277        }
16278
16279        if (app == mHomeProcess) {
16280            if (adj > ProcessList.HOME_APP_ADJ) {
16281                // This process is hosting what we currently consider to be the
16282                // home app, so we don't want to let it go into the background.
16283                adj = ProcessList.HOME_APP_ADJ;
16284                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16285                app.cached = false;
16286                app.adjType = "home";
16287            }
16288            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16289                procState = ActivityManager.PROCESS_STATE_HOME;
16290            }
16291        }
16292
16293        if (app == mPreviousProcess && app.activities.size() > 0) {
16294            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16295                // This was the previous process that showed UI to the user.
16296                // We want to try to keep it around more aggressively, to give
16297                // a good experience around switching between two apps.
16298                adj = ProcessList.PREVIOUS_APP_ADJ;
16299                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16300                app.cached = false;
16301                app.adjType = "previous";
16302            }
16303            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16304                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16305            }
16306        }
16307
16308        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16309                + " reason=" + app.adjType);
16310
16311        // By default, we use the computed adjustment.  It may be changed if
16312        // there are applications dependent on our services or providers, but
16313        // this gives us a baseline and makes sure we don't get into an
16314        // infinite recursion.
16315        app.adjSeq = mAdjSeq;
16316        app.curRawAdj = adj;
16317        app.hasStartedServices = false;
16318
16319        if (mBackupTarget != null && app == mBackupTarget.app) {
16320            // If possible we want to avoid killing apps while they're being backed up
16321            if (adj > ProcessList.BACKUP_APP_ADJ) {
16322                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16323                adj = ProcessList.BACKUP_APP_ADJ;
16324                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16325                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16326                }
16327                app.adjType = "backup";
16328                app.cached = false;
16329            }
16330            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16331                procState = ActivityManager.PROCESS_STATE_BACKUP;
16332            }
16333        }
16334
16335        boolean mayBeTop = false;
16336
16337        for (int is = app.services.size()-1;
16338                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16339                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16340                        || procState > ActivityManager.PROCESS_STATE_TOP);
16341                is--) {
16342            ServiceRecord s = app.services.valueAt(is);
16343            if (s.startRequested) {
16344                app.hasStartedServices = true;
16345                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16346                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16347                }
16348                if (app.hasShownUi && app != mHomeProcess) {
16349                    // If this process has shown some UI, let it immediately
16350                    // go to the LRU list because it may be pretty heavy with
16351                    // UI stuff.  We'll tag it with a label just to help
16352                    // debug and understand what is going on.
16353                    if (adj > ProcessList.SERVICE_ADJ) {
16354                        app.adjType = "cch-started-ui-services";
16355                    }
16356                } else {
16357                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16358                        // This service has seen some activity within
16359                        // recent memory, so we will keep its process ahead
16360                        // of the background processes.
16361                        if (adj > ProcessList.SERVICE_ADJ) {
16362                            adj = ProcessList.SERVICE_ADJ;
16363                            app.adjType = "started-services";
16364                            app.cached = false;
16365                        }
16366                    }
16367                    // If we have let the service slide into the background
16368                    // state, still have some text describing what it is doing
16369                    // even though the service no longer has an impact.
16370                    if (adj > ProcessList.SERVICE_ADJ) {
16371                        app.adjType = "cch-started-services";
16372                    }
16373                }
16374            }
16375            for (int conni = s.connections.size()-1;
16376                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16377                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16378                            || procState > ActivityManager.PROCESS_STATE_TOP);
16379                    conni--) {
16380                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16381                for (int i = 0;
16382                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16383                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16384                                || procState > ActivityManager.PROCESS_STATE_TOP);
16385                        i++) {
16386                    // XXX should compute this based on the max of
16387                    // all connected clients.
16388                    ConnectionRecord cr = clist.get(i);
16389                    if (cr.binding.client == app) {
16390                        // Binding to ourself is not interesting.
16391                        continue;
16392                    }
16393                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16394                        ProcessRecord client = cr.binding.client;
16395                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16396                                TOP_APP, doingAll, now);
16397                        int clientProcState = client.curProcState;
16398                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16399                            // If the other app is cached for any reason, for purposes here
16400                            // we are going to consider it empty.  The specific cached state
16401                            // doesn't propagate except under certain conditions.
16402                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16403                        }
16404                        String adjType = null;
16405                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16406                            // Not doing bind OOM management, so treat
16407                            // this guy more like a started service.
16408                            if (app.hasShownUi && app != mHomeProcess) {
16409                                // If this process has shown some UI, let it immediately
16410                                // go to the LRU list because it may be pretty heavy with
16411                                // UI stuff.  We'll tag it with a label just to help
16412                                // debug and understand what is going on.
16413                                if (adj > clientAdj) {
16414                                    adjType = "cch-bound-ui-services";
16415                                }
16416                                app.cached = false;
16417                                clientAdj = adj;
16418                                clientProcState = procState;
16419                            } else {
16420                                if (now >= (s.lastActivity
16421                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16422                                    // This service has not seen activity within
16423                                    // recent memory, so allow it to drop to the
16424                                    // LRU list if there is no other reason to keep
16425                                    // it around.  We'll also tag it with a label just
16426                                    // to help debug and undertand what is going on.
16427                                    if (adj > clientAdj) {
16428                                        adjType = "cch-bound-services";
16429                                    }
16430                                    clientAdj = adj;
16431                                }
16432                            }
16433                        }
16434                        if (adj > clientAdj) {
16435                            // If this process has recently shown UI, and
16436                            // the process that is binding to it is less
16437                            // important than being visible, then we don't
16438                            // care about the binding as much as we care
16439                            // about letting this process get into the LRU
16440                            // list to be killed and restarted if needed for
16441                            // memory.
16442                            if (app.hasShownUi && app != mHomeProcess
16443                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16444                                adjType = "cch-bound-ui-services";
16445                            } else {
16446                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16447                                        |Context.BIND_IMPORTANT)) != 0) {
16448                                    adj = clientAdj;
16449                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16450                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16451                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16452                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16453                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16454                                    adj = clientAdj;
16455                                } else {
16456                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16457                                        adj = ProcessList.VISIBLE_APP_ADJ;
16458                                    }
16459                                }
16460                                if (!client.cached) {
16461                                    app.cached = false;
16462                                }
16463                                adjType = "service";
16464                            }
16465                        }
16466                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16467                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16468                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16469                            }
16470                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16471                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16472                                    // Special handling of clients who are in the top state.
16473                                    // We *may* want to consider this process to be in the
16474                                    // top state as well, but only if there is not another
16475                                    // reason for it to be running.  Being on the top is a
16476                                    // special state, meaning you are specifically running
16477                                    // for the current top app.  If the process is already
16478                                    // running in the background for some other reason, it
16479                                    // is more important to continue considering it to be
16480                                    // in the background state.
16481                                    mayBeTop = true;
16482                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16483                                } else {
16484                                    // Special handling for above-top states (persistent
16485                                    // processes).  These should not bring the current process
16486                                    // into the top state, since they are not on top.  Instead
16487                                    // give them the best state after that.
16488                                    clientProcState =
16489                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16490                                }
16491                            }
16492                        } else {
16493                            if (clientProcState <
16494                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16495                                clientProcState =
16496                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16497                            }
16498                        }
16499                        if (procState > clientProcState) {
16500                            procState = clientProcState;
16501                        }
16502                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16503                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16504                            app.pendingUiClean = true;
16505                        }
16506                        if (adjType != null) {
16507                            app.adjType = adjType;
16508                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16509                                    .REASON_SERVICE_IN_USE;
16510                            app.adjSource = cr.binding.client;
16511                            app.adjSourceProcState = clientProcState;
16512                            app.adjTarget = s.name;
16513                        }
16514                    }
16515                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16516                        app.treatLikeActivity = true;
16517                    }
16518                    final ActivityRecord a = cr.activity;
16519                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16520                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16521                                (a.visible || a.state == ActivityState.RESUMED
16522                                 || a.state == ActivityState.PAUSING)) {
16523                            adj = ProcessList.FOREGROUND_APP_ADJ;
16524                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16525                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16526                            }
16527                            app.cached = false;
16528                            app.adjType = "service";
16529                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16530                                    .REASON_SERVICE_IN_USE;
16531                            app.adjSource = a;
16532                            app.adjSourceProcState = procState;
16533                            app.adjTarget = s.name;
16534                        }
16535                    }
16536                }
16537            }
16538        }
16539
16540        for (int provi = app.pubProviders.size()-1;
16541                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16542                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16543                        || procState > ActivityManager.PROCESS_STATE_TOP);
16544                provi--) {
16545            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16546            for (int i = cpr.connections.size()-1;
16547                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16548                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16549                            || procState > ActivityManager.PROCESS_STATE_TOP);
16550                    i--) {
16551                ContentProviderConnection conn = cpr.connections.get(i);
16552                ProcessRecord client = conn.client;
16553                if (client == app) {
16554                    // Being our own client is not interesting.
16555                    continue;
16556                }
16557                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16558                int clientProcState = client.curProcState;
16559                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16560                    // If the other app is cached for any reason, for purposes here
16561                    // we are going to consider it empty.
16562                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16563                }
16564                if (adj > clientAdj) {
16565                    if (app.hasShownUi && app != mHomeProcess
16566                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16567                        app.adjType = "cch-ui-provider";
16568                    } else {
16569                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16570                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16571                        app.adjType = "provider";
16572                    }
16573                    app.cached &= client.cached;
16574                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16575                            .REASON_PROVIDER_IN_USE;
16576                    app.adjSource = client;
16577                    app.adjSourceProcState = clientProcState;
16578                    app.adjTarget = cpr.name;
16579                }
16580                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16581                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16582                        // Special handling of clients who are in the top state.
16583                        // We *may* want to consider this process to be in the
16584                        // top state as well, but only if there is not another
16585                        // reason for it to be running.  Being on the top is a
16586                        // special state, meaning you are specifically running
16587                        // for the current top app.  If the process is already
16588                        // running in the background for some other reason, it
16589                        // is more important to continue considering it to be
16590                        // in the background state.
16591                        mayBeTop = true;
16592                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16593                    } else {
16594                        // Special handling for above-top states (persistent
16595                        // processes).  These should not bring the current process
16596                        // into the top state, since they are not on top.  Instead
16597                        // give them the best state after that.
16598                        clientProcState =
16599                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16600                    }
16601                }
16602                if (procState > clientProcState) {
16603                    procState = clientProcState;
16604                }
16605                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16606                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16607                }
16608            }
16609            // If the provider has external (non-framework) process
16610            // dependencies, ensure that its adjustment is at least
16611            // FOREGROUND_APP_ADJ.
16612            if (cpr.hasExternalProcessHandles()) {
16613                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16614                    adj = ProcessList.FOREGROUND_APP_ADJ;
16615                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16616                    app.cached = false;
16617                    app.adjType = "provider";
16618                    app.adjTarget = cpr.name;
16619                }
16620                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16621                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16622                }
16623            }
16624        }
16625
16626        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16627            // A client of one of our services or providers is in the top state.  We
16628            // *may* want to be in the top state, but not if we are already running in
16629            // the background for some other reason.  For the decision here, we are going
16630            // to pick out a few specific states that we want to remain in when a client
16631            // is top (states that tend to be longer-term) and otherwise allow it to go
16632            // to the top state.
16633            switch (procState) {
16634                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16635                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16636                case ActivityManager.PROCESS_STATE_SERVICE:
16637                    // These all are longer-term states, so pull them up to the top
16638                    // of the background states, but not all the way to the top state.
16639                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16640                    break;
16641                default:
16642                    // Otherwise, top is a better choice, so take it.
16643                    procState = ActivityManager.PROCESS_STATE_TOP;
16644                    break;
16645            }
16646        }
16647
16648        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16649            if (app.hasClientActivities) {
16650                // This is a cached process, but with client activities.  Mark it so.
16651                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16652                app.adjType = "cch-client-act";
16653            } else if (app.treatLikeActivity) {
16654                // This is a cached process, but somebody wants us to treat it like it has
16655                // an activity, okay!
16656                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16657                app.adjType = "cch-as-act";
16658            }
16659        }
16660
16661        if (adj == ProcessList.SERVICE_ADJ) {
16662            if (doingAll) {
16663                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16664                mNewNumServiceProcs++;
16665                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16666                if (!app.serviceb) {
16667                    // This service isn't far enough down on the LRU list to
16668                    // normally be a B service, but if we are low on RAM and it
16669                    // is large we want to force it down since we would prefer to
16670                    // keep launcher over it.
16671                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16672                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16673                        app.serviceHighRam = true;
16674                        app.serviceb = true;
16675                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16676                    } else {
16677                        mNewNumAServiceProcs++;
16678                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16679                    }
16680                } else {
16681                    app.serviceHighRam = false;
16682                }
16683            }
16684            if (app.serviceb) {
16685                adj = ProcessList.SERVICE_B_ADJ;
16686            }
16687        }
16688
16689        app.curRawAdj = adj;
16690
16691        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16692        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16693        if (adj > app.maxAdj) {
16694            adj = app.maxAdj;
16695            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16696                schedGroup = Process.THREAD_GROUP_DEFAULT;
16697            }
16698        }
16699
16700        // Do final modification to adj.  Everything we do between here and applying
16701        // the final setAdj must be done in this function, because we will also use
16702        // it when computing the final cached adj later.  Note that we don't need to
16703        // worry about this for max adj above, since max adj will always be used to
16704        // keep it out of the cached vaues.
16705        app.curAdj = app.modifyRawOomAdj(adj);
16706        app.curSchedGroup = schedGroup;
16707        app.curProcState = procState;
16708        app.foregroundActivities = foregroundActivities;
16709
16710        return app.curRawAdj;
16711    }
16712
16713    /**
16714     * Schedule PSS collection of a process.
16715     */
16716    void requestPssLocked(ProcessRecord proc, int procState) {
16717        if (mPendingPssProcesses.contains(proc)) {
16718            return;
16719        }
16720        if (mPendingPssProcesses.size() == 0) {
16721            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16722        }
16723        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16724        proc.pssProcState = procState;
16725        mPendingPssProcesses.add(proc);
16726    }
16727
16728    /**
16729     * Schedule PSS collection of all processes.
16730     */
16731    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16732        if (!always) {
16733            if (now < (mLastFullPssTime +
16734                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16735                return;
16736            }
16737        }
16738        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16739        mLastFullPssTime = now;
16740        mFullPssPending = true;
16741        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16742        mPendingPssProcesses.clear();
16743        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16744            ProcessRecord app = mLruProcesses.get(i);
16745            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16746                app.pssProcState = app.setProcState;
16747                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16748                        isSleeping(), now);
16749                mPendingPssProcesses.add(app);
16750            }
16751        }
16752        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16753    }
16754
16755    /**
16756     * Ask a given process to GC right now.
16757     */
16758    final void performAppGcLocked(ProcessRecord app) {
16759        try {
16760            app.lastRequestedGc = SystemClock.uptimeMillis();
16761            if (app.thread != null) {
16762                if (app.reportLowMemory) {
16763                    app.reportLowMemory = false;
16764                    app.thread.scheduleLowMemory();
16765                } else {
16766                    app.thread.processInBackground();
16767                }
16768            }
16769        } catch (Exception e) {
16770            // whatever.
16771        }
16772    }
16773
16774    /**
16775     * Returns true if things are idle enough to perform GCs.
16776     */
16777    private final boolean canGcNowLocked() {
16778        boolean processingBroadcasts = false;
16779        for (BroadcastQueue q : mBroadcastQueues) {
16780            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16781                processingBroadcasts = true;
16782            }
16783        }
16784        return !processingBroadcasts
16785                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16786    }
16787
16788    /**
16789     * Perform GCs on all processes that are waiting for it, but only
16790     * if things are idle.
16791     */
16792    final void performAppGcsLocked() {
16793        final int N = mProcessesToGc.size();
16794        if (N <= 0) {
16795            return;
16796        }
16797        if (canGcNowLocked()) {
16798            while (mProcessesToGc.size() > 0) {
16799                ProcessRecord proc = mProcessesToGc.remove(0);
16800                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16801                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16802                            <= SystemClock.uptimeMillis()) {
16803                        // To avoid spamming the system, we will GC processes one
16804                        // at a time, waiting a few seconds between each.
16805                        performAppGcLocked(proc);
16806                        scheduleAppGcsLocked();
16807                        return;
16808                    } else {
16809                        // It hasn't been long enough since we last GCed this
16810                        // process...  put it in the list to wait for its time.
16811                        addProcessToGcListLocked(proc);
16812                        break;
16813                    }
16814                }
16815            }
16816
16817            scheduleAppGcsLocked();
16818        }
16819    }
16820
16821    /**
16822     * If all looks good, perform GCs on all processes waiting for them.
16823     */
16824    final void performAppGcsIfAppropriateLocked() {
16825        if (canGcNowLocked()) {
16826            performAppGcsLocked();
16827            return;
16828        }
16829        // Still not idle, wait some more.
16830        scheduleAppGcsLocked();
16831    }
16832
16833    /**
16834     * Schedule the execution of all pending app GCs.
16835     */
16836    final void scheduleAppGcsLocked() {
16837        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16838
16839        if (mProcessesToGc.size() > 0) {
16840            // Schedule a GC for the time to the next process.
16841            ProcessRecord proc = mProcessesToGc.get(0);
16842            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16843
16844            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16845            long now = SystemClock.uptimeMillis();
16846            if (when < (now+GC_TIMEOUT)) {
16847                when = now + GC_TIMEOUT;
16848            }
16849            mHandler.sendMessageAtTime(msg, when);
16850        }
16851    }
16852
16853    /**
16854     * Add a process to the array of processes waiting to be GCed.  Keeps the
16855     * list in sorted order by the last GC time.  The process can't already be
16856     * on the list.
16857     */
16858    final void addProcessToGcListLocked(ProcessRecord proc) {
16859        boolean added = false;
16860        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16861            if (mProcessesToGc.get(i).lastRequestedGc <
16862                    proc.lastRequestedGc) {
16863                added = true;
16864                mProcessesToGc.add(i+1, proc);
16865                break;
16866            }
16867        }
16868        if (!added) {
16869            mProcessesToGc.add(0, proc);
16870        }
16871    }
16872
16873    /**
16874     * Set up to ask a process to GC itself.  This will either do it
16875     * immediately, or put it on the list of processes to gc the next
16876     * time things are idle.
16877     */
16878    final void scheduleAppGcLocked(ProcessRecord app) {
16879        long now = SystemClock.uptimeMillis();
16880        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16881            return;
16882        }
16883        if (!mProcessesToGc.contains(app)) {
16884            addProcessToGcListLocked(app);
16885            scheduleAppGcsLocked();
16886        }
16887    }
16888
16889    final void checkExcessivePowerUsageLocked(boolean doKills) {
16890        updateCpuStatsNow();
16891
16892        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16893        boolean doWakeKills = doKills;
16894        boolean doCpuKills = doKills;
16895        if (mLastPowerCheckRealtime == 0) {
16896            doWakeKills = false;
16897        }
16898        if (mLastPowerCheckUptime == 0) {
16899            doCpuKills = false;
16900        }
16901        if (stats.isScreenOn()) {
16902            doWakeKills = false;
16903        }
16904        final long curRealtime = SystemClock.elapsedRealtime();
16905        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16906        final long curUptime = SystemClock.uptimeMillis();
16907        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16908        mLastPowerCheckRealtime = curRealtime;
16909        mLastPowerCheckUptime = curUptime;
16910        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16911            doWakeKills = false;
16912        }
16913        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16914            doCpuKills = false;
16915        }
16916        int i = mLruProcesses.size();
16917        while (i > 0) {
16918            i--;
16919            ProcessRecord app = mLruProcesses.get(i);
16920            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16921                long wtime;
16922                synchronized (stats) {
16923                    wtime = stats.getProcessWakeTime(app.info.uid,
16924                            app.pid, curRealtime);
16925                }
16926                long wtimeUsed = wtime - app.lastWakeTime;
16927                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16928                if (DEBUG_POWER) {
16929                    StringBuilder sb = new StringBuilder(128);
16930                    sb.append("Wake for ");
16931                    app.toShortString(sb);
16932                    sb.append(": over ");
16933                    TimeUtils.formatDuration(realtimeSince, sb);
16934                    sb.append(" used ");
16935                    TimeUtils.formatDuration(wtimeUsed, sb);
16936                    sb.append(" (");
16937                    sb.append((wtimeUsed*100)/realtimeSince);
16938                    sb.append("%)");
16939                    Slog.i(TAG, sb.toString());
16940                    sb.setLength(0);
16941                    sb.append("CPU for ");
16942                    app.toShortString(sb);
16943                    sb.append(": over ");
16944                    TimeUtils.formatDuration(uptimeSince, sb);
16945                    sb.append(" used ");
16946                    TimeUtils.formatDuration(cputimeUsed, sb);
16947                    sb.append(" (");
16948                    sb.append((cputimeUsed*100)/uptimeSince);
16949                    sb.append("%)");
16950                    Slog.i(TAG, sb.toString());
16951                }
16952                // If a process has held a wake lock for more
16953                // than 50% of the time during this period,
16954                // that sounds bad.  Kill!
16955                if (doWakeKills && realtimeSince > 0
16956                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16957                    synchronized (stats) {
16958                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16959                                realtimeSince, wtimeUsed);
16960                    }
16961                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16962                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16963                } else if (doCpuKills && uptimeSince > 0
16964                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16965                    synchronized (stats) {
16966                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16967                                uptimeSince, cputimeUsed);
16968                    }
16969                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16970                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16971                } else {
16972                    app.lastWakeTime = wtime;
16973                    app.lastCpuTime = app.curCpuTime;
16974                }
16975            }
16976        }
16977    }
16978
16979    private final boolean applyOomAdjLocked(ProcessRecord app,
16980            ProcessRecord TOP_APP, boolean doingAll, long now) {
16981        boolean success = true;
16982
16983        if (app.curRawAdj != app.setRawAdj) {
16984            app.setRawAdj = app.curRawAdj;
16985        }
16986
16987        int changes = 0;
16988
16989        if (app.curAdj != app.setAdj) {
16990            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16991            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16992                TAG, "Set " + app.pid + " " + app.processName +
16993                " adj " + app.curAdj + ": " + app.adjType);
16994            app.setAdj = app.curAdj;
16995        }
16996
16997        if (app.setSchedGroup != app.curSchedGroup) {
16998            app.setSchedGroup = app.curSchedGroup;
16999            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17000                    "Setting process group of " + app.processName
17001                    + " to " + app.curSchedGroup);
17002            if (app.waitingToKill != null &&
17003                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17004                app.kill(app.waitingToKill, true);
17005                success = false;
17006            } else {
17007                if (true) {
17008                    long oldId = Binder.clearCallingIdentity();
17009                    try {
17010                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17011                    } catch (Exception e) {
17012                        Slog.w(TAG, "Failed setting process group of " + app.pid
17013                                + " to " + app.curSchedGroup);
17014                        e.printStackTrace();
17015                    } finally {
17016                        Binder.restoreCallingIdentity(oldId);
17017                    }
17018                } else {
17019                    if (app.thread != null) {
17020                        try {
17021                            app.thread.setSchedulingGroup(app.curSchedGroup);
17022                        } catch (RemoteException e) {
17023                        }
17024                    }
17025                }
17026                Process.setSwappiness(app.pid,
17027                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17028            }
17029        }
17030        if (app.repForegroundActivities != app.foregroundActivities) {
17031            app.repForegroundActivities = app.foregroundActivities;
17032            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17033        }
17034        if (app.repProcState != app.curProcState) {
17035            app.repProcState = app.curProcState;
17036            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17037            if (app.thread != null) {
17038                try {
17039                    if (false) {
17040                        //RuntimeException h = new RuntimeException("here");
17041                        Slog.i(TAG, "Sending new process state " + app.repProcState
17042                                + " to " + app /*, h*/);
17043                    }
17044                    app.thread.setProcessState(app.repProcState);
17045                } catch (RemoteException e) {
17046                }
17047            }
17048        }
17049        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17050                app.setProcState)) {
17051            app.lastStateTime = now;
17052            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17053                    isSleeping(), now);
17054            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17055                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17056                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17057                    + (app.nextPssTime-now) + ": " + app);
17058        } else {
17059            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17060                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17061                requestPssLocked(app, app.setProcState);
17062                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17063                        isSleeping(), now);
17064            } else if (false && DEBUG_PSS) {
17065                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17066            }
17067        }
17068        if (app.setProcState != app.curProcState) {
17069            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17070                    "Proc state change of " + app.processName
17071                    + " to " + app.curProcState);
17072            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17073            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17074            if (setImportant && !curImportant) {
17075                // This app is no longer something we consider important enough to allow to
17076                // use arbitrary amounts of battery power.  Note
17077                // its current wake lock time to later know to kill it if
17078                // it is not behaving well.
17079                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17080                synchronized (stats) {
17081                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17082                            app.pid, SystemClock.elapsedRealtime());
17083                }
17084                app.lastCpuTime = app.curCpuTime;
17085
17086            }
17087            app.setProcState = app.curProcState;
17088            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17089                app.notCachedSinceIdle = false;
17090            }
17091            if (!doingAll) {
17092                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17093            } else {
17094                app.procStateChanged = true;
17095            }
17096        }
17097
17098        if (changes != 0) {
17099            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17100            int i = mPendingProcessChanges.size()-1;
17101            ProcessChangeItem item = null;
17102            while (i >= 0) {
17103                item = mPendingProcessChanges.get(i);
17104                if (item.pid == app.pid) {
17105                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17106                    break;
17107                }
17108                i--;
17109            }
17110            if (i < 0) {
17111                // No existing item in pending changes; need a new one.
17112                final int NA = mAvailProcessChanges.size();
17113                if (NA > 0) {
17114                    item = mAvailProcessChanges.remove(NA-1);
17115                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17116                } else {
17117                    item = new ProcessChangeItem();
17118                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17119                }
17120                item.changes = 0;
17121                item.pid = app.pid;
17122                item.uid = app.info.uid;
17123                if (mPendingProcessChanges.size() == 0) {
17124                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17125                            "*** Enqueueing dispatch processes changed!");
17126                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17127                }
17128                mPendingProcessChanges.add(item);
17129            }
17130            item.changes |= changes;
17131            item.processState = app.repProcState;
17132            item.foregroundActivities = app.repForegroundActivities;
17133            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17134                    + Integer.toHexString(System.identityHashCode(item))
17135                    + " " + app.toShortString() + ": changes=" + item.changes
17136                    + " procState=" + item.processState
17137                    + " foreground=" + item.foregroundActivities
17138                    + " type=" + app.adjType + " source=" + app.adjSource
17139                    + " target=" + app.adjTarget);
17140        }
17141
17142        return success;
17143    }
17144
17145    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17146        if (proc.thread != null) {
17147            if (proc.baseProcessTracker != null) {
17148                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17149            }
17150            if (proc.repProcState >= 0) {
17151                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17152                        proc.repProcState);
17153            }
17154        }
17155    }
17156
17157    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17158            ProcessRecord TOP_APP, boolean doingAll, long now) {
17159        if (app.thread == null) {
17160            return false;
17161        }
17162
17163        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17164
17165        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17166    }
17167
17168    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17169            boolean oomAdj) {
17170        if (isForeground != proc.foregroundServices) {
17171            proc.foregroundServices = isForeground;
17172            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17173                    proc.info.uid);
17174            if (isForeground) {
17175                if (curProcs == null) {
17176                    curProcs = new ArrayList<ProcessRecord>();
17177                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17178                }
17179                if (!curProcs.contains(proc)) {
17180                    curProcs.add(proc);
17181                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17182                            proc.info.packageName, proc.info.uid);
17183                }
17184            } else {
17185                if (curProcs != null) {
17186                    if (curProcs.remove(proc)) {
17187                        mBatteryStatsService.noteEvent(
17188                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17189                                proc.info.packageName, proc.info.uid);
17190                        if (curProcs.size() <= 0) {
17191                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17192                        }
17193                    }
17194                }
17195            }
17196            if (oomAdj) {
17197                updateOomAdjLocked();
17198            }
17199        }
17200    }
17201
17202    private final ActivityRecord resumedAppLocked() {
17203        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17204        String pkg;
17205        int uid;
17206        if (act != null) {
17207            pkg = act.packageName;
17208            uid = act.info.applicationInfo.uid;
17209        } else {
17210            pkg = null;
17211            uid = -1;
17212        }
17213        // Has the UID or resumed package name changed?
17214        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17215                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17216            if (mCurResumedPackage != null) {
17217                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17218                        mCurResumedPackage, mCurResumedUid);
17219            }
17220            mCurResumedPackage = pkg;
17221            mCurResumedUid = uid;
17222            if (mCurResumedPackage != null) {
17223                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17224                        mCurResumedPackage, mCurResumedUid);
17225            }
17226        }
17227        return act;
17228    }
17229
17230    final boolean updateOomAdjLocked(ProcessRecord app) {
17231        final ActivityRecord TOP_ACT = resumedAppLocked();
17232        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17233        final boolean wasCached = app.cached;
17234
17235        mAdjSeq++;
17236
17237        // This is the desired cached adjusment we want to tell it to use.
17238        // If our app is currently cached, we know it, and that is it.  Otherwise,
17239        // we don't know it yet, and it needs to now be cached we will then
17240        // need to do a complete oom adj.
17241        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17242                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17243        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17244                SystemClock.uptimeMillis());
17245        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17246            // Changed to/from cached state, so apps after it in the LRU
17247            // list may also be changed.
17248            updateOomAdjLocked();
17249        }
17250        return success;
17251    }
17252
17253    final void updateOomAdjLocked() {
17254        final ActivityRecord TOP_ACT = resumedAppLocked();
17255        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17256        final long now = SystemClock.uptimeMillis();
17257        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17258        final int N = mLruProcesses.size();
17259
17260        if (false) {
17261            RuntimeException e = new RuntimeException();
17262            e.fillInStackTrace();
17263            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17264        }
17265
17266        mAdjSeq++;
17267        mNewNumServiceProcs = 0;
17268        mNewNumAServiceProcs = 0;
17269
17270        final int emptyProcessLimit;
17271        final int cachedProcessLimit;
17272        if (mProcessLimit <= 0) {
17273            emptyProcessLimit = cachedProcessLimit = 0;
17274        } else if (mProcessLimit == 1) {
17275            emptyProcessLimit = 1;
17276            cachedProcessLimit = 0;
17277        } else {
17278            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17279            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17280        }
17281
17282        // Let's determine how many processes we have running vs.
17283        // how many slots we have for background processes; we may want
17284        // to put multiple processes in a slot of there are enough of
17285        // them.
17286        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17287                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17288        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17289        if (numEmptyProcs > cachedProcessLimit) {
17290            // If there are more empty processes than our limit on cached
17291            // processes, then use the cached process limit for the factor.
17292            // This ensures that the really old empty processes get pushed
17293            // down to the bottom, so if we are running low on memory we will
17294            // have a better chance at keeping around more cached processes
17295            // instead of a gazillion empty processes.
17296            numEmptyProcs = cachedProcessLimit;
17297        }
17298        int emptyFactor = numEmptyProcs/numSlots;
17299        if (emptyFactor < 1) emptyFactor = 1;
17300        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17301        if (cachedFactor < 1) cachedFactor = 1;
17302        int stepCached = 0;
17303        int stepEmpty = 0;
17304        int numCached = 0;
17305        int numEmpty = 0;
17306        int numTrimming = 0;
17307
17308        mNumNonCachedProcs = 0;
17309        mNumCachedHiddenProcs = 0;
17310
17311        // First update the OOM adjustment for each of the
17312        // application processes based on their current state.
17313        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17314        int nextCachedAdj = curCachedAdj+1;
17315        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17316        int nextEmptyAdj = curEmptyAdj+2;
17317        for (int i=N-1; i>=0; i--) {
17318            ProcessRecord app = mLruProcesses.get(i);
17319            if (!app.killedByAm && app.thread != null) {
17320                app.procStateChanged = false;
17321                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17322
17323                // If we haven't yet assigned the final cached adj
17324                // to the process, do that now.
17325                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17326                    switch (app.curProcState) {
17327                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17328                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17329                            // This process is a cached process holding activities...
17330                            // assign it the next cached value for that type, and then
17331                            // step that cached level.
17332                            app.curRawAdj = curCachedAdj;
17333                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17334                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17335                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17336                                    + ")");
17337                            if (curCachedAdj != nextCachedAdj) {
17338                                stepCached++;
17339                                if (stepCached >= cachedFactor) {
17340                                    stepCached = 0;
17341                                    curCachedAdj = nextCachedAdj;
17342                                    nextCachedAdj += 2;
17343                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17344                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17345                                    }
17346                                }
17347                            }
17348                            break;
17349                        default:
17350                            // For everything else, assign next empty cached process
17351                            // level and bump that up.  Note that this means that
17352                            // long-running services that have dropped down to the
17353                            // cached level will be treated as empty (since their process
17354                            // state is still as a service), which is what we want.
17355                            app.curRawAdj = curEmptyAdj;
17356                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17357                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17358                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17359                                    + ")");
17360                            if (curEmptyAdj != nextEmptyAdj) {
17361                                stepEmpty++;
17362                                if (stepEmpty >= emptyFactor) {
17363                                    stepEmpty = 0;
17364                                    curEmptyAdj = nextEmptyAdj;
17365                                    nextEmptyAdj += 2;
17366                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17367                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17368                                    }
17369                                }
17370                            }
17371                            break;
17372                    }
17373                }
17374
17375                applyOomAdjLocked(app, TOP_APP, true, now);
17376
17377                // Count the number of process types.
17378                switch (app.curProcState) {
17379                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17380                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17381                        mNumCachedHiddenProcs++;
17382                        numCached++;
17383                        if (numCached > cachedProcessLimit) {
17384                            app.kill("cached #" + numCached, true);
17385                        }
17386                        break;
17387                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17388                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17389                                && app.lastActivityTime < oldTime) {
17390                            app.kill("empty for "
17391                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17392                                    / 1000) + "s", true);
17393                        } else {
17394                            numEmpty++;
17395                            if (numEmpty > emptyProcessLimit) {
17396                                app.kill("empty #" + numEmpty, true);
17397                            }
17398                        }
17399                        break;
17400                    default:
17401                        mNumNonCachedProcs++;
17402                        break;
17403                }
17404
17405                if (app.isolated && app.services.size() <= 0) {
17406                    // If this is an isolated process, and there are no
17407                    // services running in it, then the process is no longer
17408                    // needed.  We agressively kill these because we can by
17409                    // definition not re-use the same process again, and it is
17410                    // good to avoid having whatever code was running in them
17411                    // left sitting around after no longer needed.
17412                    app.kill("isolated not needed", true);
17413                }
17414
17415                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17416                        && !app.killedByAm) {
17417                    numTrimming++;
17418                }
17419            }
17420        }
17421
17422        mNumServiceProcs = mNewNumServiceProcs;
17423
17424        // Now determine the memory trimming level of background processes.
17425        // Unfortunately we need to start at the back of the list to do this
17426        // properly.  We only do this if the number of background apps we
17427        // are managing to keep around is less than half the maximum we desire;
17428        // if we are keeping a good number around, we'll let them use whatever
17429        // memory they want.
17430        final int numCachedAndEmpty = numCached + numEmpty;
17431        int memFactor;
17432        if (numCached <= ProcessList.TRIM_CACHED_APPS
17433                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17434            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17435                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17436            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17437                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17438            } else {
17439                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17440            }
17441        } else {
17442            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17443        }
17444        // We always allow the memory level to go up (better).  We only allow it to go
17445        // down if we are in a state where that is allowed, *and* the total number of processes
17446        // has gone down since last time.
17447        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17448                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17449                + " last=" + mLastNumProcesses);
17450        if (memFactor > mLastMemoryLevel) {
17451            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17452                memFactor = mLastMemoryLevel;
17453                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17454            }
17455        }
17456        mLastMemoryLevel = memFactor;
17457        mLastNumProcesses = mLruProcesses.size();
17458        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17459        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17460        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17461            if (mLowRamStartTime == 0) {
17462                mLowRamStartTime = now;
17463            }
17464            int step = 0;
17465            int fgTrimLevel;
17466            switch (memFactor) {
17467                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17468                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17469                    break;
17470                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17471                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17472                    break;
17473                default:
17474                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17475                    break;
17476            }
17477            int factor = numTrimming/3;
17478            int minFactor = 2;
17479            if (mHomeProcess != null) minFactor++;
17480            if (mPreviousProcess != null) minFactor++;
17481            if (factor < minFactor) factor = minFactor;
17482            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17483            for (int i=N-1; i>=0; i--) {
17484                ProcessRecord app = mLruProcesses.get(i);
17485                if (allChanged || app.procStateChanged) {
17486                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17487                    app.procStateChanged = false;
17488                }
17489                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17490                        && !app.killedByAm) {
17491                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17492                        try {
17493                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17494                                    "Trimming memory of " + app.processName
17495                                    + " to " + curLevel);
17496                            app.thread.scheduleTrimMemory(curLevel);
17497                        } catch (RemoteException e) {
17498                        }
17499                        if (false) {
17500                            // For now we won't do this; our memory trimming seems
17501                            // to be good enough at this point that destroying
17502                            // activities causes more harm than good.
17503                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17504                                    && app != mHomeProcess && app != mPreviousProcess) {
17505                                // Need to do this on its own message because the stack may not
17506                                // be in a consistent state at this point.
17507                                // For these apps we will also finish their activities
17508                                // to help them free memory.
17509                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17510                            }
17511                        }
17512                    }
17513                    app.trimMemoryLevel = curLevel;
17514                    step++;
17515                    if (step >= factor) {
17516                        step = 0;
17517                        switch (curLevel) {
17518                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17519                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17520                                break;
17521                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17522                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17523                                break;
17524                        }
17525                    }
17526                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17527                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17528                            && app.thread != null) {
17529                        try {
17530                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17531                                    "Trimming memory of heavy-weight " + app.processName
17532                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17533                            app.thread.scheduleTrimMemory(
17534                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17535                        } catch (RemoteException e) {
17536                        }
17537                    }
17538                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17539                } else {
17540                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17541                            || app.systemNoUi) && app.pendingUiClean) {
17542                        // If this application is now in the background and it
17543                        // had done UI, then give it the special trim level to
17544                        // have it free UI resources.
17545                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17546                        if (app.trimMemoryLevel < level && app.thread != null) {
17547                            try {
17548                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17549                                        "Trimming memory of bg-ui " + app.processName
17550                                        + " to " + level);
17551                                app.thread.scheduleTrimMemory(level);
17552                            } catch (RemoteException e) {
17553                            }
17554                        }
17555                        app.pendingUiClean = false;
17556                    }
17557                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17558                        try {
17559                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17560                                    "Trimming memory of fg " + app.processName
17561                                    + " to " + fgTrimLevel);
17562                            app.thread.scheduleTrimMemory(fgTrimLevel);
17563                        } catch (RemoteException e) {
17564                        }
17565                    }
17566                    app.trimMemoryLevel = fgTrimLevel;
17567                }
17568            }
17569        } else {
17570            if (mLowRamStartTime != 0) {
17571                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17572                mLowRamStartTime = 0;
17573            }
17574            for (int i=N-1; i>=0; i--) {
17575                ProcessRecord app = mLruProcesses.get(i);
17576                if (allChanged || app.procStateChanged) {
17577                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17578                    app.procStateChanged = false;
17579                }
17580                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17581                        || app.systemNoUi) && app.pendingUiClean) {
17582                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17583                            && app.thread != null) {
17584                        try {
17585                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17586                                    "Trimming memory of ui hidden " + app.processName
17587                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17588                            app.thread.scheduleTrimMemory(
17589                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17590                        } catch (RemoteException e) {
17591                        }
17592                    }
17593                    app.pendingUiClean = false;
17594                }
17595                app.trimMemoryLevel = 0;
17596            }
17597        }
17598
17599        if (mAlwaysFinishActivities) {
17600            // Need to do this on its own message because the stack may not
17601            // be in a consistent state at this point.
17602            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17603        }
17604
17605        if (allChanged) {
17606            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17607        }
17608
17609        if (mProcessStats.shouldWriteNowLocked(now)) {
17610            mHandler.post(new Runnable() {
17611                @Override public void run() {
17612                    synchronized (ActivityManagerService.this) {
17613                        mProcessStats.writeStateAsyncLocked();
17614                    }
17615                }
17616            });
17617        }
17618
17619        if (DEBUG_OOM_ADJ) {
17620            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17621        }
17622    }
17623
17624    final void trimApplications() {
17625        synchronized (this) {
17626            int i;
17627
17628            // First remove any unused application processes whose package
17629            // has been removed.
17630            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17631                final ProcessRecord app = mRemovedProcesses.get(i);
17632                if (app.activities.size() == 0
17633                        && app.curReceiver == null && app.services.size() == 0) {
17634                    Slog.i(
17635                        TAG, "Exiting empty application process "
17636                        + app.processName + " ("
17637                        + (app.thread != null ? app.thread.asBinder() : null)
17638                        + ")\n");
17639                    if (app.pid > 0 && app.pid != MY_PID) {
17640                        app.kill("empty", false);
17641                    } else {
17642                        try {
17643                            app.thread.scheduleExit();
17644                        } catch (Exception e) {
17645                            // Ignore exceptions.
17646                        }
17647                    }
17648                    cleanUpApplicationRecordLocked(app, false, true, -1);
17649                    mRemovedProcesses.remove(i);
17650
17651                    if (app.persistent) {
17652                        addAppLocked(app.info, false, null /* ABI override */);
17653                    }
17654                }
17655            }
17656
17657            // Now update the oom adj for all processes.
17658            updateOomAdjLocked();
17659        }
17660    }
17661
17662    /** This method sends the specified signal to each of the persistent apps */
17663    public void signalPersistentProcesses(int sig) throws RemoteException {
17664        if (sig != Process.SIGNAL_USR1) {
17665            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17666        }
17667
17668        synchronized (this) {
17669            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17670                    != PackageManager.PERMISSION_GRANTED) {
17671                throw new SecurityException("Requires permission "
17672                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17673            }
17674
17675            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17676                ProcessRecord r = mLruProcesses.get(i);
17677                if (r.thread != null && r.persistent) {
17678                    Process.sendSignal(r.pid, sig);
17679                }
17680            }
17681        }
17682    }
17683
17684    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17685        if (proc == null || proc == mProfileProc) {
17686            proc = mProfileProc;
17687            profileType = mProfileType;
17688            clearProfilerLocked();
17689        }
17690        if (proc == null) {
17691            return;
17692        }
17693        try {
17694            proc.thread.profilerControl(false, null, profileType);
17695        } catch (RemoteException e) {
17696            throw new IllegalStateException("Process disappeared");
17697        }
17698    }
17699
17700    private void clearProfilerLocked() {
17701        if (mProfileFd != null) {
17702            try {
17703                mProfileFd.close();
17704            } catch (IOException e) {
17705            }
17706        }
17707        mProfileApp = null;
17708        mProfileProc = null;
17709        mProfileFile = null;
17710        mProfileType = 0;
17711        mAutoStopProfiler = false;
17712        mSamplingInterval = 0;
17713    }
17714
17715    public boolean profileControl(String process, int userId, boolean start,
17716            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17717
17718        try {
17719            synchronized (this) {
17720                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17721                // its own permission.
17722                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17723                        != PackageManager.PERMISSION_GRANTED) {
17724                    throw new SecurityException("Requires permission "
17725                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17726                }
17727
17728                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17729                    throw new IllegalArgumentException("null profile info or fd");
17730                }
17731
17732                ProcessRecord proc = null;
17733                if (process != null) {
17734                    proc = findProcessLocked(process, userId, "profileControl");
17735                }
17736
17737                if (start && (proc == null || proc.thread == null)) {
17738                    throw new IllegalArgumentException("Unknown process: " + process);
17739                }
17740
17741                if (start) {
17742                    stopProfilerLocked(null, 0);
17743                    setProfileApp(proc.info, proc.processName, profilerInfo);
17744                    mProfileProc = proc;
17745                    mProfileType = profileType;
17746                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17747                    try {
17748                        fd = fd.dup();
17749                    } catch (IOException e) {
17750                        fd = null;
17751                    }
17752                    profilerInfo.profileFd = fd;
17753                    proc.thread.profilerControl(start, profilerInfo, profileType);
17754                    fd = null;
17755                    mProfileFd = null;
17756                } else {
17757                    stopProfilerLocked(proc, profileType);
17758                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17759                        try {
17760                            profilerInfo.profileFd.close();
17761                        } catch (IOException e) {
17762                        }
17763                    }
17764                }
17765
17766                return true;
17767            }
17768        } catch (RemoteException e) {
17769            throw new IllegalStateException("Process disappeared");
17770        } finally {
17771            if (profilerInfo != null && profilerInfo.profileFd != null) {
17772                try {
17773                    profilerInfo.profileFd.close();
17774                } catch (IOException e) {
17775                }
17776            }
17777        }
17778    }
17779
17780    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17781        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17782                userId, true, ALLOW_FULL_ONLY, callName, null);
17783        ProcessRecord proc = null;
17784        try {
17785            int pid = Integer.parseInt(process);
17786            synchronized (mPidsSelfLocked) {
17787                proc = mPidsSelfLocked.get(pid);
17788            }
17789        } catch (NumberFormatException e) {
17790        }
17791
17792        if (proc == null) {
17793            ArrayMap<String, SparseArray<ProcessRecord>> all
17794                    = mProcessNames.getMap();
17795            SparseArray<ProcessRecord> procs = all.get(process);
17796            if (procs != null && procs.size() > 0) {
17797                proc = procs.valueAt(0);
17798                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17799                    for (int i=1; i<procs.size(); i++) {
17800                        ProcessRecord thisProc = procs.valueAt(i);
17801                        if (thisProc.userId == userId) {
17802                            proc = thisProc;
17803                            break;
17804                        }
17805                    }
17806                }
17807            }
17808        }
17809
17810        return proc;
17811    }
17812
17813    public boolean dumpHeap(String process, int userId, boolean managed,
17814            String path, ParcelFileDescriptor fd) throws RemoteException {
17815
17816        try {
17817            synchronized (this) {
17818                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17819                // its own permission (same as profileControl).
17820                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17821                        != PackageManager.PERMISSION_GRANTED) {
17822                    throw new SecurityException("Requires permission "
17823                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17824                }
17825
17826                if (fd == null) {
17827                    throw new IllegalArgumentException("null fd");
17828                }
17829
17830                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17831                if (proc == null || proc.thread == null) {
17832                    throw new IllegalArgumentException("Unknown process: " + process);
17833                }
17834
17835                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17836                if (!isDebuggable) {
17837                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17838                        throw new SecurityException("Process not debuggable: " + proc);
17839                    }
17840                }
17841
17842                proc.thread.dumpHeap(managed, path, fd);
17843                fd = null;
17844                return true;
17845            }
17846        } catch (RemoteException e) {
17847            throw new IllegalStateException("Process disappeared");
17848        } finally {
17849            if (fd != null) {
17850                try {
17851                    fd.close();
17852                } catch (IOException e) {
17853                }
17854            }
17855        }
17856    }
17857
17858    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17859    public void monitor() {
17860        synchronized (this) { }
17861    }
17862
17863    void onCoreSettingsChange(Bundle settings) {
17864        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17865            ProcessRecord processRecord = mLruProcesses.get(i);
17866            try {
17867                if (processRecord.thread != null) {
17868                    processRecord.thread.setCoreSettings(settings);
17869                }
17870            } catch (RemoteException re) {
17871                /* ignore */
17872            }
17873        }
17874    }
17875
17876    // Multi-user methods
17877
17878    /**
17879     * Start user, if its not already running, but don't bring it to foreground.
17880     */
17881    @Override
17882    public boolean startUserInBackground(final int userId) {
17883        return startUser(userId, /* foreground */ false);
17884    }
17885
17886    /**
17887     * Start user, if its not already running, and bring it to foreground.
17888     */
17889    boolean startUserInForeground(final int userId, Dialog dlg) {
17890        boolean result = startUser(userId, /* foreground */ true);
17891        dlg.dismiss();
17892        return result;
17893    }
17894
17895    /**
17896     * Refreshes the list of users related to the current user when either a
17897     * user switch happens or when a new related user is started in the
17898     * background.
17899     */
17900    private void updateCurrentProfileIdsLocked() {
17901        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17902                mCurrentUserId, false /* enabledOnly */);
17903        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17904        for (int i = 0; i < currentProfileIds.length; i++) {
17905            currentProfileIds[i] = profiles.get(i).id;
17906        }
17907        mCurrentProfileIds = currentProfileIds;
17908
17909        synchronized (mUserProfileGroupIdsSelfLocked) {
17910            mUserProfileGroupIdsSelfLocked.clear();
17911            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17912            for (int i = 0; i < users.size(); i++) {
17913                UserInfo user = users.get(i);
17914                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17915                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17916                }
17917            }
17918        }
17919    }
17920
17921    private Set getProfileIdsLocked(int userId) {
17922        Set userIds = new HashSet<Integer>();
17923        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17924                userId, false /* enabledOnly */);
17925        for (UserInfo user : profiles) {
17926            userIds.add(Integer.valueOf(user.id));
17927        }
17928        return userIds;
17929    }
17930
17931    @Override
17932    public boolean switchUser(final int userId) {
17933        String userName;
17934        synchronized (this) {
17935            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17936            if (userInfo == null) {
17937                Slog.w(TAG, "No user info for user #" + userId);
17938                return false;
17939            }
17940            if (userInfo.isManagedProfile()) {
17941                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17942                return false;
17943            }
17944            userName = userInfo.name;
17945            mTargetUserId = userId;
17946        }
17947        mHandler.removeMessages(START_USER_SWITCH_MSG);
17948        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17949        return true;
17950    }
17951
17952    private void showUserSwitchDialog(int userId, String userName) {
17953        // The dialog will show and then initiate the user switch by calling startUserInForeground
17954        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17955                true /* above system */);
17956        d.show();
17957    }
17958
17959    private boolean startUser(final int userId, final boolean foreground) {
17960        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17961                != PackageManager.PERMISSION_GRANTED) {
17962            String msg = "Permission Denial: switchUser() from pid="
17963                    + Binder.getCallingPid()
17964                    + ", uid=" + Binder.getCallingUid()
17965                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17966            Slog.w(TAG, msg);
17967            throw new SecurityException(msg);
17968        }
17969
17970        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17971
17972        final long ident = Binder.clearCallingIdentity();
17973        try {
17974            synchronized (this) {
17975                final int oldUserId = mCurrentUserId;
17976                if (oldUserId == userId) {
17977                    return true;
17978                }
17979
17980                mStackSupervisor.setLockTaskModeLocked(null, false);
17981
17982                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17983                if (userInfo == null) {
17984                    Slog.w(TAG, "No user info for user #" + userId);
17985                    return false;
17986                }
17987                if (foreground && userInfo.isManagedProfile()) {
17988                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17989                    return false;
17990                }
17991
17992                if (foreground) {
17993                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17994                            R.anim.screen_user_enter);
17995                }
17996
17997                boolean needStart = false;
17998
17999                // If the user we are switching to is not currently started, then
18000                // we need to start it now.
18001                if (mStartedUsers.get(userId) == null) {
18002                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18003                    updateStartedUserArrayLocked();
18004                    needStart = true;
18005                }
18006
18007                final Integer userIdInt = Integer.valueOf(userId);
18008                mUserLru.remove(userIdInt);
18009                mUserLru.add(userIdInt);
18010
18011                if (foreground) {
18012                    mCurrentUserId = userId;
18013                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18014                    updateCurrentProfileIdsLocked();
18015                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18016                    // Once the internal notion of the active user has switched, we lock the device
18017                    // with the option to show the user switcher on the keyguard.
18018                    mWindowManager.lockNow(null);
18019                } else {
18020                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18021                    updateCurrentProfileIdsLocked();
18022                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18023                    mUserLru.remove(currentUserIdInt);
18024                    mUserLru.add(currentUserIdInt);
18025                }
18026
18027                final UserStartedState uss = mStartedUsers.get(userId);
18028
18029                // Make sure user is in the started state.  If it is currently
18030                // stopping, we need to knock that off.
18031                if (uss.mState == UserStartedState.STATE_STOPPING) {
18032                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18033                    // so we can just fairly silently bring the user back from
18034                    // the almost-dead.
18035                    uss.mState = UserStartedState.STATE_RUNNING;
18036                    updateStartedUserArrayLocked();
18037                    needStart = true;
18038                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18039                    // This means ACTION_SHUTDOWN has been sent, so we will
18040                    // need to treat this as a new boot of the user.
18041                    uss.mState = UserStartedState.STATE_BOOTING;
18042                    updateStartedUserArrayLocked();
18043                    needStart = true;
18044                }
18045
18046                if (uss.mState == UserStartedState.STATE_BOOTING) {
18047                    // Booting up a new user, need to tell system services about it.
18048                    // Note that this is on the same handler as scheduling of broadcasts,
18049                    // which is important because it needs to go first.
18050                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18051                }
18052
18053                if (foreground) {
18054                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18055                            oldUserId));
18056                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18057                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18058                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18059                            oldUserId, userId, uss));
18060                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18061                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18062                }
18063
18064                if (needStart) {
18065                    // Send USER_STARTED broadcast
18066                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18067                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18068                            | Intent.FLAG_RECEIVER_FOREGROUND);
18069                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18070                    broadcastIntentLocked(null, null, intent,
18071                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18072                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18073                }
18074
18075                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18076                    if (userId != UserHandle.USER_OWNER) {
18077                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18078                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18079                        broadcastIntentLocked(null, null, intent, null,
18080                                new IIntentReceiver.Stub() {
18081                                    public void performReceive(Intent intent, int resultCode,
18082                                            String data, Bundle extras, boolean ordered,
18083                                            boolean sticky, int sendingUser) {
18084                                        onUserInitialized(uss, foreground, oldUserId, userId);
18085                                    }
18086                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18087                                true, false, MY_PID, Process.SYSTEM_UID,
18088                                userId);
18089                        uss.initializing = true;
18090                    } else {
18091                        getUserManagerLocked().makeInitialized(userInfo.id);
18092                    }
18093                }
18094
18095                if (foreground) {
18096                    if (!uss.initializing) {
18097                        moveUserToForeground(uss, oldUserId, userId);
18098                    }
18099                } else {
18100                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18101                }
18102
18103                if (needStart) {
18104                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18105                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18106                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18107                    broadcastIntentLocked(null, null, intent,
18108                            null, new IIntentReceiver.Stub() {
18109                                @Override
18110                                public void performReceive(Intent intent, int resultCode, String data,
18111                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18112                                        throws RemoteException {
18113                                }
18114                            }, 0, null, null,
18115                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18116                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18117                }
18118            }
18119        } finally {
18120            Binder.restoreCallingIdentity(ident);
18121        }
18122
18123        return true;
18124    }
18125
18126    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18127        long ident = Binder.clearCallingIdentity();
18128        try {
18129            Intent intent;
18130            if (oldUserId >= 0) {
18131                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18132                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18133                int count = profiles.size();
18134                for (int i = 0; i < count; i++) {
18135                    int profileUserId = profiles.get(i).id;
18136                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18137                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18138                            | Intent.FLAG_RECEIVER_FOREGROUND);
18139                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18140                    broadcastIntentLocked(null, null, intent,
18141                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18142                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18143                }
18144            }
18145            if (newUserId >= 0) {
18146                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18147                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18148                int count = profiles.size();
18149                for (int i = 0; i < count; i++) {
18150                    int profileUserId = profiles.get(i).id;
18151                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18152                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18153                            | Intent.FLAG_RECEIVER_FOREGROUND);
18154                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18155                    broadcastIntentLocked(null, null, intent,
18156                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18157                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18158                }
18159                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18160                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18161                        | Intent.FLAG_RECEIVER_FOREGROUND);
18162                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18163                broadcastIntentLocked(null, null, intent,
18164                        null, null, 0, null, null,
18165                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18166                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18167            }
18168        } finally {
18169            Binder.restoreCallingIdentity(ident);
18170        }
18171    }
18172
18173    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18174            final int newUserId) {
18175        final int N = mUserSwitchObservers.beginBroadcast();
18176        if (N > 0) {
18177            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18178                int mCount = 0;
18179                @Override
18180                public void sendResult(Bundle data) throws RemoteException {
18181                    synchronized (ActivityManagerService.this) {
18182                        if (mCurUserSwitchCallback == this) {
18183                            mCount++;
18184                            if (mCount == N) {
18185                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18186                            }
18187                        }
18188                    }
18189                }
18190            };
18191            synchronized (this) {
18192                uss.switching = true;
18193                mCurUserSwitchCallback = callback;
18194            }
18195            for (int i=0; i<N; i++) {
18196                try {
18197                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18198                            newUserId, callback);
18199                } catch (RemoteException e) {
18200                }
18201            }
18202        } else {
18203            synchronized (this) {
18204                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18205            }
18206        }
18207        mUserSwitchObservers.finishBroadcast();
18208    }
18209
18210    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18211        synchronized (this) {
18212            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18213            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18214        }
18215    }
18216
18217    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18218        mCurUserSwitchCallback = null;
18219        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18220        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18221                oldUserId, newUserId, uss));
18222    }
18223
18224    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18225        synchronized (this) {
18226            if (foreground) {
18227                moveUserToForeground(uss, oldUserId, newUserId);
18228            }
18229        }
18230
18231        completeSwitchAndInitalize(uss, newUserId, true, false);
18232    }
18233
18234    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18235        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18236        if (homeInFront) {
18237            startHomeActivityLocked(newUserId);
18238        } else {
18239            mStackSupervisor.resumeTopActivitiesLocked();
18240        }
18241        EventLogTags.writeAmSwitchUser(newUserId);
18242        getUserManagerLocked().userForeground(newUserId);
18243        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18244    }
18245
18246    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18247        completeSwitchAndInitalize(uss, newUserId, false, true);
18248    }
18249
18250    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18251            boolean clearInitializing, boolean clearSwitching) {
18252        boolean unfrozen = false;
18253        synchronized (this) {
18254            if (clearInitializing) {
18255                uss.initializing = false;
18256                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18257            }
18258            if (clearSwitching) {
18259                uss.switching = false;
18260            }
18261            if (!uss.switching && !uss.initializing) {
18262                mWindowManager.stopFreezingScreen();
18263                unfrozen = true;
18264            }
18265        }
18266        if (unfrozen) {
18267            final int N = mUserSwitchObservers.beginBroadcast();
18268            for (int i=0; i<N; i++) {
18269                try {
18270                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18271                } catch (RemoteException e) {
18272                }
18273            }
18274            mUserSwitchObservers.finishBroadcast();
18275        }
18276    }
18277
18278    void scheduleStartProfilesLocked() {
18279        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18280            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18281                    DateUtils.SECOND_IN_MILLIS);
18282        }
18283    }
18284
18285    void startProfilesLocked() {
18286        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18287        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18288                mCurrentUserId, false /* enabledOnly */);
18289        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18290        for (UserInfo user : profiles) {
18291            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18292                    && user.id != mCurrentUserId) {
18293                toStart.add(user);
18294            }
18295        }
18296        final int n = toStart.size();
18297        int i = 0;
18298        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18299            startUserInBackground(toStart.get(i).id);
18300        }
18301        if (i < n) {
18302            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18303        }
18304    }
18305
18306    void finishUserBoot(UserStartedState uss) {
18307        synchronized (this) {
18308            if (uss.mState == UserStartedState.STATE_BOOTING
18309                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18310                uss.mState = UserStartedState.STATE_RUNNING;
18311                final int userId = uss.mHandle.getIdentifier();
18312                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18313                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18314                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18315                broadcastIntentLocked(null, null, intent,
18316                        null, null, 0, null, null,
18317                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18318                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18319            }
18320        }
18321    }
18322
18323    void finishUserSwitch(UserStartedState uss) {
18324        synchronized (this) {
18325            finishUserBoot(uss);
18326
18327            startProfilesLocked();
18328
18329            int num = mUserLru.size();
18330            int i = 0;
18331            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18332                Integer oldUserId = mUserLru.get(i);
18333                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18334                if (oldUss == null) {
18335                    // Shouldn't happen, but be sane if it does.
18336                    mUserLru.remove(i);
18337                    num--;
18338                    continue;
18339                }
18340                if (oldUss.mState == UserStartedState.STATE_STOPPING
18341                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18342                    // This user is already stopping, doesn't count.
18343                    num--;
18344                    i++;
18345                    continue;
18346                }
18347                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18348                    // Owner and current can't be stopped, but count as running.
18349                    i++;
18350                    continue;
18351                }
18352                // This is a user to be stopped.
18353                stopUserLocked(oldUserId, null);
18354                num--;
18355                i++;
18356            }
18357        }
18358    }
18359
18360    @Override
18361    public int stopUser(final int userId, final IStopUserCallback callback) {
18362        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18363                != PackageManager.PERMISSION_GRANTED) {
18364            String msg = "Permission Denial: switchUser() from pid="
18365                    + Binder.getCallingPid()
18366                    + ", uid=" + Binder.getCallingUid()
18367                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18368            Slog.w(TAG, msg);
18369            throw new SecurityException(msg);
18370        }
18371        if (userId <= 0) {
18372            throw new IllegalArgumentException("Can't stop primary user " + userId);
18373        }
18374        synchronized (this) {
18375            return stopUserLocked(userId, callback);
18376        }
18377    }
18378
18379    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18380        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18381        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18382            return ActivityManager.USER_OP_IS_CURRENT;
18383        }
18384
18385        final UserStartedState uss = mStartedUsers.get(userId);
18386        if (uss == null) {
18387            // User is not started, nothing to do...  but we do need to
18388            // callback if requested.
18389            if (callback != null) {
18390                mHandler.post(new Runnable() {
18391                    @Override
18392                    public void run() {
18393                        try {
18394                            callback.userStopped(userId);
18395                        } catch (RemoteException e) {
18396                        }
18397                    }
18398                });
18399            }
18400            return ActivityManager.USER_OP_SUCCESS;
18401        }
18402
18403        if (callback != null) {
18404            uss.mStopCallbacks.add(callback);
18405        }
18406
18407        if (uss.mState != UserStartedState.STATE_STOPPING
18408                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18409            uss.mState = UserStartedState.STATE_STOPPING;
18410            updateStartedUserArrayLocked();
18411
18412            long ident = Binder.clearCallingIdentity();
18413            try {
18414                // We are going to broadcast ACTION_USER_STOPPING and then
18415                // once that is done send a final ACTION_SHUTDOWN and then
18416                // stop the user.
18417                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18418                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18419                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18420                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18421                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18422                // This is the result receiver for the final shutdown broadcast.
18423                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18424                    @Override
18425                    public void performReceive(Intent intent, int resultCode, String data,
18426                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18427                        finishUserStop(uss);
18428                    }
18429                };
18430                // This is the result receiver for the initial stopping broadcast.
18431                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18432                    @Override
18433                    public void performReceive(Intent intent, int resultCode, String data,
18434                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18435                        // On to the next.
18436                        synchronized (ActivityManagerService.this) {
18437                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18438                                // Whoops, we are being started back up.  Abort, abort!
18439                                return;
18440                            }
18441                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18442                        }
18443                        mBatteryStatsService.noteEvent(
18444                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18445                                Integer.toString(userId), userId);
18446                        mSystemServiceManager.stopUser(userId);
18447                        broadcastIntentLocked(null, null, shutdownIntent,
18448                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18449                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18450                    }
18451                };
18452                // Kick things off.
18453                broadcastIntentLocked(null, null, stoppingIntent,
18454                        null, stoppingReceiver, 0, null, null,
18455                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18456                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18457            } finally {
18458                Binder.restoreCallingIdentity(ident);
18459            }
18460        }
18461
18462        return ActivityManager.USER_OP_SUCCESS;
18463    }
18464
18465    void finishUserStop(UserStartedState uss) {
18466        final int userId = uss.mHandle.getIdentifier();
18467        boolean stopped;
18468        ArrayList<IStopUserCallback> callbacks;
18469        synchronized (this) {
18470            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18471            if (mStartedUsers.get(userId) != uss) {
18472                stopped = false;
18473            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18474                stopped = false;
18475            } else {
18476                stopped = true;
18477                // User can no longer run.
18478                mStartedUsers.remove(userId);
18479                mUserLru.remove(Integer.valueOf(userId));
18480                updateStartedUserArrayLocked();
18481
18482                // Clean up all state and processes associated with the user.
18483                // Kill all the processes for the user.
18484                forceStopUserLocked(userId, "finish user");
18485            }
18486
18487            // Explicitly remove the old information in mRecentTasks.
18488            removeRecentTasksForUserLocked(userId);
18489        }
18490
18491        for (int i=0; i<callbacks.size(); i++) {
18492            try {
18493                if (stopped) callbacks.get(i).userStopped(userId);
18494                else callbacks.get(i).userStopAborted(userId);
18495            } catch (RemoteException e) {
18496            }
18497        }
18498
18499        if (stopped) {
18500            mSystemServiceManager.cleanupUser(userId);
18501            synchronized (this) {
18502                mStackSupervisor.removeUserLocked(userId);
18503            }
18504        }
18505    }
18506
18507    @Override
18508    public UserInfo getCurrentUser() {
18509        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18510                != PackageManager.PERMISSION_GRANTED) && (
18511                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18512                != PackageManager.PERMISSION_GRANTED)) {
18513            String msg = "Permission Denial: getCurrentUser() from pid="
18514                    + Binder.getCallingPid()
18515                    + ", uid=" + Binder.getCallingUid()
18516                    + " requires " + INTERACT_ACROSS_USERS;
18517            Slog.w(TAG, msg);
18518            throw new SecurityException(msg);
18519        }
18520        synchronized (this) {
18521            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18522            return getUserManagerLocked().getUserInfo(userId);
18523        }
18524    }
18525
18526    int getCurrentUserIdLocked() {
18527        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18528    }
18529
18530    @Override
18531    public boolean isUserRunning(int userId, boolean orStopped) {
18532        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18533                != PackageManager.PERMISSION_GRANTED) {
18534            String msg = "Permission Denial: isUserRunning() from pid="
18535                    + Binder.getCallingPid()
18536                    + ", uid=" + Binder.getCallingUid()
18537                    + " requires " + INTERACT_ACROSS_USERS;
18538            Slog.w(TAG, msg);
18539            throw new SecurityException(msg);
18540        }
18541        synchronized (this) {
18542            return isUserRunningLocked(userId, orStopped);
18543        }
18544    }
18545
18546    boolean isUserRunningLocked(int userId, boolean orStopped) {
18547        UserStartedState state = mStartedUsers.get(userId);
18548        if (state == null) {
18549            return false;
18550        }
18551        if (orStopped) {
18552            return true;
18553        }
18554        return state.mState != UserStartedState.STATE_STOPPING
18555                && state.mState != UserStartedState.STATE_SHUTDOWN;
18556    }
18557
18558    @Override
18559    public int[] getRunningUserIds() {
18560        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18561                != PackageManager.PERMISSION_GRANTED) {
18562            String msg = "Permission Denial: isUserRunning() from pid="
18563                    + Binder.getCallingPid()
18564                    + ", uid=" + Binder.getCallingUid()
18565                    + " requires " + INTERACT_ACROSS_USERS;
18566            Slog.w(TAG, msg);
18567            throw new SecurityException(msg);
18568        }
18569        synchronized (this) {
18570            return mStartedUserArray;
18571        }
18572    }
18573
18574    private void updateStartedUserArrayLocked() {
18575        int num = 0;
18576        for (int i=0; i<mStartedUsers.size();  i++) {
18577            UserStartedState uss = mStartedUsers.valueAt(i);
18578            // This list does not include stopping users.
18579            if (uss.mState != UserStartedState.STATE_STOPPING
18580                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18581                num++;
18582            }
18583        }
18584        mStartedUserArray = new int[num];
18585        num = 0;
18586        for (int i=0; i<mStartedUsers.size();  i++) {
18587            UserStartedState uss = mStartedUsers.valueAt(i);
18588            if (uss.mState != UserStartedState.STATE_STOPPING
18589                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18590                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18591                num++;
18592            }
18593        }
18594    }
18595
18596    @Override
18597    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18598        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18599                != PackageManager.PERMISSION_GRANTED) {
18600            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18601                    + Binder.getCallingPid()
18602                    + ", uid=" + Binder.getCallingUid()
18603                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18604            Slog.w(TAG, msg);
18605            throw new SecurityException(msg);
18606        }
18607
18608        mUserSwitchObservers.register(observer);
18609    }
18610
18611    @Override
18612    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18613        mUserSwitchObservers.unregister(observer);
18614    }
18615
18616    private boolean userExists(int userId) {
18617        if (userId == 0) {
18618            return true;
18619        }
18620        UserManagerService ums = getUserManagerLocked();
18621        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18622    }
18623
18624    int[] getUsersLocked() {
18625        UserManagerService ums = getUserManagerLocked();
18626        return ums != null ? ums.getUserIds() : new int[] { 0 };
18627    }
18628
18629    UserManagerService getUserManagerLocked() {
18630        if (mUserManager == null) {
18631            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18632            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18633        }
18634        return mUserManager;
18635    }
18636
18637    private int applyUserId(int uid, int userId) {
18638        return UserHandle.getUid(userId, uid);
18639    }
18640
18641    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18642        if (info == null) return null;
18643        ApplicationInfo newInfo = new ApplicationInfo(info);
18644        newInfo.uid = applyUserId(info.uid, userId);
18645        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18646                + info.packageName;
18647        return newInfo;
18648    }
18649
18650    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18651        if (aInfo == null
18652                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18653            return aInfo;
18654        }
18655
18656        ActivityInfo info = new ActivityInfo(aInfo);
18657        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18658        return info;
18659    }
18660
18661    private final class LocalService extends ActivityManagerInternal {
18662        @Override
18663        public void goingToSleep() {
18664            ActivityManagerService.this.goingToSleep();
18665        }
18666
18667        @Override
18668        public void wakingUp() {
18669            ActivityManagerService.this.wakingUp();
18670        }
18671
18672        @Override
18673        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18674                String processName, String abiOverride, int uid, Runnable crashHandler) {
18675            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18676                    processName, abiOverride, uid, crashHandler);
18677        }
18678    }
18679
18680    /**
18681     * An implementation of IAppTask, that allows an app to manage its own tasks via
18682     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18683     * only the process that calls getAppTasks() can call the AppTask methods.
18684     */
18685    class AppTaskImpl extends IAppTask.Stub {
18686        private int mTaskId;
18687        private int mCallingUid;
18688
18689        public AppTaskImpl(int taskId, int callingUid) {
18690            mTaskId = taskId;
18691            mCallingUid = callingUid;
18692        }
18693
18694        private void checkCaller() {
18695            if (mCallingUid != Binder.getCallingUid()) {
18696                throw new SecurityException("Caller " + mCallingUid
18697                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18698            }
18699        }
18700
18701        @Override
18702        public void finishAndRemoveTask() {
18703            checkCaller();
18704
18705            synchronized (ActivityManagerService.this) {
18706                long origId = Binder.clearCallingIdentity();
18707                try {
18708                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18709                    if (tr == null) {
18710                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18711                    }
18712                    // Only kill the process if we are not a new document
18713                    int flags = tr.getBaseIntent().getFlags();
18714                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18715                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18716                    removeTaskByIdLocked(mTaskId,
18717                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18718                } finally {
18719                    Binder.restoreCallingIdentity(origId);
18720                }
18721            }
18722        }
18723
18724        @Override
18725        public ActivityManager.RecentTaskInfo getTaskInfo() {
18726            checkCaller();
18727
18728            synchronized (ActivityManagerService.this) {
18729                long origId = Binder.clearCallingIdentity();
18730                try {
18731                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18732                    if (tr == null) {
18733                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18734                    }
18735                    return createRecentTaskInfoFromTaskRecord(tr);
18736                } finally {
18737                    Binder.restoreCallingIdentity(origId);
18738                }
18739            }
18740        }
18741
18742        @Override
18743        public void moveToFront() {
18744            checkCaller();
18745
18746            final TaskRecord tr;
18747            synchronized (ActivityManagerService.this) {
18748                tr = recentTaskForIdLocked(mTaskId);
18749                if (tr == null) {
18750                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18751                }
18752                if (tr.getRootActivity() != null) {
18753                    long origId = Binder.clearCallingIdentity();
18754                    try {
18755                        moveTaskToFrontLocked(tr.taskId, 0, null);
18756                        return;
18757                    } finally {
18758                        Binder.restoreCallingIdentity(origId);
18759                    }
18760                }
18761            }
18762
18763            startActivityFromRecentsInner(tr.taskId, null);
18764        }
18765
18766        @Override
18767        public int startActivity(IBinder whoThread, String callingPackage,
18768                Intent intent, String resolvedType, Bundle options) {
18769            checkCaller();
18770
18771            int callingUser = UserHandle.getCallingUserId();
18772            TaskRecord tr;
18773            IApplicationThread appThread;
18774            synchronized (ActivityManagerService.this) {
18775                tr = recentTaskForIdLocked(mTaskId);
18776                if (tr == null) {
18777                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18778                }
18779                appThread = ApplicationThreadNative.asInterface(whoThread);
18780                if (appThread == null) {
18781                    throw new IllegalArgumentException("Bad app thread " + appThread);
18782                }
18783            }
18784            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18785                    resolvedType, null, null, null, null, 0, 0, null, null,
18786                    null, options, callingUser, null, tr);
18787        }
18788
18789        @Override
18790        public void setExcludeFromRecents(boolean exclude) {
18791            checkCaller();
18792
18793            synchronized (ActivityManagerService.this) {
18794                long origId = Binder.clearCallingIdentity();
18795                try {
18796                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18797                    if (tr == null) {
18798                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18799                    }
18800                    Intent intent = tr.getBaseIntent();
18801                    if (exclude) {
18802                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18803                    } else {
18804                        intent.setFlags(intent.getFlags()
18805                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18806                    }
18807                } finally {
18808                    Binder.restoreCallingIdentity(origId);
18809                }
18810            }
18811        }
18812    }
18813}
18814