ActivityManagerService.java revision 85b764e22babfe5508286fbad5d7fee12345704f
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.provider.Settings;
184import android.text.format.DateUtils;
185import android.text.format.Time;
186import android.util.AtomicFile;
187import android.util.EventLog;
188import android.util.Log;
189import android.util.Pair;
190import android.util.PrintWriterPrinter;
191import android.util.Slog;
192import android.util.SparseArray;
193import android.util.TimeUtils;
194import android.util.Xml;
195import android.view.Gravity;
196import android.view.LayoutInflater;
197import android.view.View;
198import android.view.WindowManager;
199
200import java.io.BufferedInputStream;
201import java.io.BufferedOutputStream;
202import java.io.DataInputStream;
203import java.io.DataOutputStream;
204import java.io.File;
205import java.io.FileDescriptor;
206import java.io.FileInputStream;
207import java.io.FileNotFoundException;
208import java.io.FileOutputStream;
209import java.io.IOException;
210import java.io.InputStreamReader;
211import java.io.PrintWriter;
212import java.io.StringWriter;
213import java.lang.ref.WeakReference;
214import java.util.ArrayList;
215import java.util.Arrays;
216import java.util.Collections;
217import java.util.Comparator;
218import java.util.HashMap;
219import java.util.HashSet;
220import java.util.Iterator;
221import java.util.List;
222import java.util.Locale;
223import java.util.Map;
224import java.util.Set;
225import java.util.concurrent.atomic.AtomicBoolean;
226import java.util.concurrent.atomic.AtomicLong;
227
228public final class ActivityManagerService extends ActivityManagerNative
229        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
230
231    private static final String USER_DATA_DIR = "/data/user/";
232    // File that stores last updated system version and called preboot receivers
233    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
234
235    static final String TAG = "ActivityManager";
236    static final String TAG_MU = "ActivityManagerServiceMU";
237    static final boolean DEBUG = false;
238    static final boolean localLOGV = DEBUG;
239    static final boolean DEBUG_BACKUP = localLOGV || false;
240    static final boolean DEBUG_BROADCAST = localLOGV || false;
241    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
242    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
243    static final boolean DEBUG_CLEANUP = localLOGV || false;
244    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
245    static final boolean DEBUG_FOCUS = false;
246    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
247    static final boolean DEBUG_MU = localLOGV || false;
248    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
249    static final boolean DEBUG_LRU = localLOGV || false;
250    static final boolean DEBUG_PAUSE = localLOGV || false;
251    static final boolean DEBUG_POWER = localLOGV || false;
252    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
253    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
254    static final boolean DEBUG_PROCESSES = localLOGV || false;
255    static final boolean DEBUG_PROVIDER = localLOGV || false;
256    static final boolean DEBUG_RESULTS = localLOGV || false;
257    static final boolean DEBUG_SERVICE = localLOGV || false;
258    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
259    static final boolean DEBUG_STACK = localLOGV || false;
260    static final boolean DEBUG_SWITCH = localLOGV || false;
261    static final boolean DEBUG_TASKS = localLOGV || false;
262    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
263    static final boolean DEBUG_TRANSITION = localLOGV || false;
264    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
265    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
266    static final boolean DEBUG_VISBILITY = localLOGV || false;
267    static final boolean DEBUG_PSS = localLOGV || false;
268    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
269    static final boolean DEBUG_RECENTS = localLOGV || false;
270    static final boolean VALIDATE_TOKENS = false;
271    static final boolean SHOW_ACTIVITY_START_TIME = true;
272
273    // Control over CPU and battery monitoring.
274    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
275    static final boolean MONITOR_CPU_USAGE = true;
276    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
277    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
278    static final boolean MONITOR_THREAD_CPU_USAGE = false;
279
280    // The flags that are set for all calls we make to the package manager.
281    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
282
283    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
284
285    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
286
287    // Maximum number recent bitmaps to keep in memory.
288    static final int MAX_RECENT_BITMAPS = 5;
289
290    // Amount of time after a call to stopAppSwitches() during which we will
291    // prevent further untrusted switches from happening.
292    static final long APP_SWITCH_DELAY_TIME = 5*1000;
293
294    // How long we wait for a launched process to attach to the activity manager
295    // before we decide it's never going to come up for real.
296    static final int PROC_START_TIMEOUT = 10*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real, when the process was
300    // started with a wrapper for instrumentation (such as Valgrind) because it
301    // could take much longer than usual.
302    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
303
304    // How long to wait after going idle before forcing apps to GC.
305    static final int GC_TIMEOUT = 5*1000;
306
307    // The minimum amount of time between successive GC requests for a process.
308    static final int GC_MIN_INTERVAL = 60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process.
311    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
312
313    // The minimum amount of time between successive PSS requests for a process
314    // when the request is due to the memory state being lowered.
315    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
316
317    // The rate at which we check for apps using excessive power -- 15 mins.
318    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
319
320    // The minimum sample duration we will allow before deciding we have
321    // enough data on wake locks to start killing things.
322    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on CPU usage to start killing things.
326    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // How long we allow a receiver to run before giving up on it.
329    static final int BROADCAST_FG_TIMEOUT = 10*1000;
330    static final int BROADCAST_BG_TIMEOUT = 60*1000;
331
332    // How long we wait until we timeout on key dispatching.
333    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
334
335    // How long we wait until we timeout on key dispatching during instrumentation.
336    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
337
338    // Amount of time we wait for observers to handle a user switch before
339    // giving up on them and unfreezing the screen.
340    static final int USER_SWITCH_TIMEOUT = 2*1000;
341
342    // Maximum number of users we allow to be running at a time.
343    static final int MAX_RUNNING_USERS = 3;
344
345    // How long to wait in getAssistContextExtras for the activity and foreground services
346    // to respond with the result.
347    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
348
349    // Maximum number of persisted Uri grants a package is allowed
350    static final int MAX_PERSISTED_URI_GRANTS = 128;
351
352    static final int MY_PID = Process.myPid();
353
354    static final String[] EMPTY_STRING_ARRAY = new String[0];
355
356    // How many bytes to write into the dropbox log before truncating
357    static final int DROPBOX_MAX_SIZE = 256 * 1024;
358
359    // Access modes for handleIncomingUser.
360    static final int ALLOW_NON_FULL = 0;
361    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
362    static final int ALLOW_FULL_ONLY = 2;
363
364    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
365
366    /** All system services */
367    SystemServiceManager mSystemServiceManager;
368
369    /** Run all ActivityStacks through this */
370    ActivityStackSupervisor mStackSupervisor;
371
372    public IntentFirewall mIntentFirewall;
373
374    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
375    // default actuion automatically.  Important for devices without direct input
376    // devices.
377    private boolean mShowDialogs = true;
378
379    BroadcastQueue mFgBroadcastQueue;
380    BroadcastQueue mBgBroadcastQueue;
381    // Convenient for easy iteration over the queues. Foreground is first
382    // so that dispatch of foreground broadcasts gets precedence.
383    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
384
385    BroadcastQueue broadcastQueueForIntent(Intent intent) {
386        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
387        if (DEBUG_BACKGROUND_BROADCAST) {
388            Slog.i(TAG, "Broadcast intent " + intent + " on "
389                    + (isFg ? "foreground" : "background")
390                    + " queue");
391        }
392        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
393    }
394
395    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
396        for (BroadcastQueue queue : mBroadcastQueues) {
397            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
398            if (r != null) {
399                return r;
400            }
401        }
402        return null;
403    }
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    ActivityRecord mFocusedActivity = null;
409
410    /**
411     * List of intents that were used to start the most recent tasks.
412     */
413    ArrayList<TaskRecord> mRecentTasks;
414    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
415
416    /**
417     * For addAppTask: cached of the last activity component that was added.
418     */
419    ComponentName mLastAddedTaskComponent;
420
421    /**
422     * For addAppTask: cached of the last activity uid that was added.
423     */
424    int mLastAddedTaskUid;
425
426    /**
427     * For addAppTask: cached of the last ActivityInfo that was added.
428     */
429    ActivityInfo mLastAddedTaskActivity;
430
431    public class PendingAssistExtras extends Binder implements Runnable {
432        public final ActivityRecord activity;
433        public boolean haveResult = false;
434        public Bundle result = null;
435        public PendingAssistExtras(ActivityRecord _activity) {
436            activity = _activity;
437        }
438        @Override
439        public void run() {
440            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
441            synchronized (this) {
442                haveResult = true;
443                notifyAll();
444            }
445        }
446    }
447
448    final ArrayList<PendingAssistExtras> mPendingAssistExtras
449            = new ArrayList<PendingAssistExtras>();
450
451    /**
452     * Process management.
453     */
454    final ProcessList mProcessList = new ProcessList();
455
456    /**
457     * All of the applications we currently have running organized by name.
458     * The keys are strings of the application package name (as
459     * returned by the package manager), and the keys are ApplicationRecord
460     * objects.
461     */
462    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
463
464    /**
465     * Tracking long-term execution of processes to look for abuse and other
466     * bad app behavior.
467     */
468    final ProcessStatsService mProcessStats;
469
470    /**
471     * The currently running isolated processes.
472     */
473    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
474
475    /**
476     * Counter for assigning isolated process uids, to avoid frequently reusing the
477     * same ones.
478     */
479    int mNextIsolatedProcessUid = 0;
480
481    /**
482     * The currently running heavy-weight process, if any.
483     */
484    ProcessRecord mHeavyWeightProcess = null;
485
486    /**
487     * The last time that various processes have crashed.
488     */
489    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
490
491    /**
492     * Information about a process that is currently marked as bad.
493     */
494    static final class BadProcessInfo {
495        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
496            this.time = time;
497            this.shortMsg = shortMsg;
498            this.longMsg = longMsg;
499            this.stack = stack;
500        }
501
502        final long time;
503        final String shortMsg;
504        final String longMsg;
505        final String stack;
506    }
507
508    /**
509     * Set of applications that we consider to be bad, and will reject
510     * incoming broadcasts from (which the user has no control over).
511     * Processes are added to this set when they have crashed twice within
512     * a minimum amount of time; they are removed from it when they are
513     * later restarted (hopefully due to some user action).  The value is the
514     * time it was added to the list.
515     */
516    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
517
518    /**
519     * All of the processes we currently have running organized by pid.
520     * The keys are the pid running the application.
521     *
522     * <p>NOTE: This object is protected by its own lock, NOT the global
523     * activity manager lock!
524     */
525    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
526
527    /**
528     * All of the processes that have been forced to be foreground.  The key
529     * is the pid of the caller who requested it (we hold a death
530     * link on it).
531     */
532    abstract class ForegroundToken implements IBinder.DeathRecipient {
533        int pid;
534        IBinder token;
535    }
536    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
537
538    /**
539     * List of records for processes that someone had tried to start before the
540     * system was ready.  We don't start them at that point, but ensure they
541     * are started by the time booting is complete.
542     */
543    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
544
545    /**
546     * List of persistent applications that are in the process
547     * of being started.
548     */
549    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
550
551    /**
552     * Processes that are being forcibly torn down.
553     */
554    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
555
556    /**
557     * List of running applications, sorted by recent usage.
558     * The first entry in the list is the least recently used.
559     */
560    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
561
562    /**
563     * Where in mLruProcesses that the processes hosting activities start.
564     */
565    int mLruProcessActivityStart = 0;
566
567    /**
568     * Where in mLruProcesses that the processes hosting services start.
569     * This is after (lower index) than mLruProcessesActivityStart.
570     */
571    int mLruProcessServiceStart = 0;
572
573    /**
574     * List of processes that should gc as soon as things are idle.
575     */
576    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes we want to collect PSS data from.
580     */
581    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * Last time we requested PSS data of all processes.
585     */
586    long mLastFullPssTime = SystemClock.uptimeMillis();
587
588    /**
589     * If set, the next time we collect PSS data we should do a full collection
590     * with data from native processes and the kernel.
591     */
592    boolean mFullPssPending = false;
593
594    /**
595     * This is the process holding what we currently consider to be
596     * the "home" activity.
597     */
598    ProcessRecord mHomeProcess;
599
600    /**
601     * This is the process holding the activity the user last visited that
602     * is in a different process from the one they are currently in.
603     */
604    ProcessRecord mPreviousProcess;
605
606    /**
607     * The time at which the previous process was last visible.
608     */
609    long mPreviousProcessVisibleTime;
610
611    /**
612     * Which uses have been started, so are allowed to run code.
613     */
614    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
615
616    /**
617     * LRU list of history of current users.  Most recently current is at the end.
618     */
619    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
620
621    /**
622     * Constant array of the users that are currently started.
623     */
624    int[] mStartedUserArray = new int[] { 0 };
625
626    /**
627     * Registered observers of the user switching mechanics.
628     */
629    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
630            = new RemoteCallbackList<IUserSwitchObserver>();
631
632    /**
633     * Currently active user switch.
634     */
635    Object mCurUserSwitchCallback;
636
637    /**
638     * Packages that the user has asked to have run in screen size
639     * compatibility mode instead of filling the screen.
640     */
641    final CompatModePackages mCompatModePackages;
642
643    /**
644     * Set of IntentSenderRecord objects that are currently active.
645     */
646    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
647            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
648
649    /**
650     * Fingerprints (hashCode()) of stack traces that we've
651     * already logged DropBox entries for.  Guarded by itself.  If
652     * something (rogue user app) forces this over
653     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
654     */
655    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
656    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
657
658    /**
659     * Strict Mode background batched logging state.
660     *
661     * The string buffer is guarded by itself, and its lock is also
662     * used to determine if another batched write is already
663     * in-flight.
664     */
665    private final StringBuilder mStrictModeBuffer = new StringBuilder();
666
667    /**
668     * Keeps track of all IIntentReceivers that have been registered for
669     * broadcasts.  Hash keys are the receiver IBinder, hash value is
670     * a ReceiverList.
671     */
672    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
673            new HashMap<IBinder, ReceiverList>();
674
675    /**
676     * Resolver for broadcast intents to registered receivers.
677     * Holds BroadcastFilter (subclass of IntentFilter).
678     */
679    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
680            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
681        @Override
682        protected boolean allowFilterResult(
683                BroadcastFilter filter, List<BroadcastFilter> dest) {
684            IBinder target = filter.receiverList.receiver.asBinder();
685            for (int i=dest.size()-1; i>=0; i--) {
686                if (dest.get(i).receiverList.receiver.asBinder() == target) {
687                    return false;
688                }
689            }
690            return true;
691        }
692
693        @Override
694        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
695            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
696                    || userId == filter.owningUserId) {
697                return super.newResult(filter, match, userId);
698            }
699            return null;
700        }
701
702        @Override
703        protected BroadcastFilter[] newArray(int size) {
704            return new BroadcastFilter[size];
705        }
706
707        @Override
708        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
709            return packageName.equals(filter.packageName);
710        }
711    };
712
713    /**
714     * State of all active sticky broadcasts per user.  Keys are the action of the
715     * sticky Intent, values are an ArrayList of all broadcasted intents with
716     * that action (which should usually be one).  The SparseArray is keyed
717     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
718     * for stickies that are sent to all users.
719     */
720    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
721            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
722
723    final ActiveServices mServices;
724
725    /**
726     * Backup/restore process management
727     */
728    String mBackupAppName = null;
729    BackupRecord mBackupTarget = null;
730
731    final ProviderMap mProviderMap;
732
733    /**
734     * List of content providers who have clients waiting for them.  The
735     * application is currently being launched and the provider will be
736     * removed from this list once it is published.
737     */
738    final ArrayList<ContentProviderRecord> mLaunchingProviders
739            = new ArrayList<ContentProviderRecord>();
740
741    /**
742     * File storing persisted {@link #mGrantedUriPermissions}.
743     */
744    private final AtomicFile mGrantFile;
745
746    /** XML constants used in {@link #mGrantFile} */
747    private static final String TAG_URI_GRANTS = "uri-grants";
748    private static final String TAG_URI_GRANT = "uri-grant";
749    private static final String ATTR_USER_HANDLE = "userHandle";
750    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
751    private static final String ATTR_TARGET_USER_ID = "targetUserId";
752    private static final String ATTR_SOURCE_PKG = "sourcePkg";
753    private static final String ATTR_TARGET_PKG = "targetPkg";
754    private static final String ATTR_URI = "uri";
755    private static final String ATTR_MODE_FLAGS = "modeFlags";
756    private static final String ATTR_CREATED_TIME = "createdTime";
757    private static final String ATTR_PREFIX = "prefix";
758
759    /**
760     * Global set of specific {@link Uri} permissions that have been granted.
761     * This optimized lookup structure maps from {@link UriPermission#targetUid}
762     * to {@link UriPermission#uri} to {@link UriPermission}.
763     */
764    @GuardedBy("this")
765    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
766            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
767
768    public static class GrantUri {
769        public final int sourceUserId;
770        public final Uri uri;
771        public boolean prefix;
772
773        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
774            this.sourceUserId = sourceUserId;
775            this.uri = uri;
776            this.prefix = prefix;
777        }
778
779        @Override
780        public int hashCode() {
781            return toString().hashCode();
782        }
783
784        @Override
785        public boolean equals(Object o) {
786            if (o instanceof GrantUri) {
787                GrantUri other = (GrantUri) o;
788                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
789                        && prefix == other.prefix;
790            }
791            return false;
792        }
793
794        @Override
795        public String toString() {
796            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
797            if (prefix) result += " [prefix]";
798            return result;
799        }
800
801        public String toSafeString() {
802            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
803            if (prefix) result += " [prefix]";
804            return result;
805        }
806
807        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
808            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
809                    ContentProvider.getUriWithoutUserId(uri), false);
810        }
811    }
812
813    CoreSettingsObserver mCoreSettingsObserver;
814
815    /**
816     * Thread-local storage used to carry caller permissions over through
817     * indirect content-provider access.
818     */
819    private class Identity {
820        public int pid;
821        public int uid;
822
823        Identity(int _pid, int _uid) {
824            pid = _pid;
825            uid = _uid;
826        }
827    }
828
829    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
830
831    /**
832     * All information we have collected about the runtime performance of
833     * any user id that can impact battery performance.
834     */
835    final BatteryStatsService mBatteryStatsService;
836
837    /**
838     * Information about component usage
839     */
840    UsageStatsManagerInternal mUsageStatsService;
841
842    /**
843     * Information about and control over application operations
844     */
845    final AppOpsService mAppOpsService;
846
847    /**
848     * Save recent tasks information across reboots.
849     */
850    final TaskPersister mTaskPersister;
851
852    /**
853     * Current configuration information.  HistoryRecord objects are given
854     * a reference to this object to indicate which configuration they are
855     * currently running in, so this object must be kept immutable.
856     */
857    Configuration mConfiguration = new Configuration();
858
859    /**
860     * Current sequencing integer of the configuration, for skipping old
861     * configurations.
862     */
863    int mConfigurationSeq = 0;
864
865    /**
866     * Hardware-reported OpenGLES version.
867     */
868    final int GL_ES_VERSION;
869
870    /**
871     * List of initialization arguments to pass to all processes when binding applications to them.
872     * For example, references to the commonly used services.
873     */
874    HashMap<String, IBinder> mAppBindArgs;
875
876    /**
877     * Temporary to avoid allocations.  Protected by main lock.
878     */
879    final StringBuilder mStringBuilder = new StringBuilder(256);
880
881    /**
882     * Used to control how we initialize the service.
883     */
884    ComponentName mTopComponent;
885    String mTopAction = Intent.ACTION_MAIN;
886    String mTopData;
887    boolean mProcessesReady = false;
888    boolean mSystemReady = false;
889    boolean mBooting = false;
890    boolean mWaitingUpdate = false;
891    boolean mDidUpdate = false;
892    boolean mOnBattery = false;
893    boolean mLaunchWarningShown = false;
894
895    Context mContext;
896
897    int mFactoryTest;
898
899    boolean mCheckedForSetup;
900
901    /**
902     * The time at which we will allow normal application switches again,
903     * after a call to {@link #stopAppSwitches()}.
904     */
905    long mAppSwitchesAllowedTime;
906
907    /**
908     * This is set to true after the first switch after mAppSwitchesAllowedTime
909     * is set; any switches after that will clear the time.
910     */
911    boolean mDidAppSwitch;
912
913    /**
914     * Last time (in realtime) at which we checked for power usage.
915     */
916    long mLastPowerCheckRealtime;
917
918    /**
919     * Last time (in uptime) at which we checked for power usage.
920     */
921    long mLastPowerCheckUptime;
922
923    /**
924     * Set while we are wanting to sleep, to prevent any
925     * activities from being started/resumed.
926     */
927    private boolean mSleeping = false;
928
929    /**
930     * Set while we are running a voice interaction.  This overrides
931     * sleeping while it is active.
932     */
933    private boolean mRunningVoice = false;
934
935    /**
936     * State of external calls telling us if the device is asleep.
937     */
938    private boolean mWentToSleep = false;
939
940    /**
941     * State of external call telling us if the lock screen is shown.
942     */
943    private boolean mLockScreenShown = false;
944
945    /**
946     * Set if we are shutting down the system, similar to sleeping.
947     */
948    boolean mShuttingDown = false;
949
950    /**
951     * Current sequence id for oom_adj computation traversal.
952     */
953    int mAdjSeq = 0;
954
955    /**
956     * Current sequence id for process LRU updating.
957     */
958    int mLruSeq = 0;
959
960    /**
961     * Keep track of the non-cached/empty process we last found, to help
962     * determine how to distribute cached/empty processes next time.
963     */
964    int mNumNonCachedProcs = 0;
965
966    /**
967     * Keep track of the number of cached hidden procs, to balance oom adj
968     * distribution between those and empty procs.
969     */
970    int mNumCachedHiddenProcs = 0;
971
972    /**
973     * Keep track of the number of service processes we last found, to
974     * determine on the next iteration which should be B services.
975     */
976    int mNumServiceProcs = 0;
977    int mNewNumAServiceProcs = 0;
978    int mNewNumServiceProcs = 0;
979
980    /**
981     * Allow the current computed overall memory level of the system to go down?
982     * This is set to false when we are killing processes for reasons other than
983     * memory management, so that the now smaller process list will not be taken as
984     * an indication that memory is tighter.
985     */
986    boolean mAllowLowerMemLevel = false;
987
988    /**
989     * The last computed memory level, for holding when we are in a state that
990     * processes are going away for other reasons.
991     */
992    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
993
994    /**
995     * The last total number of process we have, to determine if changes actually look
996     * like a shrinking number of process due to lower RAM.
997     */
998    int mLastNumProcesses;
999
1000    /**
1001     * The uptime of the last time we performed idle maintenance.
1002     */
1003    long mLastIdleTime = SystemClock.uptimeMillis();
1004
1005    /**
1006     * Total time spent with RAM that has been added in the past since the last idle time.
1007     */
1008    long mLowRamTimeSinceLastIdle = 0;
1009
1010    /**
1011     * If RAM is currently low, when that horrible situation started.
1012     */
1013    long mLowRamStartTime = 0;
1014
1015    /**
1016     * For reporting to battery stats the current top application.
1017     */
1018    private String mCurResumedPackage = null;
1019    private int mCurResumedUid = -1;
1020
1021    /**
1022     * For reporting to battery stats the apps currently running foreground
1023     * service.  The ProcessMap is package/uid tuples; each of these contain
1024     * an array of the currently foreground processes.
1025     */
1026    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1027            = new ProcessMap<ArrayList<ProcessRecord>>();
1028
1029    /**
1030     * This is set if we had to do a delayed dexopt of an app before launching
1031     * it, to increase the ANR timeouts in that case.
1032     */
1033    boolean mDidDexOpt;
1034
1035    /**
1036     * Set if the systemServer made a call to enterSafeMode.
1037     */
1038    boolean mSafeMode;
1039
1040    String mDebugApp = null;
1041    boolean mWaitForDebugger = false;
1042    boolean mDebugTransient = false;
1043    String mOrigDebugApp = null;
1044    boolean mOrigWaitForDebugger = false;
1045    boolean mAlwaysFinishActivities = false;
1046    IActivityController mController = null;
1047    String mProfileApp = null;
1048    ProcessRecord mProfileProc = null;
1049    String mProfileFile;
1050    ParcelFileDescriptor mProfileFd;
1051    int mSamplingInterval = 0;
1052    boolean mAutoStopProfiler = false;
1053    int mProfileType = 0;
1054    String mOpenGlTraceApp = null;
1055
1056    static class ProcessChangeItem {
1057        static final int CHANGE_ACTIVITIES = 1<<0;
1058        static final int CHANGE_PROCESS_STATE = 1<<1;
1059        int changes;
1060        int uid;
1061        int pid;
1062        int processState;
1063        boolean foregroundActivities;
1064    }
1065
1066    final RemoteCallbackList<IProcessObserver> mProcessObservers
1067            = new RemoteCallbackList<IProcessObserver>();
1068    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1069
1070    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1071            = new ArrayList<ProcessChangeItem>();
1072    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1073            = new ArrayList<ProcessChangeItem>();
1074
1075    /**
1076     * Runtime CPU use collection thread.  This object's lock is used to
1077     * protect all related state.
1078     */
1079    final Thread mProcessCpuThread;
1080
1081    /**
1082     * Used to collect process stats when showing not responding dialog.
1083     * Protected by mProcessCpuThread.
1084     */
1085    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1086            MONITOR_THREAD_CPU_USAGE);
1087    final AtomicLong mLastCpuTime = new AtomicLong(0);
1088    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1089
1090    long mLastWriteTime = 0;
1091
1092    /**
1093     * Used to retain an update lock when the foreground activity is in
1094     * immersive mode.
1095     */
1096    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1097
1098    /**
1099     * Set to true after the system has finished booting.
1100     */
1101    boolean mBooted = false;
1102
1103    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1104    int mProcessLimitOverride = -1;
1105
1106    WindowManagerService mWindowManager;
1107
1108    final ActivityThread mSystemThread;
1109
1110    int mCurrentUserId = 0;
1111    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1112
1113    /**
1114     * Mapping from each known user ID to the profile group ID it is associated with.
1115     */
1116    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1117
1118    private UserManagerService mUserManager;
1119
1120    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1121        final ProcessRecord mApp;
1122        final int mPid;
1123        final IApplicationThread mAppThread;
1124
1125        AppDeathRecipient(ProcessRecord app, int pid,
1126                IApplicationThread thread) {
1127            if (localLOGV) Slog.v(
1128                TAG, "New death recipient " + this
1129                + " for thread " + thread.asBinder());
1130            mApp = app;
1131            mPid = pid;
1132            mAppThread = thread;
1133        }
1134
1135        @Override
1136        public void binderDied() {
1137            if (localLOGV) Slog.v(
1138                TAG, "Death received in " + this
1139                + " for thread " + mAppThread.asBinder());
1140            synchronized(ActivityManagerService.this) {
1141                appDiedLocked(mApp, mPid, mAppThread);
1142            }
1143        }
1144    }
1145
1146    static final int SHOW_ERROR_MSG = 1;
1147    static final int SHOW_NOT_RESPONDING_MSG = 2;
1148    static final int SHOW_FACTORY_ERROR_MSG = 3;
1149    static final int UPDATE_CONFIGURATION_MSG = 4;
1150    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1151    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1152    static final int SERVICE_TIMEOUT_MSG = 12;
1153    static final int UPDATE_TIME_ZONE = 13;
1154    static final int SHOW_UID_ERROR_MSG = 14;
1155    static final int IM_FEELING_LUCKY_MSG = 15;
1156    static final int PROC_START_TIMEOUT_MSG = 20;
1157    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1158    static final int KILL_APPLICATION_MSG = 22;
1159    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1160    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1161    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1162    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1163    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1164    static final int CLEAR_DNS_CACHE_MSG = 28;
1165    static final int UPDATE_HTTP_PROXY_MSG = 29;
1166    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1167    static final int DISPATCH_PROCESSES_CHANGED = 31;
1168    static final int DISPATCH_PROCESS_DIED = 32;
1169    static final int REPORT_MEM_USAGE_MSG = 33;
1170    static final int REPORT_USER_SWITCH_MSG = 34;
1171    static final int CONTINUE_USER_SWITCH_MSG = 35;
1172    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1173    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1174    static final int PERSIST_URI_GRANTS_MSG = 38;
1175    static final int REQUEST_ALL_PSS_MSG = 39;
1176    static final int START_PROFILES_MSG = 40;
1177    static final int UPDATE_TIME = 41;
1178    static final int SYSTEM_USER_START_MSG = 42;
1179    static final int SYSTEM_USER_CURRENT_MSG = 43;
1180    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1181    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1182    static final int START_USER_SWITCH_MSG = 46;
1183
1184    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1185    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1186    static final int FIRST_COMPAT_MODE_MSG = 300;
1187    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1188
1189    AlertDialog mUidAlert;
1190    CompatModeDialog mCompatModeDialog;
1191    long mLastMemUsageReportTime = 0;
1192
1193    private LockToAppRequestDialog mLockToAppRequest;
1194
1195    /**
1196     * Flag whether the current user is a "monkey", i.e. whether
1197     * the UI is driven by a UI automation tool.
1198     */
1199    private boolean mUserIsMonkey;
1200
1201    /** Flag whether the device has a recents UI */
1202    final boolean mHasRecents;
1203
1204    final int mThumbnailWidth;
1205    final int mThumbnailHeight;
1206
1207    final ServiceThread mHandlerThread;
1208    final MainHandler mHandler;
1209
1210    final class MainHandler extends Handler {
1211        public MainHandler(Looper looper) {
1212            super(looper, null, true);
1213        }
1214
1215        @Override
1216        public void handleMessage(Message msg) {
1217            switch (msg.what) {
1218            case SHOW_ERROR_MSG: {
1219                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1220                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1221                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1222                synchronized (ActivityManagerService.this) {
1223                    ProcessRecord proc = (ProcessRecord)data.get("app");
1224                    AppErrorResult res = (AppErrorResult) data.get("result");
1225                    if (proc != null && proc.crashDialog != null) {
1226                        Slog.e(TAG, "App already has crash dialog: " + proc);
1227                        if (res != null) {
1228                            res.set(0);
1229                        }
1230                        return;
1231                    }
1232                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1233                            >= Process.FIRST_APPLICATION_UID
1234                            && proc.pid != MY_PID);
1235                    for (int userId : mCurrentProfileIds) {
1236                        isBackground &= (proc.userId != userId);
1237                    }
1238                    if (isBackground && !showBackground) {
1239                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1240                        if (res != null) {
1241                            res.set(0);
1242                        }
1243                        return;
1244                    }
1245                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1246                        Dialog d = new AppErrorDialog(mContext,
1247                                ActivityManagerService.this, res, proc);
1248                        d.show();
1249                        proc.crashDialog = d;
1250                    } else {
1251                        // The device is asleep, so just pretend that the user
1252                        // saw a crash dialog and hit "force quit".
1253                        if (res != null) {
1254                            res.set(0);
1255                        }
1256                    }
1257                }
1258
1259                ensureBootCompleted();
1260            } break;
1261            case SHOW_NOT_RESPONDING_MSG: {
1262                synchronized (ActivityManagerService.this) {
1263                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1264                    ProcessRecord proc = (ProcessRecord)data.get("app");
1265                    if (proc != null && proc.anrDialog != null) {
1266                        Slog.e(TAG, "App already has anr dialog: " + proc);
1267                        return;
1268                    }
1269
1270                    Intent intent = new Intent("android.intent.action.ANR");
1271                    if (!mProcessesReady) {
1272                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1273                                | Intent.FLAG_RECEIVER_FOREGROUND);
1274                    }
1275                    broadcastIntentLocked(null, null, intent,
1276                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1277                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1278
1279                    if (mShowDialogs) {
1280                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1281                                mContext, proc, (ActivityRecord)data.get("activity"),
1282                                msg.arg1 != 0);
1283                        d.show();
1284                        proc.anrDialog = d;
1285                    } else {
1286                        // Just kill the app if there is no dialog to be shown.
1287                        killAppAtUsersRequest(proc, null);
1288                    }
1289                }
1290
1291                ensureBootCompleted();
1292            } break;
1293            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1294                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1295                synchronized (ActivityManagerService.this) {
1296                    ProcessRecord proc = (ProcessRecord) data.get("app");
1297                    if (proc == null) {
1298                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1299                        break;
1300                    }
1301                    if (proc.crashDialog != null) {
1302                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1303                        return;
1304                    }
1305                    AppErrorResult res = (AppErrorResult) data.get("result");
1306                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1307                        Dialog d = new StrictModeViolationDialog(mContext,
1308                                ActivityManagerService.this, res, proc);
1309                        d.show();
1310                        proc.crashDialog = d;
1311                    } else {
1312                        // The device is asleep, so just pretend that the user
1313                        // saw a crash dialog and hit "force quit".
1314                        res.set(0);
1315                    }
1316                }
1317                ensureBootCompleted();
1318            } break;
1319            case SHOW_FACTORY_ERROR_MSG: {
1320                Dialog d = new FactoryErrorDialog(
1321                    mContext, msg.getData().getCharSequence("msg"));
1322                d.show();
1323                ensureBootCompleted();
1324            } break;
1325            case UPDATE_CONFIGURATION_MSG: {
1326                final ContentResolver resolver = mContext.getContentResolver();
1327                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1328            } break;
1329            case GC_BACKGROUND_PROCESSES_MSG: {
1330                synchronized (ActivityManagerService.this) {
1331                    performAppGcsIfAppropriateLocked();
1332                }
1333            } break;
1334            case WAIT_FOR_DEBUGGER_MSG: {
1335                synchronized (ActivityManagerService.this) {
1336                    ProcessRecord app = (ProcessRecord)msg.obj;
1337                    if (msg.arg1 != 0) {
1338                        if (!app.waitedForDebugger) {
1339                            Dialog d = new AppWaitingForDebuggerDialog(
1340                                    ActivityManagerService.this,
1341                                    mContext, app);
1342                            app.waitDialog = d;
1343                            app.waitedForDebugger = true;
1344                            d.show();
1345                        }
1346                    } else {
1347                        if (app.waitDialog != null) {
1348                            app.waitDialog.dismiss();
1349                            app.waitDialog = null;
1350                        }
1351                    }
1352                }
1353            } break;
1354            case SERVICE_TIMEOUT_MSG: {
1355                if (mDidDexOpt) {
1356                    mDidDexOpt = false;
1357                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1358                    nmsg.obj = msg.obj;
1359                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1360                    return;
1361                }
1362                mServices.serviceTimeout((ProcessRecord)msg.obj);
1363            } break;
1364            case UPDATE_TIME_ZONE: {
1365                synchronized (ActivityManagerService.this) {
1366                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1367                        ProcessRecord r = mLruProcesses.get(i);
1368                        if (r.thread != null) {
1369                            try {
1370                                r.thread.updateTimeZone();
1371                            } catch (RemoteException ex) {
1372                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1373                            }
1374                        }
1375                    }
1376                }
1377            } break;
1378            case CLEAR_DNS_CACHE_MSG: {
1379                synchronized (ActivityManagerService.this) {
1380                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1381                        ProcessRecord r = mLruProcesses.get(i);
1382                        if (r.thread != null) {
1383                            try {
1384                                r.thread.clearDnsCache();
1385                            } catch (RemoteException ex) {
1386                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1387                            }
1388                        }
1389                    }
1390                }
1391            } break;
1392            case UPDATE_HTTP_PROXY_MSG: {
1393                ProxyInfo proxy = (ProxyInfo)msg.obj;
1394                String host = "";
1395                String port = "";
1396                String exclList = "";
1397                Uri pacFileUrl = Uri.EMPTY;
1398                if (proxy != null) {
1399                    host = proxy.getHost();
1400                    port = Integer.toString(proxy.getPort());
1401                    exclList = proxy.getExclusionListAsString();
1402                    pacFileUrl = proxy.getPacFileUrl();
1403                }
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to update http proxy for: " +
1412                                        r.info.processName);
1413                            }
1414                        }
1415                    }
1416                }
1417            } break;
1418            case SHOW_UID_ERROR_MSG: {
1419                String title = "System UIDs Inconsistent";
1420                String text = "UIDs on the system are inconsistent, you need to wipe your"
1421                        + " data partition or your device will be unstable.";
1422                Log.e(TAG, title + ": " + text);
1423                if (mShowDialogs) {
1424                    // XXX This is a temporary dialog, no need to localize.
1425                    AlertDialog d = new BaseErrorDialog(mContext);
1426                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1427                    d.setCancelable(false);
1428                    d.setTitle(title);
1429                    d.setMessage(text);
1430                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1431                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1432                    mUidAlert = d;
1433                    d.show();
1434                }
1435            } break;
1436            case IM_FEELING_LUCKY_MSG: {
1437                if (mUidAlert != null) {
1438                    mUidAlert.dismiss();
1439                    mUidAlert = null;
1440                }
1441            } break;
1442            case PROC_START_TIMEOUT_MSG: {
1443                if (mDidDexOpt) {
1444                    mDidDexOpt = false;
1445                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1446                    nmsg.obj = msg.obj;
1447                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1448                    return;
1449                }
1450                ProcessRecord app = (ProcessRecord)msg.obj;
1451                synchronized (ActivityManagerService.this) {
1452                    processStartTimedOutLocked(app);
1453                }
1454            } break;
1455            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1456                synchronized (ActivityManagerService.this) {
1457                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1458                }
1459            } break;
1460            case KILL_APPLICATION_MSG: {
1461                synchronized (ActivityManagerService.this) {
1462                    int appid = msg.arg1;
1463                    boolean restart = (msg.arg2 == 1);
1464                    Bundle bundle = (Bundle)msg.obj;
1465                    String pkg = bundle.getString("pkg");
1466                    String reason = bundle.getString("reason");
1467                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1468                            false, UserHandle.USER_ALL, reason);
1469                }
1470            } break;
1471            case FINALIZE_PENDING_INTENT_MSG: {
1472                ((PendingIntentRecord)msg.obj).completeFinalize();
1473            } break;
1474            case POST_HEAVY_NOTIFICATION_MSG: {
1475                INotificationManager inm = NotificationManager.getService();
1476                if (inm == null) {
1477                    return;
1478                }
1479
1480                ActivityRecord root = (ActivityRecord)msg.obj;
1481                ProcessRecord process = root.app;
1482                if (process == null) {
1483                    return;
1484                }
1485
1486                try {
1487                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1488                    String text = mContext.getString(R.string.heavy_weight_notification,
1489                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1490                    Notification notification = new Notification();
1491                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1492                    notification.when = 0;
1493                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1494                    notification.tickerText = text;
1495                    notification.defaults = 0; // please be quiet
1496                    notification.sound = null;
1497                    notification.vibrate = null;
1498                    notification.color = mContext.getResources().getColor(
1499                            com.android.internal.R.color.system_notification_accent_color);
1500                    notification.setLatestEventInfo(context, text,
1501                            mContext.getText(R.string.heavy_weight_notification_detail),
1502                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1503                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1504                                    new UserHandle(root.userId)));
1505
1506                    try {
1507                        int[] outId = new int[1];
1508                        inm.enqueueNotificationWithTag("android", "android", null,
1509                                R.string.heavy_weight_notification,
1510                                notification, outId, root.userId);
1511                    } catch (RuntimeException e) {
1512                        Slog.w(ActivityManagerService.TAG,
1513                                "Error showing notification for heavy-weight app", e);
1514                    } catch (RemoteException e) {
1515                    }
1516                } catch (NameNotFoundException e) {
1517                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1518                }
1519            } break;
1520            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1521                INotificationManager inm = NotificationManager.getService();
1522                if (inm == null) {
1523                    return;
1524                }
1525                try {
1526                    inm.cancelNotificationWithTag("android", null,
1527                            R.string.heavy_weight_notification,  msg.arg1);
1528                } catch (RuntimeException e) {
1529                    Slog.w(ActivityManagerService.TAG,
1530                            "Error canceling notification for service", e);
1531                } catch (RemoteException e) {
1532                }
1533            } break;
1534            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1535                synchronized (ActivityManagerService.this) {
1536                    checkExcessivePowerUsageLocked(true);
1537                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1538                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1539                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1540                }
1541            } break;
1542            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1543                synchronized (ActivityManagerService.this) {
1544                    ActivityRecord ar = (ActivityRecord)msg.obj;
1545                    if (mCompatModeDialog != null) {
1546                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1547                                ar.info.applicationInfo.packageName)) {
1548                            return;
1549                        }
1550                        mCompatModeDialog.dismiss();
1551                        mCompatModeDialog = null;
1552                    }
1553                    if (ar != null && false) {
1554                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1555                                ar.packageName)) {
1556                            int mode = mCompatModePackages.computeCompatModeLocked(
1557                                    ar.info.applicationInfo);
1558                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1559                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1560                                mCompatModeDialog = new CompatModeDialog(
1561                                        ActivityManagerService.this, mContext,
1562                                        ar.info.applicationInfo);
1563                                mCompatModeDialog.show();
1564                            }
1565                        }
1566                    }
1567                }
1568                break;
1569            }
1570            case DISPATCH_PROCESSES_CHANGED: {
1571                dispatchProcessesChanged();
1572                break;
1573            }
1574            case DISPATCH_PROCESS_DIED: {
1575                final int pid = msg.arg1;
1576                final int uid = msg.arg2;
1577                dispatchProcessDied(pid, uid);
1578                break;
1579            }
1580            case REPORT_MEM_USAGE_MSG: {
1581                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1582                Thread thread = new Thread() {
1583                    @Override public void run() {
1584                        final SparseArray<ProcessMemInfo> infoMap
1585                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1586                        for (int i=0, N=memInfos.size(); i<N; i++) {
1587                            ProcessMemInfo mi = memInfos.get(i);
1588                            infoMap.put(mi.pid, mi);
1589                        }
1590                        updateCpuStatsNow();
1591                        synchronized (mProcessCpuThread) {
1592                            final int N = mProcessCpuTracker.countStats();
1593                            for (int i=0; i<N; i++) {
1594                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1595                                if (st.vsize > 0) {
1596                                    long pss = Debug.getPss(st.pid, null);
1597                                    if (pss > 0) {
1598                                        if (infoMap.indexOfKey(st.pid) < 0) {
1599                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1600                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1601                                            mi.pss = pss;
1602                                            memInfos.add(mi);
1603                                        }
1604                                    }
1605                                }
1606                            }
1607                        }
1608
1609                        long totalPss = 0;
1610                        for (int i=0, N=memInfos.size(); i<N; i++) {
1611                            ProcessMemInfo mi = memInfos.get(i);
1612                            if (mi.pss == 0) {
1613                                mi.pss = Debug.getPss(mi.pid, null);
1614                            }
1615                            totalPss += mi.pss;
1616                        }
1617                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1618                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1619                                if (lhs.oomAdj != rhs.oomAdj) {
1620                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1621                                }
1622                                if (lhs.pss != rhs.pss) {
1623                                    return lhs.pss < rhs.pss ? 1 : -1;
1624                                }
1625                                return 0;
1626                            }
1627                        });
1628
1629                        StringBuilder tag = new StringBuilder(128);
1630                        StringBuilder stack = new StringBuilder(128);
1631                        tag.append("Low on memory -- ");
1632                        appendMemBucket(tag, totalPss, "total", false);
1633                        appendMemBucket(stack, totalPss, "total", true);
1634
1635                        StringBuilder logBuilder = new StringBuilder(1024);
1636                        logBuilder.append("Low on memory:\n");
1637
1638                        boolean firstLine = true;
1639                        int lastOomAdj = Integer.MIN_VALUE;
1640                        for (int i=0, N=memInfos.size(); i<N; i++) {
1641                            ProcessMemInfo mi = memInfos.get(i);
1642
1643                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1644                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1645                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1646                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1647                                if (lastOomAdj != mi.oomAdj) {
1648                                    lastOomAdj = mi.oomAdj;
1649                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1650                                        tag.append(" / ");
1651                                    }
1652                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1653                                        if (firstLine) {
1654                                            stack.append(":");
1655                                            firstLine = false;
1656                                        }
1657                                        stack.append("\n\t at ");
1658                                    } else {
1659                                        stack.append("$");
1660                                    }
1661                                } else {
1662                                    tag.append(" ");
1663                                    stack.append("$");
1664                                }
1665                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1666                                    appendMemBucket(tag, mi.pss, mi.name, false);
1667                                }
1668                                appendMemBucket(stack, mi.pss, mi.name, true);
1669                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1670                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1671                                    stack.append("(");
1672                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1673                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1674                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1675                                            stack.append(":");
1676                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1677                                        }
1678                                    }
1679                                    stack.append(")");
1680                                }
1681                            }
1682
1683                            logBuilder.append("  ");
1684                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1685                            logBuilder.append(' ');
1686                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1687                            logBuilder.append(' ');
1688                            ProcessList.appendRamKb(logBuilder, mi.pss);
1689                            logBuilder.append(" kB: ");
1690                            logBuilder.append(mi.name);
1691                            logBuilder.append(" (");
1692                            logBuilder.append(mi.pid);
1693                            logBuilder.append(") ");
1694                            logBuilder.append(mi.adjType);
1695                            logBuilder.append('\n');
1696                            if (mi.adjReason != null) {
1697                                logBuilder.append("                      ");
1698                                logBuilder.append(mi.adjReason);
1699                                logBuilder.append('\n');
1700                            }
1701                        }
1702
1703                        logBuilder.append("           ");
1704                        ProcessList.appendRamKb(logBuilder, totalPss);
1705                        logBuilder.append(" kB: TOTAL\n");
1706
1707                        long[] infos = new long[Debug.MEMINFO_COUNT];
1708                        Debug.getMemInfo(infos);
1709                        logBuilder.append("  MemInfo: ");
1710                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1711                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1712                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1713                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1714                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1715                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1716                            logBuilder.append("  ZRAM: ");
1717                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1718                            logBuilder.append(" kB RAM, ");
1719                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1720                            logBuilder.append(" kB swap total, ");
1721                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1722                            logBuilder.append(" kB swap free\n");
1723                        }
1724                        Slog.i(TAG, logBuilder.toString());
1725
1726                        StringBuilder dropBuilder = new StringBuilder(1024);
1727                        /*
1728                        StringWriter oomSw = new StringWriter();
1729                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1730                        StringWriter catSw = new StringWriter();
1731                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1732                        String[] emptyArgs = new String[] { };
1733                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1734                        oomPw.flush();
1735                        String oomString = oomSw.toString();
1736                        */
1737                        dropBuilder.append(stack);
1738                        dropBuilder.append('\n');
1739                        dropBuilder.append('\n');
1740                        dropBuilder.append(logBuilder);
1741                        dropBuilder.append('\n');
1742                        /*
1743                        dropBuilder.append(oomString);
1744                        dropBuilder.append('\n');
1745                        */
1746                        StringWriter catSw = new StringWriter();
1747                        synchronized (ActivityManagerService.this) {
1748                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1749                            String[] emptyArgs = new String[] { };
1750                            catPw.println();
1751                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1752                            catPw.println();
1753                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1754                                    false, false, null);
1755                            catPw.println();
1756                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1757                            catPw.flush();
1758                        }
1759                        dropBuilder.append(catSw.toString());
1760                        addErrorToDropBox("lowmem", null, "system_server", null,
1761                                null, tag.toString(), dropBuilder.toString(), null, null);
1762                        //Slog.i(TAG, "Sent to dropbox:");
1763                        //Slog.i(TAG, dropBuilder.toString());
1764                        synchronized (ActivityManagerService.this) {
1765                            long now = SystemClock.uptimeMillis();
1766                            if (mLastMemUsageReportTime < now) {
1767                                mLastMemUsageReportTime = now;
1768                            }
1769                        }
1770                    }
1771                };
1772                thread.start();
1773                break;
1774            }
1775            case START_USER_SWITCH_MSG: {
1776                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1777                break;
1778            }
1779            case REPORT_USER_SWITCH_MSG: {
1780                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1781                break;
1782            }
1783            case CONTINUE_USER_SWITCH_MSG: {
1784                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1785                break;
1786            }
1787            case USER_SWITCH_TIMEOUT_MSG: {
1788                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1789                break;
1790            }
1791            case IMMERSIVE_MODE_LOCK_MSG: {
1792                final boolean nextState = (msg.arg1 != 0);
1793                if (mUpdateLock.isHeld() != nextState) {
1794                    if (DEBUG_IMMERSIVE) {
1795                        final ActivityRecord r = (ActivityRecord) msg.obj;
1796                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1797                    }
1798                    if (nextState) {
1799                        mUpdateLock.acquire();
1800                    } else {
1801                        mUpdateLock.release();
1802                    }
1803                }
1804                break;
1805            }
1806            case PERSIST_URI_GRANTS_MSG: {
1807                writeGrantedUriPermissions();
1808                break;
1809            }
1810            case REQUEST_ALL_PSS_MSG: {
1811                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1812                break;
1813            }
1814            case START_PROFILES_MSG: {
1815                synchronized (ActivityManagerService.this) {
1816                    startProfilesLocked();
1817                }
1818                break;
1819            }
1820            case UPDATE_TIME: {
1821                synchronized (ActivityManagerService.this) {
1822                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1823                        ProcessRecord r = mLruProcesses.get(i);
1824                        if (r.thread != null) {
1825                            try {
1826                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1827                            } catch (RemoteException ex) {
1828                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1829                            }
1830                        }
1831                    }
1832                }
1833                break;
1834            }
1835            case SYSTEM_USER_START_MSG: {
1836                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1837                        Integer.toString(msg.arg1), msg.arg1);
1838                mSystemServiceManager.startUser(msg.arg1);
1839                break;
1840            }
1841            case SYSTEM_USER_CURRENT_MSG: {
1842                mBatteryStatsService.noteEvent(
1843                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1844                        Integer.toString(msg.arg2), msg.arg2);
1845                mBatteryStatsService.noteEvent(
1846                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1847                        Integer.toString(msg.arg1), msg.arg1);
1848                mSystemServiceManager.switchUser(msg.arg1);
1849                mLockToAppRequest.clearPrompt();
1850                break;
1851            }
1852            case ENTER_ANIMATION_COMPLETE_MSG: {
1853                synchronized (ActivityManagerService.this) {
1854                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1855                    if (r != null && r.app != null && r.app.thread != null) {
1856                        try {
1857                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1858                        } catch (RemoteException e) {
1859                        }
1860                    }
1861                }
1862                break;
1863            }
1864            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1865                enableScreenAfterBoot();
1866                break;
1867            }
1868            }
1869        }
1870    };
1871
1872    static final int COLLECT_PSS_BG_MSG = 1;
1873
1874    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1875        @Override
1876        public void handleMessage(Message msg) {
1877            switch (msg.what) {
1878            case COLLECT_PSS_BG_MSG: {
1879                long start = SystemClock.uptimeMillis();
1880                MemInfoReader memInfo = null;
1881                synchronized (ActivityManagerService.this) {
1882                    if (mFullPssPending) {
1883                        mFullPssPending = false;
1884                        memInfo = new MemInfoReader();
1885                    }
1886                }
1887                if (memInfo != null) {
1888                    updateCpuStatsNow();
1889                    long nativeTotalPss = 0;
1890                    synchronized (mProcessCpuThread) {
1891                        final int N = mProcessCpuTracker.countStats();
1892                        for (int j=0; j<N; j++) {
1893                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1894                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1895                                // This is definitely an application process; skip it.
1896                                continue;
1897                            }
1898                            synchronized (mPidsSelfLocked) {
1899                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1900                                    // This is one of our own processes; skip it.
1901                                    continue;
1902                                }
1903                            }
1904                            nativeTotalPss += Debug.getPss(st.pid, null);
1905                        }
1906                    }
1907                    memInfo.readMemInfo();
1908                    synchronized (this) {
1909                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1910                                + (SystemClock.uptimeMillis()-start) + "ms");
1911                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1912                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1913                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1914                                        +memInfo.getSlabSizeKb(),
1915                                nativeTotalPss);
1916                    }
1917                }
1918
1919                int i=0, num=0;
1920                long[] tmp = new long[1];
1921                do {
1922                    ProcessRecord proc;
1923                    int procState;
1924                    int pid;
1925                    synchronized (ActivityManagerService.this) {
1926                        if (i >= mPendingPssProcesses.size()) {
1927                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1928                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1929                            mPendingPssProcesses.clear();
1930                            return;
1931                        }
1932                        proc = mPendingPssProcesses.get(i);
1933                        procState = proc.pssProcState;
1934                        if (proc.thread != null && procState == proc.setProcState) {
1935                            pid = proc.pid;
1936                        } else {
1937                            proc = null;
1938                            pid = 0;
1939                        }
1940                        i++;
1941                    }
1942                    if (proc != null) {
1943                        long pss = Debug.getPss(pid, tmp);
1944                        synchronized (ActivityManagerService.this) {
1945                            if (proc.thread != null && proc.setProcState == procState
1946                                    && proc.pid == pid) {
1947                                num++;
1948                                proc.lastPssTime = SystemClock.uptimeMillis();
1949                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1950                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1951                                        + ": " + pss + " lastPss=" + proc.lastPss
1952                                        + " state=" + ProcessList.makeProcStateString(procState));
1953                                if (proc.initialIdlePss == 0) {
1954                                    proc.initialIdlePss = pss;
1955                                }
1956                                proc.lastPss = pss;
1957                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1958                                    proc.lastCachedPss = pss;
1959                                }
1960                            }
1961                        }
1962                    }
1963                } while (true);
1964            }
1965            }
1966        }
1967    };
1968
1969    /**
1970     * Monitor for package changes and update our internal state.
1971     */
1972    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1973        @Override
1974        public void onPackageRemoved(String packageName, int uid) {
1975            // Remove all tasks with activities in the specified package from the list of recent tasks
1976            synchronized (ActivityManagerService.this) {
1977                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1978                    TaskRecord tr = mRecentTasks.get(i);
1979                    ComponentName cn = tr.intent.getComponent();
1980                    if (cn != null && cn.getPackageName().equals(packageName)) {
1981                        // If the package name matches, remove the task and kill the process
1982                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1983                    }
1984                }
1985            }
1986        }
1987
1988        @Override
1989        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1990            onPackageModified(packageName);
1991            return true;
1992        }
1993
1994        @Override
1995        public void onPackageModified(String packageName) {
1996            final PackageManager pm = mContext.getPackageManager();
1997            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1998                    new ArrayList<Pair<Intent, Integer>>();
1999            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2000            // Copy the list of recent tasks so that we don't hold onto the lock on
2001            // ActivityManagerService for long periods while checking if components exist.
2002            synchronized (ActivityManagerService.this) {
2003                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2004                    TaskRecord tr = mRecentTasks.get(i);
2005                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2006                }
2007            }
2008            // Check the recent tasks and filter out all tasks with components that no longer exist.
2009            Intent tmpI = new Intent();
2010            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2011                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2012                ComponentName cn = p.first.getComponent();
2013                if (cn != null && cn.getPackageName().equals(packageName)) {
2014                    try {
2015                        // Add the task to the list to remove if the component no longer exists
2016                        tmpI.setComponent(cn);
2017                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2018                            tasksToRemove.add(p.second);
2019                        }
2020                    } catch (Exception e) {}
2021                }
2022            }
2023            // Prune all the tasks with removed components from the list of recent tasks
2024            synchronized (ActivityManagerService.this) {
2025                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2026                    // Remove the task but don't kill the process (since other components in that
2027                    // package may still be running and in the background)
2028                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2029                }
2030            }
2031        }
2032
2033        @Override
2034        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2035            // Force stop the specified packages
2036            if (packages != null) {
2037                for (String pkg : packages) {
2038                    synchronized (ActivityManagerService.this) {
2039                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2040                                "finished booting")) {
2041                            return true;
2042                        }
2043                    }
2044                }
2045            }
2046            return false;
2047        }
2048    };
2049
2050    public void setSystemProcess() {
2051        try {
2052            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2053            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2054            ServiceManager.addService("meminfo", new MemBinder(this));
2055            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2056            ServiceManager.addService("dbinfo", new DbBinder(this));
2057            if (MONITOR_CPU_USAGE) {
2058                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2059            }
2060            ServiceManager.addService("permission", new PermissionController(this));
2061
2062            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2063                    "android", STOCK_PM_FLAGS);
2064            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2065
2066            synchronized (this) {
2067                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2068                app.persistent = true;
2069                app.pid = MY_PID;
2070                app.maxAdj = ProcessList.SYSTEM_ADJ;
2071                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2072                mProcessNames.put(app.processName, app.uid, app);
2073                synchronized (mPidsSelfLocked) {
2074                    mPidsSelfLocked.put(app.pid, app);
2075                }
2076                updateLruProcessLocked(app, false, null);
2077                updateOomAdjLocked();
2078            }
2079        } catch (PackageManager.NameNotFoundException e) {
2080            throw new RuntimeException(
2081                    "Unable to find android system package", e);
2082        }
2083    }
2084
2085    public void setWindowManager(WindowManagerService wm) {
2086        mWindowManager = wm;
2087        mStackSupervisor.setWindowManager(wm);
2088    }
2089
2090    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2091        mUsageStatsService = usageStatsManager;
2092    }
2093
2094    public void startObservingNativeCrashes() {
2095        final NativeCrashListener ncl = new NativeCrashListener(this);
2096        ncl.start();
2097    }
2098
2099    public IAppOpsService getAppOpsService() {
2100        return mAppOpsService;
2101    }
2102
2103    static class MemBinder extends Binder {
2104        ActivityManagerService mActivityManagerService;
2105        MemBinder(ActivityManagerService activityManagerService) {
2106            mActivityManagerService = activityManagerService;
2107        }
2108
2109        @Override
2110        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2111            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2112                    != PackageManager.PERMISSION_GRANTED) {
2113                pw.println("Permission Denial: can't dump meminfo from from pid="
2114                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2115                        + " without permission " + android.Manifest.permission.DUMP);
2116                return;
2117            }
2118
2119            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2120        }
2121    }
2122
2123    static class GraphicsBinder extends Binder {
2124        ActivityManagerService mActivityManagerService;
2125        GraphicsBinder(ActivityManagerService activityManagerService) {
2126            mActivityManagerService = activityManagerService;
2127        }
2128
2129        @Override
2130        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2131            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2132                    != PackageManager.PERMISSION_GRANTED) {
2133                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2134                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2135                        + " without permission " + android.Manifest.permission.DUMP);
2136                return;
2137            }
2138
2139            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2140        }
2141    }
2142
2143    static class DbBinder extends Binder {
2144        ActivityManagerService mActivityManagerService;
2145        DbBinder(ActivityManagerService activityManagerService) {
2146            mActivityManagerService = activityManagerService;
2147        }
2148
2149        @Override
2150        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2151            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2152                    != PackageManager.PERMISSION_GRANTED) {
2153                pw.println("Permission Denial: can't dump dbinfo from from pid="
2154                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2155                        + " without permission " + android.Manifest.permission.DUMP);
2156                return;
2157            }
2158
2159            mActivityManagerService.dumpDbInfo(fd, pw, args);
2160        }
2161    }
2162
2163    static class CpuBinder extends Binder {
2164        ActivityManagerService mActivityManagerService;
2165        CpuBinder(ActivityManagerService activityManagerService) {
2166            mActivityManagerService = activityManagerService;
2167        }
2168
2169        @Override
2170        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2171            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2172                    != PackageManager.PERMISSION_GRANTED) {
2173                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2174                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2175                        + " without permission " + android.Manifest.permission.DUMP);
2176                return;
2177            }
2178
2179            synchronized (mActivityManagerService.mProcessCpuThread) {
2180                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2181                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2182                        SystemClock.uptimeMillis()));
2183            }
2184        }
2185    }
2186
2187    public static final class Lifecycle extends SystemService {
2188        private final ActivityManagerService mService;
2189
2190        public Lifecycle(Context context) {
2191            super(context);
2192            mService = new ActivityManagerService(context);
2193        }
2194
2195        @Override
2196        public void onStart() {
2197            mService.start();
2198        }
2199
2200        public ActivityManagerService getService() {
2201            return mService;
2202        }
2203    }
2204
2205    // Note: This method is invoked on the main thread but may need to attach various
2206    // handlers to other threads.  So take care to be explicit about the looper.
2207    public ActivityManagerService(Context systemContext) {
2208        mContext = systemContext;
2209        mFactoryTest = FactoryTest.getMode();
2210        mSystemThread = ActivityThread.currentActivityThread();
2211
2212        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2213
2214        mHandlerThread = new ServiceThread(TAG,
2215                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2216        mHandlerThread.start();
2217        mHandler = new MainHandler(mHandlerThread.getLooper());
2218
2219        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2220                "foreground", BROADCAST_FG_TIMEOUT, false);
2221        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2222                "background", BROADCAST_BG_TIMEOUT, true);
2223        mBroadcastQueues[0] = mFgBroadcastQueue;
2224        mBroadcastQueues[1] = mBgBroadcastQueue;
2225
2226        mServices = new ActiveServices(this);
2227        mProviderMap = new ProviderMap(this);
2228
2229        // TODO: Move creation of battery stats service outside of activity manager service.
2230        File dataDir = Environment.getDataDirectory();
2231        File systemDir = new File(dataDir, "system");
2232        systemDir.mkdirs();
2233        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2234        mBatteryStatsService.getActiveStatistics().readLocked();
2235        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2236        mOnBattery = DEBUG_POWER ? true
2237                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2238        mBatteryStatsService.getActiveStatistics().setCallback(this);
2239
2240        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2241
2242        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2243
2244        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2245
2246        // User 0 is the first and only user that runs at boot.
2247        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2248        mUserLru.add(Integer.valueOf(0));
2249        updateStartedUserArrayLocked();
2250
2251        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2252            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2253
2254        mConfiguration.setToDefaults();
2255        mConfiguration.setLocale(Locale.getDefault());
2256
2257        mConfigurationSeq = mConfiguration.seq = 1;
2258        mProcessCpuTracker.init();
2259
2260        final Resources res = mContext.getResources();
2261        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
2262        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2263        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2264
2265        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2266        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2267        mStackSupervisor = new ActivityStackSupervisor(this);
2268        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2269
2270        mProcessCpuThread = new Thread("CpuTracker") {
2271            @Override
2272            public void run() {
2273                while (true) {
2274                    try {
2275                        try {
2276                            synchronized(this) {
2277                                final long now = SystemClock.uptimeMillis();
2278                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2279                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2280                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2281                                //        + ", write delay=" + nextWriteDelay);
2282                                if (nextWriteDelay < nextCpuDelay) {
2283                                    nextCpuDelay = nextWriteDelay;
2284                                }
2285                                if (nextCpuDelay > 0) {
2286                                    mProcessCpuMutexFree.set(true);
2287                                    this.wait(nextCpuDelay);
2288                                }
2289                            }
2290                        } catch (InterruptedException e) {
2291                        }
2292                        updateCpuStatsNow();
2293                    } catch (Exception e) {
2294                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2295                    }
2296                }
2297            }
2298        };
2299
2300        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2301
2302        Watchdog.getInstance().addMonitor(this);
2303        Watchdog.getInstance().addThread(mHandler);
2304    }
2305
2306    public void setSystemServiceManager(SystemServiceManager mgr) {
2307        mSystemServiceManager = mgr;
2308    }
2309
2310    private void start() {
2311        Process.removeAllProcessGroups();
2312        mProcessCpuThread.start();
2313
2314        mBatteryStatsService.publish(mContext);
2315        mAppOpsService.publish(mContext);
2316        Slog.d("AppOps", "AppOpsService published");
2317        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2318    }
2319
2320    public void initPowerManagement() {
2321        mStackSupervisor.initPowerManagement();
2322        mBatteryStatsService.initPowerManagement();
2323    }
2324
2325    @Override
2326    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2327            throws RemoteException {
2328        if (code == SYSPROPS_TRANSACTION) {
2329            // We need to tell all apps about the system property change.
2330            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2331            synchronized(this) {
2332                final int NP = mProcessNames.getMap().size();
2333                for (int ip=0; ip<NP; ip++) {
2334                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2335                    final int NA = apps.size();
2336                    for (int ia=0; ia<NA; ia++) {
2337                        ProcessRecord app = apps.valueAt(ia);
2338                        if (app.thread != null) {
2339                            procs.add(app.thread.asBinder());
2340                        }
2341                    }
2342                }
2343            }
2344
2345            int N = procs.size();
2346            for (int i=0; i<N; i++) {
2347                Parcel data2 = Parcel.obtain();
2348                try {
2349                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2350                } catch (RemoteException e) {
2351                }
2352                data2.recycle();
2353            }
2354        }
2355        try {
2356            return super.onTransact(code, data, reply, flags);
2357        } catch (RuntimeException e) {
2358            // The activity manager only throws security exceptions, so let's
2359            // log all others.
2360            if (!(e instanceof SecurityException)) {
2361                Slog.wtf(TAG, "Activity Manager Crash", e);
2362            }
2363            throw e;
2364        }
2365    }
2366
2367    void updateCpuStats() {
2368        final long now = SystemClock.uptimeMillis();
2369        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2370            return;
2371        }
2372        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2373            synchronized (mProcessCpuThread) {
2374                mProcessCpuThread.notify();
2375            }
2376        }
2377    }
2378
2379    void updateCpuStatsNow() {
2380        synchronized (mProcessCpuThread) {
2381            mProcessCpuMutexFree.set(false);
2382            final long now = SystemClock.uptimeMillis();
2383            boolean haveNewCpuStats = false;
2384
2385            if (MONITOR_CPU_USAGE &&
2386                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2387                mLastCpuTime.set(now);
2388                haveNewCpuStats = true;
2389                mProcessCpuTracker.update();
2390                //Slog.i(TAG, mProcessCpu.printCurrentState());
2391                //Slog.i(TAG, "Total CPU usage: "
2392                //        + mProcessCpu.getTotalCpuPercent() + "%");
2393
2394                // Slog the cpu usage if the property is set.
2395                if ("true".equals(SystemProperties.get("events.cpu"))) {
2396                    int user = mProcessCpuTracker.getLastUserTime();
2397                    int system = mProcessCpuTracker.getLastSystemTime();
2398                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2399                    int irq = mProcessCpuTracker.getLastIrqTime();
2400                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2401                    int idle = mProcessCpuTracker.getLastIdleTime();
2402
2403                    int total = user + system + iowait + irq + softIrq + idle;
2404                    if (total == 0) total = 1;
2405
2406                    EventLog.writeEvent(EventLogTags.CPU,
2407                            ((user+system+iowait+irq+softIrq) * 100) / total,
2408                            (user * 100) / total,
2409                            (system * 100) / total,
2410                            (iowait * 100) / total,
2411                            (irq * 100) / total,
2412                            (softIrq * 100) / total);
2413                }
2414            }
2415
2416            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2417            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2418            synchronized(bstats) {
2419                synchronized(mPidsSelfLocked) {
2420                    if (haveNewCpuStats) {
2421                        if (mOnBattery) {
2422                            int perc = bstats.startAddingCpuLocked();
2423                            int totalUTime = 0;
2424                            int totalSTime = 0;
2425                            final int N = mProcessCpuTracker.countStats();
2426                            for (int i=0; i<N; i++) {
2427                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2428                                if (!st.working) {
2429                                    continue;
2430                                }
2431                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2432                                int otherUTime = (st.rel_utime*perc)/100;
2433                                int otherSTime = (st.rel_stime*perc)/100;
2434                                totalUTime += otherUTime;
2435                                totalSTime += otherSTime;
2436                                if (pr != null) {
2437                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2438                                    if (ps == null || !ps.isActive()) {
2439                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2440                                                pr.info.uid, pr.processName);
2441                                    }
2442                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2443                                            st.rel_stime-otherSTime);
2444                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2445                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2446                                } else {
2447                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2448                                    if (ps == null || !ps.isActive()) {
2449                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2450                                                bstats.mapUid(st.uid), st.name);
2451                                    }
2452                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2453                                            st.rel_stime-otherSTime);
2454                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2455                                }
2456                            }
2457                            bstats.finishAddingCpuLocked(perc, totalUTime,
2458                                    totalSTime, cpuSpeedTimes);
2459                        }
2460                    }
2461                }
2462
2463                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2464                    mLastWriteTime = now;
2465                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2466                }
2467            }
2468        }
2469    }
2470
2471    @Override
2472    public void batteryNeedsCpuUpdate() {
2473        updateCpuStatsNow();
2474    }
2475
2476    @Override
2477    public void batteryPowerChanged(boolean onBattery) {
2478        // When plugging in, update the CPU stats first before changing
2479        // the plug state.
2480        updateCpuStatsNow();
2481        synchronized (this) {
2482            synchronized(mPidsSelfLocked) {
2483                mOnBattery = DEBUG_POWER ? true : onBattery;
2484            }
2485        }
2486    }
2487
2488    /**
2489     * Initialize the application bind args. These are passed to each
2490     * process when the bindApplication() IPC is sent to the process. They're
2491     * lazily setup to make sure the services are running when they're asked for.
2492     */
2493    private HashMap<String, IBinder> getCommonServicesLocked() {
2494        if (mAppBindArgs == null) {
2495            mAppBindArgs = new HashMap<String, IBinder>();
2496
2497            // Setup the application init args
2498            mAppBindArgs.put("package", ServiceManager.getService("package"));
2499            mAppBindArgs.put("window", ServiceManager.getService("window"));
2500            mAppBindArgs.put(Context.ALARM_SERVICE,
2501                    ServiceManager.getService(Context.ALARM_SERVICE));
2502        }
2503        return mAppBindArgs;
2504    }
2505
2506    final void setFocusedActivityLocked(ActivityRecord r) {
2507        if (mFocusedActivity != r) {
2508            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2509            mFocusedActivity = r;
2510            if (r.task != null && r.task.voiceInteractor != null) {
2511                startRunningVoiceLocked();
2512            } else {
2513                finishRunningVoiceLocked();
2514            }
2515            mStackSupervisor.setFocusedStack(r);
2516            if (r != null) {
2517                mWindowManager.setFocusedApp(r.appToken, true);
2518            }
2519            applyUpdateLockStateLocked(r);
2520        }
2521    }
2522
2523    final void clearFocusedActivity(ActivityRecord r) {
2524        if (mFocusedActivity == r) {
2525            mFocusedActivity = null;
2526        }
2527    }
2528
2529    @Override
2530    public void setFocusedStack(int stackId) {
2531        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2532        synchronized (ActivityManagerService.this) {
2533            ActivityStack stack = mStackSupervisor.getStack(stackId);
2534            if (stack != null) {
2535                ActivityRecord r = stack.topRunningActivityLocked(null);
2536                if (r != null) {
2537                    setFocusedActivityLocked(r);
2538                }
2539            }
2540        }
2541    }
2542
2543    @Override
2544    public void notifyActivityDrawn(IBinder token) {
2545        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2546        synchronized (this) {
2547            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2548            if (r != null) {
2549                r.task.stack.notifyActivityDrawnLocked(r);
2550            }
2551        }
2552    }
2553
2554    final void applyUpdateLockStateLocked(ActivityRecord r) {
2555        // Modifications to the UpdateLock state are done on our handler, outside
2556        // the activity manager's locks.  The new state is determined based on the
2557        // state *now* of the relevant activity record.  The object is passed to
2558        // the handler solely for logging detail, not to be consulted/modified.
2559        final boolean nextState = r != null && r.immersive;
2560        mHandler.sendMessage(
2561                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2562    }
2563
2564    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2565        Message msg = Message.obtain();
2566        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2567        msg.obj = r.task.askedCompatMode ? null : r;
2568        mHandler.sendMessage(msg);
2569    }
2570
2571    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2572            String what, Object obj, ProcessRecord srcApp) {
2573        app.lastActivityTime = now;
2574
2575        if (app.activities.size() > 0) {
2576            // Don't want to touch dependent processes that are hosting activities.
2577            return index;
2578        }
2579
2580        int lrui = mLruProcesses.lastIndexOf(app);
2581        if (lrui < 0) {
2582            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2583                    + what + " " + obj + " from " + srcApp);
2584            return index;
2585        }
2586
2587        if (lrui >= index) {
2588            // Don't want to cause this to move dependent processes *back* in the
2589            // list as if they were less frequently used.
2590            return index;
2591        }
2592
2593        if (lrui >= mLruProcessActivityStart) {
2594            // Don't want to touch dependent processes that are hosting activities.
2595            return index;
2596        }
2597
2598        mLruProcesses.remove(lrui);
2599        if (index > 0) {
2600            index--;
2601        }
2602        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2603                + " in LRU list: " + app);
2604        mLruProcesses.add(index, app);
2605        return index;
2606    }
2607
2608    final void removeLruProcessLocked(ProcessRecord app) {
2609        int lrui = mLruProcesses.lastIndexOf(app);
2610        if (lrui >= 0) {
2611            if (lrui <= mLruProcessActivityStart) {
2612                mLruProcessActivityStart--;
2613            }
2614            if (lrui <= mLruProcessServiceStart) {
2615                mLruProcessServiceStart--;
2616            }
2617            mLruProcesses.remove(lrui);
2618        }
2619    }
2620
2621    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2622            ProcessRecord client) {
2623        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2624                || app.treatLikeActivity;
2625        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2626        if (!activityChange && hasActivity) {
2627            // The process has activities, so we are only allowing activity-based adjustments
2628            // to move it.  It should be kept in the front of the list with other
2629            // processes that have activities, and we don't want those to change their
2630            // order except due to activity operations.
2631            return;
2632        }
2633
2634        mLruSeq++;
2635        final long now = SystemClock.uptimeMillis();
2636        app.lastActivityTime = now;
2637
2638        // First a quick reject: if the app is already at the position we will
2639        // put it, then there is nothing to do.
2640        if (hasActivity) {
2641            final int N = mLruProcesses.size();
2642            if (N > 0 && mLruProcesses.get(N-1) == app) {
2643                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2644                return;
2645            }
2646        } else {
2647            if (mLruProcessServiceStart > 0
2648                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2649                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2650                return;
2651            }
2652        }
2653
2654        int lrui = mLruProcesses.lastIndexOf(app);
2655
2656        if (app.persistent && lrui >= 0) {
2657            // We don't care about the position of persistent processes, as long as
2658            // they are in the list.
2659            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2660            return;
2661        }
2662
2663        /* In progress: compute new position first, so we can avoid doing work
2664           if the process is not actually going to move.  Not yet working.
2665        int addIndex;
2666        int nextIndex;
2667        boolean inActivity = false, inService = false;
2668        if (hasActivity) {
2669            // Process has activities, put it at the very tipsy-top.
2670            addIndex = mLruProcesses.size();
2671            nextIndex = mLruProcessServiceStart;
2672            inActivity = true;
2673        } else if (hasService) {
2674            // Process has services, put it at the top of the service list.
2675            addIndex = mLruProcessActivityStart;
2676            nextIndex = mLruProcessServiceStart;
2677            inActivity = true;
2678            inService = true;
2679        } else  {
2680            // Process not otherwise of interest, it goes to the top of the non-service area.
2681            addIndex = mLruProcessServiceStart;
2682            if (client != null) {
2683                int clientIndex = mLruProcesses.lastIndexOf(client);
2684                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2685                        + app);
2686                if (clientIndex >= 0 && addIndex > clientIndex) {
2687                    addIndex = clientIndex;
2688                }
2689            }
2690            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2691        }
2692
2693        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2694                + mLruProcessActivityStart + "): " + app);
2695        */
2696
2697        if (lrui >= 0) {
2698            if (lrui < mLruProcessActivityStart) {
2699                mLruProcessActivityStart--;
2700            }
2701            if (lrui < mLruProcessServiceStart) {
2702                mLruProcessServiceStart--;
2703            }
2704            /*
2705            if (addIndex > lrui) {
2706                addIndex--;
2707            }
2708            if (nextIndex > lrui) {
2709                nextIndex--;
2710            }
2711            */
2712            mLruProcesses.remove(lrui);
2713        }
2714
2715        /*
2716        mLruProcesses.add(addIndex, app);
2717        if (inActivity) {
2718            mLruProcessActivityStart++;
2719        }
2720        if (inService) {
2721            mLruProcessActivityStart++;
2722        }
2723        */
2724
2725        int nextIndex;
2726        if (hasActivity) {
2727            final int N = mLruProcesses.size();
2728            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2729                // Process doesn't have activities, but has clients with
2730                // activities...  move it up, but one below the top (the top
2731                // should always have a real activity).
2732                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2733                mLruProcesses.add(N-1, app);
2734                // To keep it from spamming the LRU list (by making a bunch of clients),
2735                // we will push down any other entries owned by the app.
2736                final int uid = app.info.uid;
2737                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2738                    ProcessRecord subProc = mLruProcesses.get(i);
2739                    if (subProc.info.uid == uid) {
2740                        // We want to push this one down the list.  If the process after
2741                        // it is for the same uid, however, don't do so, because we don't
2742                        // want them internally to be re-ordered.
2743                        if (mLruProcesses.get(i-1).info.uid != uid) {
2744                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2745                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2746                            ProcessRecord tmp = mLruProcesses.get(i);
2747                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2748                            mLruProcesses.set(i-1, tmp);
2749                            i--;
2750                        }
2751                    } else {
2752                        // A gap, we can stop here.
2753                        break;
2754                    }
2755                }
2756            } else {
2757                // Process has activities, put it at the very tipsy-top.
2758                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2759                mLruProcesses.add(app);
2760            }
2761            nextIndex = mLruProcessServiceStart;
2762        } else if (hasService) {
2763            // Process has services, put it at the top of the service list.
2764            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2765            mLruProcesses.add(mLruProcessActivityStart, app);
2766            nextIndex = mLruProcessServiceStart;
2767            mLruProcessActivityStart++;
2768        } else  {
2769            // Process not otherwise of interest, it goes to the top of the non-service area.
2770            int index = mLruProcessServiceStart;
2771            if (client != null) {
2772                // If there is a client, don't allow the process to be moved up higher
2773                // in the list than that client.
2774                int clientIndex = mLruProcesses.lastIndexOf(client);
2775                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2776                        + " when updating " + app);
2777                if (clientIndex <= lrui) {
2778                    // Don't allow the client index restriction to push it down farther in the
2779                    // list than it already is.
2780                    clientIndex = lrui;
2781                }
2782                if (clientIndex >= 0 && index > clientIndex) {
2783                    index = clientIndex;
2784                }
2785            }
2786            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2787            mLruProcesses.add(index, app);
2788            nextIndex = index-1;
2789            mLruProcessActivityStart++;
2790            mLruProcessServiceStart++;
2791        }
2792
2793        // If the app is currently using a content provider or service,
2794        // bump those processes as well.
2795        for (int j=app.connections.size()-1; j>=0; j--) {
2796            ConnectionRecord cr = app.connections.valueAt(j);
2797            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2798                    && cr.binding.service.app != null
2799                    && cr.binding.service.app.lruSeq != mLruSeq
2800                    && !cr.binding.service.app.persistent) {
2801                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2802                        "service connection", cr, app);
2803            }
2804        }
2805        for (int j=app.conProviders.size()-1; j>=0; j--) {
2806            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2807            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2808                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2809                        "provider reference", cpr, app);
2810            }
2811        }
2812    }
2813
2814    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2815        if (uid == Process.SYSTEM_UID) {
2816            // The system gets to run in any process.  If there are multiple
2817            // processes with the same uid, just pick the first (this
2818            // should never happen).
2819            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2820            if (procs == null) return null;
2821            final int N = procs.size();
2822            for (int i = 0; i < N; i++) {
2823                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2824            }
2825        }
2826        ProcessRecord proc = mProcessNames.get(processName, uid);
2827        if (false && proc != null && !keepIfLarge
2828                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2829                && proc.lastCachedPss >= 4000) {
2830            // Turn this condition on to cause killing to happen regularly, for testing.
2831            if (proc.baseProcessTracker != null) {
2832                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2833            }
2834            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2835        } else if (proc != null && !keepIfLarge
2836                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2837                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2838            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2839            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2840                if (proc.baseProcessTracker != null) {
2841                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2842                }
2843                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2844            }
2845        }
2846        return proc;
2847    }
2848
2849    void ensurePackageDexOpt(String packageName) {
2850        IPackageManager pm = AppGlobals.getPackageManager();
2851        try {
2852            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2853                mDidDexOpt = true;
2854            }
2855        } catch (RemoteException e) {
2856        }
2857    }
2858
2859    boolean isNextTransitionForward() {
2860        int transit = mWindowManager.getPendingAppTransition();
2861        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2862                || transit == AppTransition.TRANSIT_TASK_OPEN
2863                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2864    }
2865
2866    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2867            String processName, String abiOverride, int uid, Runnable crashHandler) {
2868        synchronized(this) {
2869            ApplicationInfo info = new ApplicationInfo();
2870            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2871            // For isolated processes, the former contains the parent's uid and the latter the
2872            // actual uid of the isolated process.
2873            // In the special case introduced by this method (which is, starting an isolated
2874            // process directly from the SystemServer without an actual parent app process) the
2875            // closest thing to a parent's uid is SYSTEM_UID.
2876            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2877            // the |isolated| logic in the ProcessRecord constructor.
2878            info.uid = Process.SYSTEM_UID;
2879            info.processName = processName;
2880            info.className = entryPoint;
2881            info.packageName = "android";
2882            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2883                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2884                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2885                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2886                    crashHandler);
2887            return proc != null ? proc.pid : 0;
2888        }
2889    }
2890
2891    final ProcessRecord startProcessLocked(String processName,
2892            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2893            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2894            boolean isolated, boolean keepIfLarge) {
2895        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2896                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2897                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2898                null /* crashHandler */);
2899    }
2900
2901    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2902            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2903            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2904            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2905        ProcessRecord app;
2906        if (!isolated) {
2907            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2908        } else {
2909            // If this is an isolated process, it can't re-use an existing process.
2910            app = null;
2911        }
2912        // We don't have to do anything more if:
2913        // (1) There is an existing application record; and
2914        // (2) The caller doesn't think it is dead, OR there is no thread
2915        //     object attached to it so we know it couldn't have crashed; and
2916        // (3) There is a pid assigned to it, so it is either starting or
2917        //     already running.
2918        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2919                + " app=" + app + " knownToBeDead=" + knownToBeDead
2920                + " thread=" + (app != null ? app.thread : null)
2921                + " pid=" + (app != null ? app.pid : -1));
2922        if (app != null && app.pid > 0) {
2923            if (!knownToBeDead || app.thread == null) {
2924                // We already have the app running, or are waiting for it to
2925                // come up (we have a pid but not yet its thread), so keep it.
2926                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2927                // If this is a new package in the process, add the package to the list
2928                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2929                return app;
2930            }
2931
2932            // An application record is attached to a previous process,
2933            // clean it up now.
2934            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2935            Process.killProcessGroup(app.info.uid, app.pid);
2936            handleAppDiedLocked(app, true, true);
2937        }
2938
2939        String hostingNameStr = hostingName != null
2940                ? hostingName.flattenToShortString() : null;
2941
2942        if (!isolated) {
2943            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2944                // If we are in the background, then check to see if this process
2945                // is bad.  If so, we will just silently fail.
2946                if (mBadProcesses.get(info.processName, info.uid) != null) {
2947                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2948                            + "/" + info.processName);
2949                    return null;
2950                }
2951            } else {
2952                // When the user is explicitly starting a process, then clear its
2953                // crash count so that we won't make it bad until they see at
2954                // least one crash dialog again, and make the process good again
2955                // if it had been bad.
2956                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2957                        + "/" + info.processName);
2958                mProcessCrashTimes.remove(info.processName, info.uid);
2959                if (mBadProcesses.get(info.processName, info.uid) != null) {
2960                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2961                            UserHandle.getUserId(info.uid), info.uid,
2962                            info.processName);
2963                    mBadProcesses.remove(info.processName, info.uid);
2964                    if (app != null) {
2965                        app.bad = false;
2966                    }
2967                }
2968            }
2969        }
2970
2971        if (app == null) {
2972            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2973            app.crashHandler = crashHandler;
2974            if (app == null) {
2975                Slog.w(TAG, "Failed making new process record for "
2976                        + processName + "/" + info.uid + " isolated=" + isolated);
2977                return null;
2978            }
2979            mProcessNames.put(processName, app.uid, app);
2980            if (isolated) {
2981                mIsolatedProcesses.put(app.uid, app);
2982            }
2983        } else {
2984            // If this is a new package in the process, add the package to the list
2985            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2986        }
2987
2988        // If the system is not ready yet, then hold off on starting this
2989        // process until it is.
2990        if (!mProcessesReady
2991                && !isAllowedWhileBooting(info)
2992                && !allowWhileBooting) {
2993            if (!mProcessesOnHold.contains(app)) {
2994                mProcessesOnHold.add(app);
2995            }
2996            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2997            return app;
2998        }
2999
3000        startProcessLocked(
3001                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3002        return (app.pid != 0) ? app : null;
3003    }
3004
3005    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3006        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3007    }
3008
3009    private final void startProcessLocked(ProcessRecord app,
3010            String hostingType, String hostingNameStr) {
3011        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3012                null /* entryPoint */, null /* entryPointArgs */);
3013    }
3014
3015    private final void startProcessLocked(ProcessRecord app, String hostingType,
3016            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3017        if (app.pid > 0 && app.pid != MY_PID) {
3018            synchronized (mPidsSelfLocked) {
3019                mPidsSelfLocked.remove(app.pid);
3020                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3021            }
3022            app.setPid(0);
3023        }
3024
3025        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3026                "startProcessLocked removing on hold: " + app);
3027        mProcessesOnHold.remove(app);
3028
3029        updateCpuStats();
3030
3031        try {
3032            int uid = app.uid;
3033
3034            int[] gids = null;
3035            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3036            if (!app.isolated) {
3037                int[] permGids = null;
3038                try {
3039                    final PackageManager pm = mContext.getPackageManager();
3040                    permGids = pm.getPackageGids(app.info.packageName);
3041
3042                    if (Environment.isExternalStorageEmulated()) {
3043                        if (pm.checkPermission(
3044                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3045                                app.info.packageName) == PERMISSION_GRANTED) {
3046                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3047                        } else {
3048                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3049                        }
3050                    }
3051                } catch (PackageManager.NameNotFoundException e) {
3052                    Slog.w(TAG, "Unable to retrieve gids", e);
3053                }
3054
3055                /*
3056                 * Add shared application and profile GIDs so applications can share some
3057                 * resources like shared libraries and access user-wide resources
3058                 */
3059                if (permGids == null) {
3060                    gids = new int[2];
3061                } else {
3062                    gids = new int[permGids.length + 2];
3063                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3064                }
3065                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3066                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3067            }
3068            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3069                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3070                        && mTopComponent != null
3071                        && app.processName.equals(mTopComponent.getPackageName())) {
3072                    uid = 0;
3073                }
3074                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3075                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3076                    uid = 0;
3077                }
3078            }
3079            int debugFlags = 0;
3080            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3081                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3082                // Also turn on CheckJNI for debuggable apps. It's quite
3083                // awkward to turn on otherwise.
3084                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3085            }
3086            // Run the app in safe mode if its manifest requests so or the
3087            // system is booted in safe mode.
3088            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3089                mSafeMode == true) {
3090                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3091            }
3092            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3093                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3094            }
3095            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3096                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3097            }
3098            if ("1".equals(SystemProperties.get("debug.assert"))) {
3099                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3100            }
3101
3102            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3103            if (requiredAbi == null) {
3104                requiredAbi = Build.SUPPORTED_ABIS[0];
3105            }
3106
3107            // Start the process.  It will either succeed and return a result containing
3108            // the PID of the new process, or else throw a RuntimeException.
3109            boolean isActivityProcess = (entryPoint == null);
3110            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3111            Process.ProcessStartResult startResult = Process.start(entryPoint,
3112                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3113                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3114
3115            if (app.isolated) {
3116                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3117            }
3118            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3119
3120            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3121                    UserHandle.getUserId(uid), startResult.pid, uid,
3122                    app.processName, hostingType,
3123                    hostingNameStr != null ? hostingNameStr : "");
3124
3125            if (app.persistent) {
3126                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3127            }
3128
3129            StringBuilder buf = mStringBuilder;
3130            buf.setLength(0);
3131            buf.append("Start proc ");
3132            buf.append(app.processName);
3133            if (!isActivityProcess) {
3134                buf.append(" [");
3135                buf.append(entryPoint);
3136                buf.append("]");
3137            }
3138            buf.append(" for ");
3139            buf.append(hostingType);
3140            if (hostingNameStr != null) {
3141                buf.append(" ");
3142                buf.append(hostingNameStr);
3143            }
3144            buf.append(": pid=");
3145            buf.append(startResult.pid);
3146            buf.append(" uid=");
3147            buf.append(uid);
3148            buf.append(" gids={");
3149            if (gids != null) {
3150                for (int gi=0; gi<gids.length; gi++) {
3151                    if (gi != 0) buf.append(", ");
3152                    buf.append(gids[gi]);
3153
3154                }
3155            }
3156            buf.append("}");
3157            if (requiredAbi != null) {
3158                buf.append(" abi=");
3159                buf.append(requiredAbi);
3160            }
3161            Slog.i(TAG, buf.toString());
3162            app.setPid(startResult.pid);
3163            app.usingWrapper = startResult.usingWrapper;
3164            app.removed = false;
3165            app.killedByAm = false;
3166            synchronized (mPidsSelfLocked) {
3167                this.mPidsSelfLocked.put(startResult.pid, app);
3168                if (isActivityProcess) {
3169                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3170                    msg.obj = app;
3171                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3172                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3173                }
3174            }
3175        } catch (RuntimeException e) {
3176            // XXX do better error recovery.
3177            app.setPid(0);
3178            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3179            if (app.isolated) {
3180                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3181            }
3182            Slog.e(TAG, "Failure starting process " + app.processName, e);
3183        }
3184    }
3185
3186    void updateUsageStats(ActivityRecord component, boolean resumed) {
3187        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3188        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3189        if (resumed) {
3190            if (mUsageStatsService != null) {
3191                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3192                        System.currentTimeMillis(),
3193                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3194            }
3195            synchronized (stats) {
3196                stats.noteActivityResumedLocked(component.app.uid);
3197            }
3198        } else {
3199            if (mUsageStatsService != null) {
3200                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3201                        System.currentTimeMillis(),
3202                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3203            }
3204            synchronized (stats) {
3205                stats.noteActivityPausedLocked(component.app.uid);
3206            }
3207        }
3208    }
3209
3210    Intent getHomeIntent() {
3211        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3212        intent.setComponent(mTopComponent);
3213        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3214            intent.addCategory(Intent.CATEGORY_HOME);
3215        }
3216        return intent;
3217    }
3218
3219    boolean startHomeActivityLocked(int userId) {
3220        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3221                && mTopAction == null) {
3222            // We are running in factory test mode, but unable to find
3223            // the factory test app, so just sit around displaying the
3224            // error message and don't try to start anything.
3225            return false;
3226        }
3227        Intent intent = getHomeIntent();
3228        ActivityInfo aInfo =
3229            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3230        if (aInfo != null) {
3231            intent.setComponent(new ComponentName(
3232                    aInfo.applicationInfo.packageName, aInfo.name));
3233            // Don't do this if the home app is currently being
3234            // instrumented.
3235            aInfo = new ActivityInfo(aInfo);
3236            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3237            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3238                    aInfo.applicationInfo.uid, true);
3239            if (app == null || app.instrumentationClass == null) {
3240                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3241                mStackSupervisor.startHomeActivity(intent, aInfo);
3242            }
3243        }
3244
3245        return true;
3246    }
3247
3248    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3249        ActivityInfo ai = null;
3250        ComponentName comp = intent.getComponent();
3251        try {
3252            if (comp != null) {
3253                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3254            } else {
3255                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3256                        intent,
3257                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3258                            flags, userId);
3259
3260                if (info != null) {
3261                    ai = info.activityInfo;
3262                }
3263            }
3264        } catch (RemoteException e) {
3265            // ignore
3266        }
3267
3268        return ai;
3269    }
3270
3271    /**
3272     * Starts the "new version setup screen" if appropriate.
3273     */
3274    void startSetupActivityLocked() {
3275        // Only do this once per boot.
3276        if (mCheckedForSetup) {
3277            return;
3278        }
3279
3280        // We will show this screen if the current one is a different
3281        // version than the last one shown, and we are not running in
3282        // low-level factory test mode.
3283        final ContentResolver resolver = mContext.getContentResolver();
3284        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3285                Settings.Global.getInt(resolver,
3286                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3287            mCheckedForSetup = true;
3288
3289            // See if we should be showing the platform update setup UI.
3290            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3291            List<ResolveInfo> ris = mContext.getPackageManager()
3292                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3293
3294            // We don't allow third party apps to replace this.
3295            ResolveInfo ri = null;
3296            for (int i=0; ris != null && i<ris.size(); i++) {
3297                if ((ris.get(i).activityInfo.applicationInfo.flags
3298                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3299                    ri = ris.get(i);
3300                    break;
3301                }
3302            }
3303
3304            if (ri != null) {
3305                String vers = ri.activityInfo.metaData != null
3306                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3307                        : null;
3308                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3309                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3310                            Intent.METADATA_SETUP_VERSION);
3311                }
3312                String lastVers = Settings.Secure.getString(
3313                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3314                if (vers != null && !vers.equals(lastVers)) {
3315                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3316                    intent.setComponent(new ComponentName(
3317                            ri.activityInfo.packageName, ri.activityInfo.name));
3318                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3319                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3320                            null);
3321                }
3322            }
3323        }
3324    }
3325
3326    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3327        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3328    }
3329
3330    void enforceNotIsolatedCaller(String caller) {
3331        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3332            throw new SecurityException("Isolated process not allowed to call " + caller);
3333        }
3334    }
3335
3336    @Override
3337    public int getFrontActivityScreenCompatMode() {
3338        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3339        synchronized (this) {
3340            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3341        }
3342    }
3343
3344    @Override
3345    public void setFrontActivityScreenCompatMode(int mode) {
3346        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3347                "setFrontActivityScreenCompatMode");
3348        synchronized (this) {
3349            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3350        }
3351    }
3352
3353    @Override
3354    public int getPackageScreenCompatMode(String packageName) {
3355        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3356        synchronized (this) {
3357            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3358        }
3359    }
3360
3361    @Override
3362    public void setPackageScreenCompatMode(String packageName, int mode) {
3363        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3364                "setPackageScreenCompatMode");
3365        synchronized (this) {
3366            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3367        }
3368    }
3369
3370    @Override
3371    public boolean getPackageAskScreenCompat(String packageName) {
3372        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3373        synchronized (this) {
3374            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3375        }
3376    }
3377
3378    @Override
3379    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3380        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3381                "setPackageAskScreenCompat");
3382        synchronized (this) {
3383            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3384        }
3385    }
3386
3387    private void dispatchProcessesChanged() {
3388        int N;
3389        synchronized (this) {
3390            N = mPendingProcessChanges.size();
3391            if (mActiveProcessChanges.length < N) {
3392                mActiveProcessChanges = new ProcessChangeItem[N];
3393            }
3394            mPendingProcessChanges.toArray(mActiveProcessChanges);
3395            mAvailProcessChanges.addAll(mPendingProcessChanges);
3396            mPendingProcessChanges.clear();
3397            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3398        }
3399
3400        int i = mProcessObservers.beginBroadcast();
3401        while (i > 0) {
3402            i--;
3403            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3404            if (observer != null) {
3405                try {
3406                    for (int j=0; j<N; j++) {
3407                        ProcessChangeItem item = mActiveProcessChanges[j];
3408                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3409                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3410                                    + item.pid + " uid=" + item.uid + ": "
3411                                    + item.foregroundActivities);
3412                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3413                                    item.foregroundActivities);
3414                        }
3415                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3416                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3417                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3418                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3419                        }
3420                    }
3421                } catch (RemoteException e) {
3422                }
3423            }
3424        }
3425        mProcessObservers.finishBroadcast();
3426    }
3427
3428    private void dispatchProcessDied(int pid, int uid) {
3429        int i = mProcessObservers.beginBroadcast();
3430        while (i > 0) {
3431            i--;
3432            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3433            if (observer != null) {
3434                try {
3435                    observer.onProcessDied(pid, uid);
3436                } catch (RemoteException e) {
3437                }
3438            }
3439        }
3440        mProcessObservers.finishBroadcast();
3441    }
3442
3443    @Override
3444    public final int startActivity(IApplicationThread caller, String callingPackage,
3445            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3446            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3447        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3448            resultWho, requestCode, startFlags, profilerInfo, options,
3449            UserHandle.getCallingUserId());
3450    }
3451
3452    @Override
3453    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3454            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3455            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3456        enforceNotIsolatedCaller("startActivity");
3457        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3458                false, ALLOW_FULL_ONLY, "startActivity", null);
3459        // TODO: Switch to user app stacks here.
3460        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3461                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3462                profilerInfo, null, null, options, userId, null, null);
3463    }
3464
3465    @Override
3466    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3467            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3468            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3469
3470        // This is very dangerous -- it allows you to perform a start activity (including
3471        // permission grants) as any app that may launch one of your own activities.  So
3472        // we will only allow this to be done from activities that are part of the core framework,
3473        // and then only when they are running as the system.
3474        final ActivityRecord sourceRecord;
3475        final int targetUid;
3476        final String targetPackage;
3477        synchronized (this) {
3478            if (resultTo == null) {
3479                throw new SecurityException("Must be called from an activity");
3480            }
3481            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3482            if (sourceRecord == null) {
3483                throw new SecurityException("Called with bad activity token: " + resultTo);
3484            }
3485            if (!sourceRecord.info.packageName.equals("android")) {
3486                throw new SecurityException(
3487                        "Must be called from an activity that is declared in the android package");
3488            }
3489            if (sourceRecord.app == null) {
3490                throw new SecurityException("Called without a process attached to activity");
3491            }
3492            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3493                // This is still okay, as long as this activity is running under the
3494                // uid of the original calling activity.
3495                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3496                    throw new SecurityException(
3497                            "Calling activity in uid " + sourceRecord.app.uid
3498                                    + " must be system uid or original calling uid "
3499                                    + sourceRecord.launchedFromUid);
3500                }
3501            }
3502            targetUid = sourceRecord.launchedFromUid;
3503            targetPackage = sourceRecord.launchedFromPackage;
3504        }
3505
3506        // TODO: Switch to user app stacks here.
3507        try {
3508            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3509                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3510                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3511            return ret;
3512        } catch (SecurityException e) {
3513            // XXX need to figure out how to propagate to original app.
3514            // A SecurityException here is generally actually a fault of the original
3515            // calling activity (such as a fairly granting permissions), so propagate it
3516            // back to them.
3517            /*
3518            StringBuilder msg = new StringBuilder();
3519            msg.append("While launching");
3520            msg.append(intent.toString());
3521            msg.append(": ");
3522            msg.append(e.getMessage());
3523            */
3524            throw e;
3525        }
3526    }
3527
3528    @Override
3529    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3530            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3531            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3532        enforceNotIsolatedCaller("startActivityAndWait");
3533        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3534                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3535        WaitResult res = new WaitResult();
3536        // TODO: Switch to user app stacks here.
3537        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3538                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3539                options, userId, null, null);
3540        return res;
3541    }
3542
3543    @Override
3544    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3545            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3546            int startFlags, Configuration config, Bundle options, int userId) {
3547        enforceNotIsolatedCaller("startActivityWithConfig");
3548        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3549                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3550        // TODO: Switch to user app stacks here.
3551        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3552                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3553                null, null, config, options, userId, null, null);
3554        return ret;
3555    }
3556
3557    @Override
3558    public int startActivityIntentSender(IApplicationThread caller,
3559            IntentSender intent, Intent fillInIntent, String resolvedType,
3560            IBinder resultTo, String resultWho, int requestCode,
3561            int flagsMask, int flagsValues, Bundle options) {
3562        enforceNotIsolatedCaller("startActivityIntentSender");
3563        // Refuse possible leaked file descriptors
3564        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3565            throw new IllegalArgumentException("File descriptors passed in Intent");
3566        }
3567
3568        IIntentSender sender = intent.getTarget();
3569        if (!(sender instanceof PendingIntentRecord)) {
3570            throw new IllegalArgumentException("Bad PendingIntent object");
3571        }
3572
3573        PendingIntentRecord pir = (PendingIntentRecord)sender;
3574
3575        synchronized (this) {
3576            // If this is coming from the currently resumed activity, it is
3577            // effectively saying that app switches are allowed at this point.
3578            final ActivityStack stack = getFocusedStack();
3579            if (stack.mResumedActivity != null &&
3580                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3581                mAppSwitchesAllowedTime = 0;
3582            }
3583        }
3584        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3585                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3586        return ret;
3587    }
3588
3589    @Override
3590    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3591            Intent intent, String resolvedType, IVoiceInteractionSession session,
3592            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3593            Bundle options, int userId) {
3594        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3595                != PackageManager.PERMISSION_GRANTED) {
3596            String msg = "Permission Denial: startVoiceActivity() from pid="
3597                    + Binder.getCallingPid()
3598                    + ", uid=" + Binder.getCallingUid()
3599                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3600            Slog.w(TAG, msg);
3601            throw new SecurityException(msg);
3602        }
3603        if (session == null || interactor == null) {
3604            throw new NullPointerException("null session or interactor");
3605        }
3606        userId = handleIncomingUser(callingPid, callingUid, userId,
3607                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3608        // TODO: Switch to user app stacks here.
3609        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3610                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3611                null, options, userId, null, null);
3612    }
3613
3614    @Override
3615    public boolean startNextMatchingActivity(IBinder callingActivity,
3616            Intent intent, Bundle options) {
3617        // Refuse possible leaked file descriptors
3618        if (intent != null && intent.hasFileDescriptors() == true) {
3619            throw new IllegalArgumentException("File descriptors passed in Intent");
3620        }
3621
3622        synchronized (this) {
3623            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3624            if (r == null) {
3625                ActivityOptions.abort(options);
3626                return false;
3627            }
3628            if (r.app == null || r.app.thread == null) {
3629                // The caller is not running...  d'oh!
3630                ActivityOptions.abort(options);
3631                return false;
3632            }
3633            intent = new Intent(intent);
3634            // The caller is not allowed to change the data.
3635            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3636            // And we are resetting to find the next component...
3637            intent.setComponent(null);
3638
3639            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3640
3641            ActivityInfo aInfo = null;
3642            try {
3643                List<ResolveInfo> resolves =
3644                    AppGlobals.getPackageManager().queryIntentActivities(
3645                            intent, r.resolvedType,
3646                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3647                            UserHandle.getCallingUserId());
3648
3649                // Look for the original activity in the list...
3650                final int N = resolves != null ? resolves.size() : 0;
3651                for (int i=0; i<N; i++) {
3652                    ResolveInfo rInfo = resolves.get(i);
3653                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3654                            && rInfo.activityInfo.name.equals(r.info.name)) {
3655                        // We found the current one...  the next matching is
3656                        // after it.
3657                        i++;
3658                        if (i<N) {
3659                            aInfo = resolves.get(i).activityInfo;
3660                        }
3661                        if (debug) {
3662                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3663                                    + "/" + r.info.name);
3664                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3665                                    + "/" + aInfo.name);
3666                        }
3667                        break;
3668                    }
3669                }
3670            } catch (RemoteException e) {
3671            }
3672
3673            if (aInfo == null) {
3674                // Nobody who is next!
3675                ActivityOptions.abort(options);
3676                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3677                return false;
3678            }
3679
3680            intent.setComponent(new ComponentName(
3681                    aInfo.applicationInfo.packageName, aInfo.name));
3682            intent.setFlags(intent.getFlags()&~(
3683                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3684                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3685                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3686                    Intent.FLAG_ACTIVITY_NEW_TASK));
3687
3688            // Okay now we need to start the new activity, replacing the
3689            // currently running activity.  This is a little tricky because
3690            // we want to start the new one as if the current one is finished,
3691            // but not finish the current one first so that there is no flicker.
3692            // And thus...
3693            final boolean wasFinishing = r.finishing;
3694            r.finishing = true;
3695
3696            // Propagate reply information over to the new activity.
3697            final ActivityRecord resultTo = r.resultTo;
3698            final String resultWho = r.resultWho;
3699            final int requestCode = r.requestCode;
3700            r.resultTo = null;
3701            if (resultTo != null) {
3702                resultTo.removeResultsLocked(r, resultWho, requestCode);
3703            }
3704
3705            final long origId = Binder.clearCallingIdentity();
3706            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3707                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3708                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3709                    options, false, null, null, null);
3710            Binder.restoreCallingIdentity(origId);
3711
3712            r.finishing = wasFinishing;
3713            if (res != ActivityManager.START_SUCCESS) {
3714                return false;
3715            }
3716            return true;
3717        }
3718    }
3719
3720    @Override
3721    public final int startActivityFromRecents(int taskId, Bundle options) {
3722        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3723            String msg = "Permission Denial: startActivityFromRecents called without " +
3724                    START_TASKS_FROM_RECENTS;
3725            Slog.w(TAG, msg);
3726            throw new SecurityException(msg);
3727        }
3728        return startActivityFromRecentsInner(taskId, options);
3729    }
3730
3731    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3732        final TaskRecord task;
3733        final int callingUid;
3734        final String callingPackage;
3735        final Intent intent;
3736        final int userId;
3737        synchronized (this) {
3738            task = recentTaskForIdLocked(taskId);
3739            if (task == null) {
3740                throw new IllegalArgumentException("Task " + taskId + " not found.");
3741            }
3742            callingUid = task.mCallingUid;
3743            callingPackage = task.mCallingPackage;
3744            intent = task.intent;
3745            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3746            userId = task.userId;
3747        }
3748        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3749                options, userId, null, task);
3750    }
3751
3752    final int startActivityInPackage(int uid, String callingPackage,
3753            Intent intent, String resolvedType, IBinder resultTo,
3754            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3755            IActivityContainer container, TaskRecord inTask) {
3756
3757        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3758                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3759
3760        // TODO: Switch to user app stacks here.
3761        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3762                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3763                null, null, null, options, userId, container, inTask);
3764        return ret;
3765    }
3766
3767    @Override
3768    public final int startActivities(IApplicationThread caller, String callingPackage,
3769            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3770            int userId) {
3771        enforceNotIsolatedCaller("startActivities");
3772        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3773                false, ALLOW_FULL_ONLY, "startActivity", null);
3774        // TODO: Switch to user app stacks here.
3775        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3776                resolvedTypes, resultTo, options, userId);
3777        return ret;
3778    }
3779
3780    final int startActivitiesInPackage(int uid, String callingPackage,
3781            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3782            Bundle options, int userId) {
3783
3784        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3785                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3786        // TODO: Switch to user app stacks here.
3787        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3788                resultTo, options, userId);
3789        return ret;
3790    }
3791
3792    //explicitly remove thd old information in mRecentTasks when removing existing user.
3793    private void removeRecentTasksForUserLocked(int userId) {
3794        if(userId <= 0) {
3795            Slog.i(TAG, "Can't remove recent task on user " + userId);
3796            return;
3797        }
3798
3799        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3800            TaskRecord tr = mRecentTasks.get(i);
3801            if (tr.userId == userId) {
3802                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3803                        + " when finishing user" + userId);
3804                mRecentTasks.remove(i);
3805                tr.removedFromRecents(mTaskPersister);
3806            }
3807        }
3808
3809        // Remove tasks from persistent storage.
3810        mTaskPersister.wakeup(null, true);
3811    }
3812
3813    /**
3814     * Update the recent tasks lists: make sure tasks should still be here (their
3815     * applications / activities still exist), update their availability, fixup ordering
3816     * of affiliations.
3817     */
3818    void cleanupRecentTasksLocked(int userId) {
3819        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3820        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3821        final IPackageManager pm = AppGlobals.getPackageManager();
3822        final ActivityInfo dummyAct = new ActivityInfo();
3823        final ApplicationInfo dummyApp = new ApplicationInfo();
3824
3825        int N = mRecentTasks.size();
3826
3827        int[] users = userId == UserHandle.USER_ALL
3828                ? getUsersLocked() : new int[] { userId };
3829        for (int user : users) {
3830            for (int i = 0; i < N; i++) {
3831                TaskRecord task = mRecentTasks.get(i);
3832                if (task.userId != user) {
3833                    // Only look at tasks for the user ID of interest.
3834                    continue;
3835                }
3836                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3837                    // This situation is broken, and we should just get rid of it now.
3838                    mRecentTasks.remove(i);
3839                    task.removedFromRecents(mTaskPersister);
3840                    i--;
3841                    N--;
3842                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3843                    continue;
3844                }
3845                // Check whether this activity is currently available.
3846                if (task.realActivity != null) {
3847                    ActivityInfo ai = availActCache.get(task.realActivity);
3848                    if (ai == null) {
3849                        try {
3850                            ai = pm.getActivityInfo(task.realActivity,
3851                                    PackageManager.GET_UNINSTALLED_PACKAGES
3852                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3853                        } catch (RemoteException e) {
3854                            // Will never happen.
3855                            continue;
3856                        }
3857                        if (ai == null) {
3858                            ai = dummyAct;
3859                        }
3860                        availActCache.put(task.realActivity, ai);
3861                    }
3862                    if (ai == dummyAct) {
3863                        // This could be either because the activity no longer exists, or the
3864                        // app is temporarily gone.  For the former we want to remove the recents
3865                        // entry; for the latter we want to mark it as unavailable.
3866                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3867                        if (app == null) {
3868                            try {
3869                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3870                                        PackageManager.GET_UNINSTALLED_PACKAGES
3871                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3872                            } catch (RemoteException e) {
3873                                // Will never happen.
3874                                continue;
3875                            }
3876                            if (app == null) {
3877                                app = dummyApp;
3878                            }
3879                            availAppCache.put(task.realActivity.getPackageName(), app);
3880                        }
3881                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3882                            // Doesn't exist any more!  Good-bye.
3883                            mRecentTasks.remove(i);
3884                            task.removedFromRecents(mTaskPersister);
3885                            i--;
3886                            N--;
3887                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3888                            continue;
3889                        } else {
3890                            // Otherwise just not available for now.
3891                            if (task.isAvailable) {
3892                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3893                                        + task);
3894                            }
3895                            task.isAvailable = false;
3896                        }
3897                    } else {
3898                        if (!ai.enabled || !ai.applicationInfo.enabled
3899                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3900                            if (task.isAvailable) {
3901                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3902                                        + task + " (enabled=" + ai.enabled + "/"
3903                                        + ai.applicationInfo.enabled +  " flags="
3904                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3905                            }
3906                            task.isAvailable = false;
3907                        } else {
3908                            if (!task.isAvailable) {
3909                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3910                                        + task);
3911                            }
3912                            task.isAvailable = true;
3913                        }
3914                    }
3915                }
3916            }
3917        }
3918
3919        // Verify the affiliate chain for each task.
3920        for (int i = 0; i < N; ) {
3921            TaskRecord task = mRecentTasks.remove(i);
3922            if (mTmpRecents.contains(task)) {
3923                continue;
3924            }
3925            int affiliatedTaskId = task.mAffiliatedTaskId;
3926            while (true) {
3927                TaskRecord next = task.mNextAffiliate;
3928                if (next == null) {
3929                    break;
3930                }
3931                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3932                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3933                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3934                    task.setNextAffiliate(null);
3935                    if (next.mPrevAffiliate == task) {
3936                        next.setPrevAffiliate(null);
3937                    }
3938                    break;
3939                }
3940                if (next.mPrevAffiliate != task) {
3941                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3942                            next.mPrevAffiliate + " task=" + task);
3943                    next.setPrevAffiliate(null);
3944                    task.setNextAffiliate(null);
3945                    break;
3946                }
3947                if (!mRecentTasks.contains(next)) {
3948                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3949                    task.setNextAffiliate(null);
3950                    // We know that next.mPrevAffiliate is always task, from above, so clear
3951                    // its previous affiliate.
3952                    next.setPrevAffiliate(null);
3953                    break;
3954                }
3955                task = next;
3956            }
3957            // task is now the end of the list
3958            do {
3959                mRecentTasks.remove(task);
3960                mRecentTasks.add(i++, task);
3961                mTmpRecents.add(task);
3962                task.inRecents = true;
3963            } while ((task = task.mPrevAffiliate) != null);
3964        }
3965        mTmpRecents.clear();
3966        // mRecentTasks is now in sorted, affiliated order.
3967    }
3968
3969    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3970        int N = mRecentTasks.size();
3971        TaskRecord top = task;
3972        int topIndex = taskIndex;
3973        while (top.mNextAffiliate != null && topIndex > 0) {
3974            top = top.mNextAffiliate;
3975            topIndex--;
3976        }
3977        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3978                + topIndex + " from intial " + taskIndex);
3979        // Find the end of the chain, doing a sanity check along the way.
3980        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3981        int endIndex = topIndex;
3982        TaskRecord prev = top;
3983        while (endIndex < N) {
3984            TaskRecord cur = mRecentTasks.get(endIndex);
3985            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3986                    + endIndex + " " + cur);
3987            if (cur == top) {
3988                // Verify start of the chain.
3989                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3990                    Slog.wtf(TAG, "Bad chain @" + endIndex
3991                            + ": first task has next affiliate: " + prev);
3992                    sane = false;
3993                    break;
3994                }
3995            } else {
3996                // Verify middle of the chain's next points back to the one before.
3997                if (cur.mNextAffiliate != prev
3998                        || cur.mNextAffiliateTaskId != prev.taskId) {
3999                    Slog.wtf(TAG, "Bad chain @" + endIndex
4000                            + ": middle task " + cur + " @" + endIndex
4001                            + " has bad next affiliate "
4002                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4003                            + ", expected " + prev);
4004                    sane = false;
4005                    break;
4006                }
4007            }
4008            if (cur.mPrevAffiliateTaskId == -1) {
4009                // Chain ends here.
4010                if (cur.mPrevAffiliate != null) {
4011                    Slog.wtf(TAG, "Bad chain @" + endIndex
4012                            + ": last task " + cur + " has previous affiliate "
4013                            + cur.mPrevAffiliate);
4014                    sane = false;
4015                }
4016                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4017                break;
4018            } else {
4019                // Verify middle of the chain's prev points to a valid item.
4020                if (cur.mPrevAffiliate == null) {
4021                    Slog.wtf(TAG, "Bad chain @" + endIndex
4022                            + ": task " + cur + " has previous affiliate "
4023                            + cur.mPrevAffiliate + " but should be id "
4024                            + cur.mPrevAffiliate);
4025                    sane = false;
4026                    break;
4027                }
4028            }
4029            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4030                Slog.wtf(TAG, "Bad chain @" + endIndex
4031                        + ": task " + cur + " has affiliated id "
4032                        + cur.mAffiliatedTaskId + " but should be "
4033                        + task.mAffiliatedTaskId);
4034                sane = false;
4035                break;
4036            }
4037            prev = cur;
4038            endIndex++;
4039            if (endIndex >= N) {
4040                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4041                        + ": last task " + prev);
4042                sane = false;
4043                break;
4044            }
4045        }
4046        if (sane) {
4047            if (endIndex < taskIndex) {
4048                Slog.wtf(TAG, "Bad chain @" + endIndex
4049                        + ": did not extend to task " + task + " @" + taskIndex);
4050                sane = false;
4051            }
4052        }
4053        if (sane) {
4054            // All looks good, we can just move all of the affiliated tasks
4055            // to the top.
4056            for (int i=topIndex; i<=endIndex; i++) {
4057                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4058                        + " from " + i + " to " + (i-topIndex));
4059                TaskRecord cur = mRecentTasks.remove(i);
4060                mRecentTasks.add(i-topIndex, cur);
4061            }
4062            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4063                    + " to " + endIndex);
4064            return true;
4065        }
4066
4067        // Whoops, couldn't do it.
4068        return false;
4069    }
4070
4071    final void addRecentTaskLocked(TaskRecord task) {
4072        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4073                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4074
4075        int N = mRecentTasks.size();
4076        // Quick case: check if the top-most recent task is the same.
4077        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4078            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4079            return;
4080        }
4081        // Another quick case: check if this is part of a set of affiliated
4082        // tasks that are at the top.
4083        if (isAffiliated && N > 0 && task.inRecents
4084                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4085            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4086                    + " at top when adding " + task);
4087            return;
4088        }
4089        // Another quick case: never add voice sessions.
4090        if (task.voiceSession != null) {
4091            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4092            return;
4093        }
4094
4095        boolean needAffiliationFix = false;
4096
4097        // Slightly less quick case: the task is already in recents, so all we need
4098        // to do is move it.
4099        if (task.inRecents) {
4100            int taskIndex = mRecentTasks.indexOf(task);
4101            if (taskIndex >= 0) {
4102                if (!isAffiliated) {
4103                    // Simple case: this is not an affiliated task, so we just move it to the front.
4104                    mRecentTasks.remove(taskIndex);
4105                    mRecentTasks.add(0, task);
4106                    notifyTaskPersisterLocked(task, false);
4107                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4108                            + " from " + taskIndex);
4109                    return;
4110                } else {
4111                    // More complicated: need to keep all affiliated tasks together.
4112                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4113                        // All went well.
4114                        return;
4115                    }
4116
4117                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4118                    // everything and then go through our general path of adding a new task.
4119                    needAffiliationFix = true;
4120                }
4121            } else {
4122                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4123                needAffiliationFix = true;
4124            }
4125        }
4126
4127        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4128        trimRecentsForTask(task, true);
4129
4130        N = mRecentTasks.size();
4131        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4132            final TaskRecord tr = mRecentTasks.remove(N - 1);
4133            tr.removedFromRecents(mTaskPersister);
4134            N--;
4135        }
4136        task.inRecents = true;
4137        if (!isAffiliated || needAffiliationFix) {
4138            // If this is a simple non-affiliated task, or we had some failure trying to
4139            // handle it as part of an affilated task, then just place it at the top.
4140            mRecentTasks.add(0, task);
4141        } else if (isAffiliated) {
4142            // If this is a new affiliated task, then move all of the affiliated tasks
4143            // to the front and insert this new one.
4144            TaskRecord other = task.mNextAffiliate;
4145            if (other == null) {
4146                other = task.mPrevAffiliate;
4147            }
4148            if (other != null) {
4149                int otherIndex = mRecentTasks.indexOf(other);
4150                if (otherIndex >= 0) {
4151                    // Insert new task at appropriate location.
4152                    int taskIndex;
4153                    if (other == task.mNextAffiliate) {
4154                        // We found the index of our next affiliation, which is who is
4155                        // before us in the list, so add after that point.
4156                        taskIndex = otherIndex+1;
4157                    } else {
4158                        // We found the index of our previous affiliation, which is who is
4159                        // after us in the list, so add at their position.
4160                        taskIndex = otherIndex;
4161                    }
4162                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4163                            + taskIndex + ": " + task);
4164                    mRecentTasks.add(taskIndex, task);
4165
4166                    // Now move everything to the front.
4167                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4168                        // All went well.
4169                        return;
4170                    }
4171
4172                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4173                    // everything and then go through our general path of adding a new task.
4174                    needAffiliationFix = true;
4175                } else {
4176                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4177                            + other);
4178                    needAffiliationFix = true;
4179                }
4180            } else {
4181                if (DEBUG_RECENTS) Slog.d(TAG,
4182                        "addRecent: adding affiliated task without next/prev:" + task);
4183                needAffiliationFix = true;
4184            }
4185        }
4186        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4187
4188        if (needAffiliationFix) {
4189            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4190            cleanupRecentTasksLocked(task.userId);
4191        }
4192    }
4193
4194    /**
4195     * If needed, remove oldest existing entries in recents that are for the same kind
4196     * of task as the given one.
4197     */
4198    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4199        int N = mRecentTasks.size();
4200        final Intent intent = task.intent;
4201        final boolean document = intent != null && intent.isDocument();
4202
4203        int maxRecents = task.maxRecents - 1;
4204        for (int i=0; i<N; i++) {
4205            final TaskRecord tr = mRecentTasks.get(i);
4206            if (task != tr) {
4207                if (task.userId != tr.userId) {
4208                    continue;
4209                }
4210                if (i > MAX_RECENT_BITMAPS) {
4211                    tr.freeLastThumbnail();
4212                }
4213                final Intent trIntent = tr.intent;
4214                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4215                    (intent == null || !intent.filterEquals(trIntent))) {
4216                    continue;
4217                }
4218                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4219                if (document && trIsDocument) {
4220                    // These are the same document activity (not necessarily the same doc).
4221                    if (maxRecents > 0) {
4222                        --maxRecents;
4223                        continue;
4224                    }
4225                    // Hit the maximum number of documents for this task. Fall through
4226                    // and remove this document from recents.
4227                } else if (document || trIsDocument) {
4228                    // Only one of these is a document. Not the droid we're looking for.
4229                    continue;
4230                }
4231            }
4232
4233            if (!doTrim) {
4234                // If the caller is not actually asking for a trim, just tell them we reached
4235                // a point where the trim would happen.
4236                return i;
4237            }
4238
4239            // Either task and tr are the same or, their affinities match or their intents match
4240            // and neither of them is a document, or they are documents using the same activity
4241            // and their maxRecents has been reached.
4242            tr.disposeThumbnail();
4243            mRecentTasks.remove(i);
4244            if (task != tr) {
4245                tr.removedFromRecents(mTaskPersister);
4246            }
4247            i--;
4248            N--;
4249            if (task.intent == null) {
4250                // If the new recent task we are adding is not fully
4251                // specified, then replace it with the existing recent task.
4252                task = tr;
4253            }
4254            notifyTaskPersisterLocked(tr, false);
4255        }
4256
4257        return -1;
4258    }
4259
4260    @Override
4261    public void reportActivityFullyDrawn(IBinder token) {
4262        synchronized (this) {
4263            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4264            if (r == null) {
4265                return;
4266            }
4267            r.reportFullyDrawnLocked();
4268        }
4269    }
4270
4271    @Override
4272    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4273        synchronized (this) {
4274            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4275            if (r == null) {
4276                return;
4277            }
4278            final long origId = Binder.clearCallingIdentity();
4279            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4280            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4281                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4282            if (config != null) {
4283                r.frozenBeforeDestroy = true;
4284                if (!updateConfigurationLocked(config, r, false, false)) {
4285                    mStackSupervisor.resumeTopActivitiesLocked();
4286                }
4287            }
4288            Binder.restoreCallingIdentity(origId);
4289        }
4290    }
4291
4292    @Override
4293    public int getRequestedOrientation(IBinder token) {
4294        synchronized (this) {
4295            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4296            if (r == null) {
4297                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4298            }
4299            return mWindowManager.getAppOrientation(r.appToken);
4300        }
4301    }
4302
4303    /**
4304     * This is the internal entry point for handling Activity.finish().
4305     *
4306     * @param token The Binder token referencing the Activity we want to finish.
4307     * @param resultCode Result code, if any, from this Activity.
4308     * @param resultData Result data (Intent), if any, from this Activity.
4309     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4310     *            the root Activity in the task.
4311     *
4312     * @return Returns true if the activity successfully finished, or false if it is still running.
4313     */
4314    @Override
4315    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4316            boolean finishTask) {
4317        // Refuse possible leaked file descriptors
4318        if (resultData != null && resultData.hasFileDescriptors() == true) {
4319            throw new IllegalArgumentException("File descriptors passed in Intent");
4320        }
4321
4322        synchronized(this) {
4323            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4324            if (r == null) {
4325                return true;
4326            }
4327            // Keep track of the root activity of the task before we finish it
4328            TaskRecord tr = r.task;
4329            ActivityRecord rootR = tr.getRootActivity();
4330            // Do not allow task to finish in Lock Task mode.
4331            if (tr == mStackSupervisor.mLockTaskModeTask) {
4332                if (rootR == r) {
4333                    mStackSupervisor.showLockTaskToast();
4334                    return false;
4335                }
4336            }
4337            if (mController != null) {
4338                // Find the first activity that is not finishing.
4339                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4340                if (next != null) {
4341                    // ask watcher if this is allowed
4342                    boolean resumeOK = true;
4343                    try {
4344                        resumeOK = mController.activityResuming(next.packageName);
4345                    } catch (RemoteException e) {
4346                        mController = null;
4347                        Watchdog.getInstance().setActivityController(null);
4348                    }
4349
4350                    if (!resumeOK) {
4351                        return false;
4352                    }
4353                }
4354            }
4355            final long origId = Binder.clearCallingIdentity();
4356            try {
4357                boolean res;
4358                if (finishTask && r == rootR) {
4359                    // If requested, remove the task that is associated to this activity only if it
4360                    // was the root activity in the task.  The result code and data is ignored because
4361                    // we don't support returning them across task boundaries.
4362                    res = removeTaskByIdLocked(tr.taskId, 0);
4363                } else {
4364                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4365                            resultData, "app-request", true);
4366                }
4367                return res;
4368            } finally {
4369                Binder.restoreCallingIdentity(origId);
4370            }
4371        }
4372    }
4373
4374    @Override
4375    public final void finishHeavyWeightApp() {
4376        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4377                != PackageManager.PERMISSION_GRANTED) {
4378            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4379                    + Binder.getCallingPid()
4380                    + ", uid=" + Binder.getCallingUid()
4381                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4382            Slog.w(TAG, msg);
4383            throw new SecurityException(msg);
4384        }
4385
4386        synchronized(this) {
4387            if (mHeavyWeightProcess == null) {
4388                return;
4389            }
4390
4391            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4392                    mHeavyWeightProcess.activities);
4393            for (int i=0; i<activities.size(); i++) {
4394                ActivityRecord r = activities.get(i);
4395                if (!r.finishing) {
4396                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4397                            null, "finish-heavy", true);
4398                }
4399            }
4400
4401            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4402                    mHeavyWeightProcess.userId, 0));
4403            mHeavyWeightProcess = null;
4404        }
4405    }
4406
4407    @Override
4408    public void crashApplication(int uid, int initialPid, String packageName,
4409            String message) {
4410        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4411                != PackageManager.PERMISSION_GRANTED) {
4412            String msg = "Permission Denial: crashApplication() from pid="
4413                    + Binder.getCallingPid()
4414                    + ", uid=" + Binder.getCallingUid()
4415                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4416            Slog.w(TAG, msg);
4417            throw new SecurityException(msg);
4418        }
4419
4420        synchronized(this) {
4421            ProcessRecord proc = null;
4422
4423            // Figure out which process to kill.  We don't trust that initialPid
4424            // still has any relation to current pids, so must scan through the
4425            // list.
4426            synchronized (mPidsSelfLocked) {
4427                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4428                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4429                    if (p.uid != uid) {
4430                        continue;
4431                    }
4432                    if (p.pid == initialPid) {
4433                        proc = p;
4434                        break;
4435                    }
4436                    if (p.pkgList.containsKey(packageName)) {
4437                        proc = p;
4438                    }
4439                }
4440            }
4441
4442            if (proc == null) {
4443                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4444                        + " initialPid=" + initialPid
4445                        + " packageName=" + packageName);
4446                return;
4447            }
4448
4449            if (proc.thread != null) {
4450                if (proc.pid == Process.myPid()) {
4451                    Log.w(TAG, "crashApplication: trying to crash self!");
4452                    return;
4453                }
4454                long ident = Binder.clearCallingIdentity();
4455                try {
4456                    proc.thread.scheduleCrash(message);
4457                } catch (RemoteException e) {
4458                }
4459                Binder.restoreCallingIdentity(ident);
4460            }
4461        }
4462    }
4463
4464    @Override
4465    public final void finishSubActivity(IBinder token, String resultWho,
4466            int requestCode) {
4467        synchronized(this) {
4468            final long origId = Binder.clearCallingIdentity();
4469            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4470            if (r != null) {
4471                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4472            }
4473            Binder.restoreCallingIdentity(origId);
4474        }
4475    }
4476
4477    @Override
4478    public boolean finishActivityAffinity(IBinder token) {
4479        synchronized(this) {
4480            final long origId = Binder.clearCallingIdentity();
4481            try {
4482                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4483
4484                ActivityRecord rootR = r.task.getRootActivity();
4485                // Do not allow task to finish in Lock Task mode.
4486                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4487                    if (rootR == r) {
4488                        mStackSupervisor.showLockTaskToast();
4489                        return false;
4490                    }
4491                }
4492                boolean res = false;
4493                if (r != null) {
4494                    res = r.task.stack.finishActivityAffinityLocked(r);
4495                }
4496                return res;
4497            } finally {
4498                Binder.restoreCallingIdentity(origId);
4499            }
4500        }
4501    }
4502
4503    @Override
4504    public void finishVoiceTask(IVoiceInteractionSession session) {
4505        synchronized(this) {
4506            final long origId = Binder.clearCallingIdentity();
4507            try {
4508                mStackSupervisor.finishVoiceTask(session);
4509            } finally {
4510                Binder.restoreCallingIdentity(origId);
4511            }
4512        }
4513
4514    }
4515
4516    @Override
4517    public boolean releaseActivityInstance(IBinder token) {
4518        synchronized(this) {
4519            final long origId = Binder.clearCallingIdentity();
4520            try {
4521                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4522                if (r.task == null || r.task.stack == null) {
4523                    return false;
4524                }
4525                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4526            } finally {
4527                Binder.restoreCallingIdentity(origId);
4528            }
4529        }
4530    }
4531
4532    @Override
4533    public void releaseSomeActivities(IApplicationThread appInt) {
4534        synchronized(this) {
4535            final long origId = Binder.clearCallingIdentity();
4536            try {
4537                ProcessRecord app = getRecordForAppLocked(appInt);
4538                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4539            } finally {
4540                Binder.restoreCallingIdentity(origId);
4541            }
4542        }
4543    }
4544
4545    @Override
4546    public boolean willActivityBeVisible(IBinder token) {
4547        synchronized(this) {
4548            ActivityStack stack = ActivityRecord.getStackLocked(token);
4549            if (stack != null) {
4550                return stack.willActivityBeVisibleLocked(token);
4551            }
4552            return false;
4553        }
4554    }
4555
4556    @Override
4557    public void overridePendingTransition(IBinder token, String packageName,
4558            int enterAnim, int exitAnim) {
4559        synchronized(this) {
4560            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4561            if (self == null) {
4562                return;
4563            }
4564
4565            final long origId = Binder.clearCallingIdentity();
4566
4567            if (self.state == ActivityState.RESUMED
4568                    || self.state == ActivityState.PAUSING) {
4569                mWindowManager.overridePendingAppTransition(packageName,
4570                        enterAnim, exitAnim, null);
4571            }
4572
4573            Binder.restoreCallingIdentity(origId);
4574        }
4575    }
4576
4577    /**
4578     * Main function for removing an existing process from the activity manager
4579     * as a result of that process going away.  Clears out all connections
4580     * to the process.
4581     */
4582    private final void handleAppDiedLocked(ProcessRecord app,
4583            boolean restarting, boolean allowRestart) {
4584        int pid = app.pid;
4585        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4586        if (!restarting) {
4587            removeLruProcessLocked(app);
4588            if (pid > 0) {
4589                ProcessList.remove(pid);
4590            }
4591        }
4592
4593        if (mProfileProc == app) {
4594            clearProfilerLocked();
4595        }
4596
4597        // Remove this application's activities from active lists.
4598        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4599
4600        app.activities.clear();
4601
4602        if (app.instrumentationClass != null) {
4603            Slog.w(TAG, "Crash of app " + app.processName
4604                  + " running instrumentation " + app.instrumentationClass);
4605            Bundle info = new Bundle();
4606            info.putString("shortMsg", "Process crashed.");
4607            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4608        }
4609
4610        if (!restarting) {
4611            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4612                // If there was nothing to resume, and we are not already
4613                // restarting this process, but there is a visible activity that
4614                // is hosted by the process...  then make sure all visible
4615                // activities are running, taking care of restarting this
4616                // process.
4617                if (hasVisibleActivities) {
4618                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4619                }
4620            }
4621        }
4622    }
4623
4624    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4625        IBinder threadBinder = thread.asBinder();
4626        // Find the application record.
4627        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4628            ProcessRecord rec = mLruProcesses.get(i);
4629            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4630                return i;
4631            }
4632        }
4633        return -1;
4634    }
4635
4636    final ProcessRecord getRecordForAppLocked(
4637            IApplicationThread thread) {
4638        if (thread == null) {
4639            return null;
4640        }
4641
4642        int appIndex = getLRURecordIndexForAppLocked(thread);
4643        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4644    }
4645
4646    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4647        // If there are no longer any background processes running,
4648        // and the app that died was not running instrumentation,
4649        // then tell everyone we are now low on memory.
4650        boolean haveBg = false;
4651        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4652            ProcessRecord rec = mLruProcesses.get(i);
4653            if (rec.thread != null
4654                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4655                haveBg = true;
4656                break;
4657            }
4658        }
4659
4660        if (!haveBg) {
4661            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4662            if (doReport) {
4663                long now = SystemClock.uptimeMillis();
4664                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4665                    doReport = false;
4666                } else {
4667                    mLastMemUsageReportTime = now;
4668                }
4669            }
4670            final ArrayList<ProcessMemInfo> memInfos
4671                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4672            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4673            long now = SystemClock.uptimeMillis();
4674            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4675                ProcessRecord rec = mLruProcesses.get(i);
4676                if (rec == dyingProc || rec.thread == null) {
4677                    continue;
4678                }
4679                if (doReport) {
4680                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4681                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4682                }
4683                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4684                    // The low memory report is overriding any current
4685                    // state for a GC request.  Make sure to do
4686                    // heavy/important/visible/foreground processes first.
4687                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4688                        rec.lastRequestedGc = 0;
4689                    } else {
4690                        rec.lastRequestedGc = rec.lastLowMemory;
4691                    }
4692                    rec.reportLowMemory = true;
4693                    rec.lastLowMemory = now;
4694                    mProcessesToGc.remove(rec);
4695                    addProcessToGcListLocked(rec);
4696                }
4697            }
4698            if (doReport) {
4699                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4700                mHandler.sendMessage(msg);
4701            }
4702            scheduleAppGcsLocked();
4703        }
4704    }
4705
4706    final void appDiedLocked(ProcessRecord app) {
4707       appDiedLocked(app, app.pid, app.thread);
4708    }
4709
4710    final void appDiedLocked(ProcessRecord app, int pid,
4711            IApplicationThread thread) {
4712
4713        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4714        synchronized (stats) {
4715            stats.noteProcessDiedLocked(app.info.uid, pid);
4716        }
4717
4718        Process.killProcessGroup(app.info.uid, pid);
4719
4720        // Clean up already done if the process has been re-started.
4721        if (app.pid == pid && app.thread != null &&
4722                app.thread.asBinder() == thread.asBinder()) {
4723            boolean doLowMem = app.instrumentationClass == null;
4724            boolean doOomAdj = doLowMem;
4725            if (!app.killedByAm) {
4726                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4727                        + ") has died.");
4728                mAllowLowerMemLevel = true;
4729            } else {
4730                // Note that we always want to do oom adj to update our state with the
4731                // new number of procs.
4732                mAllowLowerMemLevel = false;
4733                doLowMem = false;
4734            }
4735            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4736            if (DEBUG_CLEANUP) Slog.v(
4737                TAG, "Dying app: " + app + ", pid: " + pid
4738                + ", thread: " + thread.asBinder());
4739            handleAppDiedLocked(app, false, true);
4740
4741            if (doOomAdj) {
4742                updateOomAdjLocked();
4743            }
4744            if (doLowMem) {
4745                doLowMemReportIfNeededLocked(app);
4746            }
4747        } else if (app.pid != pid) {
4748            // A new process has already been started.
4749            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4750                    + ") has died and restarted (pid " + app.pid + ").");
4751            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4752        } else if (DEBUG_PROCESSES) {
4753            Slog.d(TAG, "Received spurious death notification for thread "
4754                    + thread.asBinder());
4755        }
4756    }
4757
4758    /**
4759     * If a stack trace dump file is configured, dump process stack traces.
4760     * @param clearTraces causes the dump file to be erased prior to the new
4761     *    traces being written, if true; when false, the new traces will be
4762     *    appended to any existing file content.
4763     * @param firstPids of dalvik VM processes to dump stack traces for first
4764     * @param lastPids of dalvik VM processes to dump stack traces for last
4765     * @param nativeProcs optional list of native process names to dump stack crawls
4766     * @return file containing stack traces, or null if no dump file is configured
4767     */
4768    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4769            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4770        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4771        if (tracesPath == null || tracesPath.length() == 0) {
4772            return null;
4773        }
4774
4775        File tracesFile = new File(tracesPath);
4776        try {
4777            File tracesDir = tracesFile.getParentFile();
4778            if (!tracesDir.exists()) {
4779                tracesFile.mkdirs();
4780                if (!SELinux.restorecon(tracesDir)) {
4781                    return null;
4782                }
4783            }
4784            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4785
4786            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4787            tracesFile.createNewFile();
4788            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4789        } catch (IOException e) {
4790            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4791            return null;
4792        }
4793
4794        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4795        return tracesFile;
4796    }
4797
4798    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4799            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4800        // Use a FileObserver to detect when traces finish writing.
4801        // The order of traces is considered important to maintain for legibility.
4802        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4803            @Override
4804            public synchronized void onEvent(int event, String path) { notify(); }
4805        };
4806
4807        try {
4808            observer.startWatching();
4809
4810            // First collect all of the stacks of the most important pids.
4811            if (firstPids != null) {
4812                try {
4813                    int num = firstPids.size();
4814                    for (int i = 0; i < num; i++) {
4815                        synchronized (observer) {
4816                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4817                            observer.wait(200);  // Wait for write-close, give up after 200msec
4818                        }
4819                    }
4820                } catch (InterruptedException e) {
4821                    Log.wtf(TAG, e);
4822                }
4823            }
4824
4825            // Next collect the stacks of the native pids
4826            if (nativeProcs != null) {
4827                int[] pids = Process.getPidsForCommands(nativeProcs);
4828                if (pids != null) {
4829                    for (int pid : pids) {
4830                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4831                    }
4832                }
4833            }
4834
4835            // Lastly, measure CPU usage.
4836            if (processCpuTracker != null) {
4837                processCpuTracker.init();
4838                System.gc();
4839                processCpuTracker.update();
4840                try {
4841                    synchronized (processCpuTracker) {
4842                        processCpuTracker.wait(500); // measure over 1/2 second.
4843                    }
4844                } catch (InterruptedException e) {
4845                }
4846                processCpuTracker.update();
4847
4848                // We'll take the stack crawls of just the top apps using CPU.
4849                final int N = processCpuTracker.countWorkingStats();
4850                int numProcs = 0;
4851                for (int i=0; i<N && numProcs<5; i++) {
4852                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4853                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4854                        numProcs++;
4855                        try {
4856                            synchronized (observer) {
4857                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4858                                observer.wait(200);  // Wait for write-close, give up after 200msec
4859                            }
4860                        } catch (InterruptedException e) {
4861                            Log.wtf(TAG, e);
4862                        }
4863
4864                    }
4865                }
4866            }
4867        } finally {
4868            observer.stopWatching();
4869        }
4870    }
4871
4872    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4873        if (true || IS_USER_BUILD) {
4874            return;
4875        }
4876        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4877        if (tracesPath == null || tracesPath.length() == 0) {
4878            return;
4879        }
4880
4881        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4882        StrictMode.allowThreadDiskWrites();
4883        try {
4884            final File tracesFile = new File(tracesPath);
4885            final File tracesDir = tracesFile.getParentFile();
4886            final File tracesTmp = new File(tracesDir, "__tmp__");
4887            try {
4888                if (!tracesDir.exists()) {
4889                    tracesFile.mkdirs();
4890                    if (!SELinux.restorecon(tracesDir.getPath())) {
4891                        return;
4892                    }
4893                }
4894                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4895
4896                if (tracesFile.exists()) {
4897                    tracesTmp.delete();
4898                    tracesFile.renameTo(tracesTmp);
4899                }
4900                StringBuilder sb = new StringBuilder();
4901                Time tobj = new Time();
4902                tobj.set(System.currentTimeMillis());
4903                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4904                sb.append(": ");
4905                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4906                sb.append(" since ");
4907                sb.append(msg);
4908                FileOutputStream fos = new FileOutputStream(tracesFile);
4909                fos.write(sb.toString().getBytes());
4910                if (app == null) {
4911                    fos.write("\n*** No application process!".getBytes());
4912                }
4913                fos.close();
4914                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4915            } catch (IOException e) {
4916                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4917                return;
4918            }
4919
4920            if (app != null) {
4921                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4922                firstPids.add(app.pid);
4923                dumpStackTraces(tracesPath, firstPids, null, null, null);
4924            }
4925
4926            File lastTracesFile = null;
4927            File curTracesFile = null;
4928            for (int i=9; i>=0; i--) {
4929                String name = String.format(Locale.US, "slow%02d.txt", i);
4930                curTracesFile = new File(tracesDir, name);
4931                if (curTracesFile.exists()) {
4932                    if (lastTracesFile != null) {
4933                        curTracesFile.renameTo(lastTracesFile);
4934                    } else {
4935                        curTracesFile.delete();
4936                    }
4937                }
4938                lastTracesFile = curTracesFile;
4939            }
4940            tracesFile.renameTo(curTracesFile);
4941            if (tracesTmp.exists()) {
4942                tracesTmp.renameTo(tracesFile);
4943            }
4944        } finally {
4945            StrictMode.setThreadPolicy(oldPolicy);
4946        }
4947    }
4948
4949    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4950            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4951        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4952        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4953
4954        if (mController != null) {
4955            try {
4956                // 0 == continue, -1 = kill process immediately
4957                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4958                if (res < 0 && app.pid != MY_PID) {
4959                    app.kill("anr", true);
4960                }
4961            } catch (RemoteException e) {
4962                mController = null;
4963                Watchdog.getInstance().setActivityController(null);
4964            }
4965        }
4966
4967        long anrTime = SystemClock.uptimeMillis();
4968        if (MONITOR_CPU_USAGE) {
4969            updateCpuStatsNow();
4970        }
4971
4972        synchronized (this) {
4973            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4974            if (mShuttingDown) {
4975                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4976                return;
4977            } else if (app.notResponding) {
4978                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4979                return;
4980            } else if (app.crashing) {
4981                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4982                return;
4983            }
4984
4985            // In case we come through here for the same app before completing
4986            // this one, mark as anring now so we will bail out.
4987            app.notResponding = true;
4988
4989            // Log the ANR to the event log.
4990            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4991                    app.processName, app.info.flags, annotation);
4992
4993            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4994            firstPids.add(app.pid);
4995
4996            int parentPid = app.pid;
4997            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4998            if (parentPid != app.pid) firstPids.add(parentPid);
4999
5000            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5001
5002            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5003                ProcessRecord r = mLruProcesses.get(i);
5004                if (r != null && r.thread != null) {
5005                    int pid = r.pid;
5006                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5007                        if (r.persistent) {
5008                            firstPids.add(pid);
5009                        } else {
5010                            lastPids.put(pid, Boolean.TRUE);
5011                        }
5012                    }
5013                }
5014            }
5015        }
5016
5017        // Log the ANR to the main log.
5018        StringBuilder info = new StringBuilder();
5019        info.setLength(0);
5020        info.append("ANR in ").append(app.processName);
5021        if (activity != null && activity.shortComponentName != null) {
5022            info.append(" (").append(activity.shortComponentName).append(")");
5023        }
5024        info.append("\n");
5025        info.append("PID: ").append(app.pid).append("\n");
5026        if (annotation != null) {
5027            info.append("Reason: ").append(annotation).append("\n");
5028        }
5029        if (parent != null && parent != activity) {
5030            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5031        }
5032
5033        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5034
5035        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5036                NATIVE_STACKS_OF_INTEREST);
5037
5038        String cpuInfo = null;
5039        if (MONITOR_CPU_USAGE) {
5040            updateCpuStatsNow();
5041            synchronized (mProcessCpuThread) {
5042                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5043            }
5044            info.append(processCpuTracker.printCurrentLoad());
5045            info.append(cpuInfo);
5046        }
5047
5048        info.append(processCpuTracker.printCurrentState(anrTime));
5049
5050        Slog.e(TAG, info.toString());
5051        if (tracesFile == null) {
5052            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5053            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5054        }
5055
5056        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5057                cpuInfo, tracesFile, null);
5058
5059        if (mController != null) {
5060            try {
5061                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5062                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5063                if (res != 0) {
5064                    if (res < 0 && app.pid != MY_PID) {
5065                        app.kill("anr", true);
5066                    } else {
5067                        synchronized (this) {
5068                            mServices.scheduleServiceTimeoutLocked(app);
5069                        }
5070                    }
5071                    return;
5072                }
5073            } catch (RemoteException e) {
5074                mController = null;
5075                Watchdog.getInstance().setActivityController(null);
5076            }
5077        }
5078
5079        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5080        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5081                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5082
5083        synchronized (this) {
5084            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5085                app.kill("bg anr", true);
5086                return;
5087            }
5088
5089            // Set the app's notResponding state, and look up the errorReportReceiver
5090            makeAppNotRespondingLocked(app,
5091                    activity != null ? activity.shortComponentName : null,
5092                    annotation != null ? "ANR " + annotation : "ANR",
5093                    info.toString());
5094
5095            // Bring up the infamous App Not Responding dialog
5096            Message msg = Message.obtain();
5097            HashMap<String, Object> map = new HashMap<String, Object>();
5098            msg.what = SHOW_NOT_RESPONDING_MSG;
5099            msg.obj = map;
5100            msg.arg1 = aboveSystem ? 1 : 0;
5101            map.put("app", app);
5102            if (activity != null) {
5103                map.put("activity", activity);
5104            }
5105
5106            mHandler.sendMessage(msg);
5107        }
5108    }
5109
5110    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5111        if (!mLaunchWarningShown) {
5112            mLaunchWarningShown = true;
5113            mHandler.post(new Runnable() {
5114                @Override
5115                public void run() {
5116                    synchronized (ActivityManagerService.this) {
5117                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5118                        d.show();
5119                        mHandler.postDelayed(new Runnable() {
5120                            @Override
5121                            public void run() {
5122                                synchronized (ActivityManagerService.this) {
5123                                    d.dismiss();
5124                                    mLaunchWarningShown = false;
5125                                }
5126                            }
5127                        }, 4000);
5128                    }
5129                }
5130            });
5131        }
5132    }
5133
5134    @Override
5135    public boolean clearApplicationUserData(final String packageName,
5136            final IPackageDataObserver observer, int userId) {
5137        enforceNotIsolatedCaller("clearApplicationUserData");
5138        int uid = Binder.getCallingUid();
5139        int pid = Binder.getCallingPid();
5140        userId = handleIncomingUser(pid, uid,
5141                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5142        long callingId = Binder.clearCallingIdentity();
5143        try {
5144            IPackageManager pm = AppGlobals.getPackageManager();
5145            int pkgUid = -1;
5146            synchronized(this) {
5147                try {
5148                    pkgUid = pm.getPackageUid(packageName, userId);
5149                } catch (RemoteException e) {
5150                }
5151                if (pkgUid == -1) {
5152                    Slog.w(TAG, "Invalid packageName: " + packageName);
5153                    if (observer != null) {
5154                        try {
5155                            observer.onRemoveCompleted(packageName, false);
5156                        } catch (RemoteException e) {
5157                            Slog.i(TAG, "Observer no longer exists.");
5158                        }
5159                    }
5160                    return false;
5161                }
5162                if (uid == pkgUid || checkComponentPermission(
5163                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5164                        pid, uid, -1, true)
5165                        == PackageManager.PERMISSION_GRANTED) {
5166                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5167                } else {
5168                    throw new SecurityException("PID " + pid + " does not have permission "
5169                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5170                                    + " of package " + packageName);
5171                }
5172
5173                // Remove all tasks match the cleared application package and user
5174                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5175                    final TaskRecord tr = mRecentTasks.get(i);
5176                    final String taskPackageName =
5177                            tr.getBaseIntent().getComponent().getPackageName();
5178                    if (tr.userId != userId) continue;
5179                    if (!taskPackageName.equals(packageName)) continue;
5180                    removeTaskByIdLocked(tr.taskId, 0);
5181                }
5182            }
5183
5184            try {
5185                // Clear application user data
5186                pm.clearApplicationUserData(packageName, observer, userId);
5187
5188                synchronized(this) {
5189                    // Remove all permissions granted from/to this package
5190                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5191                }
5192
5193                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5194                        Uri.fromParts("package", packageName, null));
5195                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5196                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5197                        null, null, 0, null, null, null, false, false, userId);
5198            } catch (RemoteException e) {
5199            }
5200        } finally {
5201            Binder.restoreCallingIdentity(callingId);
5202        }
5203        return true;
5204    }
5205
5206    @Override
5207    public void killBackgroundProcesses(final String packageName, int userId) {
5208        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5209                != PackageManager.PERMISSION_GRANTED &&
5210                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5211                        != PackageManager.PERMISSION_GRANTED) {
5212            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5213                    + Binder.getCallingPid()
5214                    + ", uid=" + Binder.getCallingUid()
5215                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5216            Slog.w(TAG, msg);
5217            throw new SecurityException(msg);
5218        }
5219
5220        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5221                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5222        long callingId = Binder.clearCallingIdentity();
5223        try {
5224            IPackageManager pm = AppGlobals.getPackageManager();
5225            synchronized(this) {
5226                int appId = -1;
5227                try {
5228                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5229                } catch (RemoteException e) {
5230                }
5231                if (appId == -1) {
5232                    Slog.w(TAG, "Invalid packageName: " + packageName);
5233                    return;
5234                }
5235                killPackageProcessesLocked(packageName, appId, userId,
5236                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5237            }
5238        } finally {
5239            Binder.restoreCallingIdentity(callingId);
5240        }
5241    }
5242
5243    @Override
5244    public void killAllBackgroundProcesses() {
5245        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5246                != PackageManager.PERMISSION_GRANTED) {
5247            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5248                    + Binder.getCallingPid()
5249                    + ", uid=" + Binder.getCallingUid()
5250                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5251            Slog.w(TAG, msg);
5252            throw new SecurityException(msg);
5253        }
5254
5255        long callingId = Binder.clearCallingIdentity();
5256        try {
5257            synchronized(this) {
5258                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5259                final int NP = mProcessNames.getMap().size();
5260                for (int ip=0; ip<NP; ip++) {
5261                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5262                    final int NA = apps.size();
5263                    for (int ia=0; ia<NA; ia++) {
5264                        ProcessRecord app = apps.valueAt(ia);
5265                        if (app.persistent) {
5266                            // we don't kill persistent processes
5267                            continue;
5268                        }
5269                        if (app.removed) {
5270                            procs.add(app);
5271                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5272                            app.removed = true;
5273                            procs.add(app);
5274                        }
5275                    }
5276                }
5277
5278                int N = procs.size();
5279                for (int i=0; i<N; i++) {
5280                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5281                }
5282                mAllowLowerMemLevel = true;
5283                updateOomAdjLocked();
5284                doLowMemReportIfNeededLocked(null);
5285            }
5286        } finally {
5287            Binder.restoreCallingIdentity(callingId);
5288        }
5289    }
5290
5291    @Override
5292    public void forceStopPackage(final String packageName, int userId) {
5293        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5294                != PackageManager.PERMISSION_GRANTED) {
5295            String msg = "Permission Denial: forceStopPackage() from pid="
5296                    + Binder.getCallingPid()
5297                    + ", uid=" + Binder.getCallingUid()
5298                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5299            Slog.w(TAG, msg);
5300            throw new SecurityException(msg);
5301        }
5302        final int callingPid = Binder.getCallingPid();
5303        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5304                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5305        long callingId = Binder.clearCallingIdentity();
5306        try {
5307            IPackageManager pm = AppGlobals.getPackageManager();
5308            synchronized(this) {
5309                int[] users = userId == UserHandle.USER_ALL
5310                        ? getUsersLocked() : new int[] { userId };
5311                for (int user : users) {
5312                    int pkgUid = -1;
5313                    try {
5314                        pkgUid = pm.getPackageUid(packageName, user);
5315                    } catch (RemoteException e) {
5316                    }
5317                    if (pkgUid == -1) {
5318                        Slog.w(TAG, "Invalid packageName: " + packageName);
5319                        continue;
5320                    }
5321                    try {
5322                        pm.setPackageStoppedState(packageName, true, user);
5323                    } catch (RemoteException e) {
5324                    } catch (IllegalArgumentException e) {
5325                        Slog.w(TAG, "Failed trying to unstop package "
5326                                + packageName + ": " + e);
5327                    }
5328                    if (isUserRunningLocked(user, false)) {
5329                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5330                    }
5331                }
5332            }
5333        } finally {
5334            Binder.restoreCallingIdentity(callingId);
5335        }
5336    }
5337
5338    @Override
5339    public void addPackageDependency(String packageName) {
5340        synchronized (this) {
5341            int callingPid = Binder.getCallingPid();
5342            if (callingPid == Process.myPid()) {
5343                //  Yeah, um, no.
5344                Slog.w(TAG, "Can't addPackageDependency on system process");
5345                return;
5346            }
5347            ProcessRecord proc;
5348            synchronized (mPidsSelfLocked) {
5349                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5350            }
5351            if (proc != null) {
5352                if (proc.pkgDeps == null) {
5353                    proc.pkgDeps = new ArraySet<String>(1);
5354                }
5355                proc.pkgDeps.add(packageName);
5356            }
5357        }
5358    }
5359
5360    /*
5361     * The pkg name and app id have to be specified.
5362     */
5363    @Override
5364    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5365        if (pkg == null) {
5366            return;
5367        }
5368        // Make sure the uid is valid.
5369        if (appid < 0) {
5370            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5371            return;
5372        }
5373        int callerUid = Binder.getCallingUid();
5374        // Only the system server can kill an application
5375        if (callerUid == Process.SYSTEM_UID) {
5376            // Post an aysnc message to kill the application
5377            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5378            msg.arg1 = appid;
5379            msg.arg2 = 0;
5380            Bundle bundle = new Bundle();
5381            bundle.putString("pkg", pkg);
5382            bundle.putString("reason", reason);
5383            msg.obj = bundle;
5384            mHandler.sendMessage(msg);
5385        } else {
5386            throw new SecurityException(callerUid + " cannot kill pkg: " +
5387                    pkg);
5388        }
5389    }
5390
5391    @Override
5392    public void closeSystemDialogs(String reason) {
5393        enforceNotIsolatedCaller("closeSystemDialogs");
5394
5395        final int pid = Binder.getCallingPid();
5396        final int uid = Binder.getCallingUid();
5397        final long origId = Binder.clearCallingIdentity();
5398        try {
5399            synchronized (this) {
5400                // Only allow this from foreground processes, so that background
5401                // applications can't abuse it to prevent system UI from being shown.
5402                if (uid >= Process.FIRST_APPLICATION_UID) {
5403                    ProcessRecord proc;
5404                    synchronized (mPidsSelfLocked) {
5405                        proc = mPidsSelfLocked.get(pid);
5406                    }
5407                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5408                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5409                                + " from background process " + proc);
5410                        return;
5411                    }
5412                }
5413                closeSystemDialogsLocked(reason);
5414            }
5415        } finally {
5416            Binder.restoreCallingIdentity(origId);
5417        }
5418    }
5419
5420    void closeSystemDialogsLocked(String reason) {
5421        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5422        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5423                | Intent.FLAG_RECEIVER_FOREGROUND);
5424        if (reason != null) {
5425            intent.putExtra("reason", reason);
5426        }
5427        mWindowManager.closeSystemDialogs(reason);
5428
5429        mStackSupervisor.closeSystemDialogsLocked();
5430
5431        broadcastIntentLocked(null, null, intent, null,
5432                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5433                Process.SYSTEM_UID, UserHandle.USER_ALL);
5434    }
5435
5436    @Override
5437    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5438        enforceNotIsolatedCaller("getProcessMemoryInfo");
5439        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5440        for (int i=pids.length-1; i>=0; i--) {
5441            ProcessRecord proc;
5442            int oomAdj;
5443            synchronized (this) {
5444                synchronized (mPidsSelfLocked) {
5445                    proc = mPidsSelfLocked.get(pids[i]);
5446                    oomAdj = proc != null ? proc.setAdj : 0;
5447                }
5448            }
5449            infos[i] = new Debug.MemoryInfo();
5450            Debug.getMemoryInfo(pids[i], infos[i]);
5451            if (proc != null) {
5452                synchronized (this) {
5453                    if (proc.thread != null && proc.setAdj == oomAdj) {
5454                        // Record this for posterity if the process has been stable.
5455                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5456                                infos[i].getTotalUss(), false, proc.pkgList);
5457                    }
5458                }
5459            }
5460        }
5461        return infos;
5462    }
5463
5464    @Override
5465    public long[] getProcessPss(int[] pids) {
5466        enforceNotIsolatedCaller("getProcessPss");
5467        long[] pss = new long[pids.length];
5468        for (int i=pids.length-1; i>=0; i--) {
5469            ProcessRecord proc;
5470            int oomAdj;
5471            synchronized (this) {
5472                synchronized (mPidsSelfLocked) {
5473                    proc = mPidsSelfLocked.get(pids[i]);
5474                    oomAdj = proc != null ? proc.setAdj : 0;
5475                }
5476            }
5477            long[] tmpUss = new long[1];
5478            pss[i] = Debug.getPss(pids[i], tmpUss);
5479            if (proc != null) {
5480                synchronized (this) {
5481                    if (proc.thread != null && proc.setAdj == oomAdj) {
5482                        // Record this for posterity if the process has been stable.
5483                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5484                    }
5485                }
5486            }
5487        }
5488        return pss;
5489    }
5490
5491    @Override
5492    public void killApplicationProcess(String processName, int uid) {
5493        if (processName == null) {
5494            return;
5495        }
5496
5497        int callerUid = Binder.getCallingUid();
5498        // Only the system server can kill an application
5499        if (callerUid == Process.SYSTEM_UID) {
5500            synchronized (this) {
5501                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5502                if (app != null && app.thread != null) {
5503                    try {
5504                        app.thread.scheduleSuicide();
5505                    } catch (RemoteException e) {
5506                        // If the other end already died, then our work here is done.
5507                    }
5508                } else {
5509                    Slog.w(TAG, "Process/uid not found attempting kill of "
5510                            + processName + " / " + uid);
5511                }
5512            }
5513        } else {
5514            throw new SecurityException(callerUid + " cannot kill app process: " +
5515                    processName);
5516        }
5517    }
5518
5519    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5520        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5521                false, true, false, false, UserHandle.getUserId(uid), reason);
5522        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5523                Uri.fromParts("package", packageName, null));
5524        if (!mProcessesReady) {
5525            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5526                    | Intent.FLAG_RECEIVER_FOREGROUND);
5527        }
5528        intent.putExtra(Intent.EXTRA_UID, uid);
5529        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5530        broadcastIntentLocked(null, null, intent,
5531                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5532                false, false,
5533                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5534    }
5535
5536    private void forceStopUserLocked(int userId, String reason) {
5537        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5538        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5539        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5540                | Intent.FLAG_RECEIVER_FOREGROUND);
5541        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5542        broadcastIntentLocked(null, null, intent,
5543                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5544                false, false,
5545                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5546    }
5547
5548    private final boolean killPackageProcessesLocked(String packageName, int appId,
5549            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5550            boolean doit, boolean evenPersistent, String reason) {
5551        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5552
5553        // Remove all processes this package may have touched: all with the
5554        // same UID (except for the system or root user), and all whose name
5555        // matches the package name.
5556        final int NP = mProcessNames.getMap().size();
5557        for (int ip=0; ip<NP; ip++) {
5558            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5559            final int NA = apps.size();
5560            for (int ia=0; ia<NA; ia++) {
5561                ProcessRecord app = apps.valueAt(ia);
5562                if (app.persistent && !evenPersistent) {
5563                    // we don't kill persistent processes
5564                    continue;
5565                }
5566                if (app.removed) {
5567                    if (doit) {
5568                        procs.add(app);
5569                    }
5570                    continue;
5571                }
5572
5573                // Skip process if it doesn't meet our oom adj requirement.
5574                if (app.setAdj < minOomAdj) {
5575                    continue;
5576                }
5577
5578                // If no package is specified, we call all processes under the
5579                // give user id.
5580                if (packageName == null) {
5581                    if (app.userId != userId) {
5582                        continue;
5583                    }
5584                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5585                        continue;
5586                    }
5587                // Package has been specified, we want to hit all processes
5588                // that match it.  We need to qualify this by the processes
5589                // that are running under the specified app and user ID.
5590                } else {
5591                    final boolean isDep = app.pkgDeps != null
5592                            && app.pkgDeps.contains(packageName);
5593                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5594                        continue;
5595                    }
5596                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5597                        continue;
5598                    }
5599                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5600                        continue;
5601                    }
5602                }
5603
5604                // Process has passed all conditions, kill it!
5605                if (!doit) {
5606                    return true;
5607                }
5608                app.removed = true;
5609                procs.add(app);
5610            }
5611        }
5612
5613        int N = procs.size();
5614        for (int i=0; i<N; i++) {
5615            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5616        }
5617        updateOomAdjLocked();
5618        return N > 0;
5619    }
5620
5621    private final boolean forceStopPackageLocked(String name, int appId,
5622            boolean callerWillRestart, boolean purgeCache, boolean doit,
5623            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5624        int i;
5625        int N;
5626
5627        if (userId == UserHandle.USER_ALL && name == null) {
5628            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5629        }
5630
5631        if (appId < 0 && name != null) {
5632            try {
5633                appId = UserHandle.getAppId(
5634                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5635            } catch (RemoteException e) {
5636            }
5637        }
5638
5639        if (doit) {
5640            if (name != null) {
5641                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5642                        + " user=" + userId + ": " + reason);
5643            } else {
5644                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5645            }
5646
5647            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5648            for (int ip=pmap.size()-1; ip>=0; ip--) {
5649                SparseArray<Long> ba = pmap.valueAt(ip);
5650                for (i=ba.size()-1; i>=0; i--) {
5651                    boolean remove = false;
5652                    final int entUid = ba.keyAt(i);
5653                    if (name != null) {
5654                        if (userId == UserHandle.USER_ALL) {
5655                            if (UserHandle.getAppId(entUid) == appId) {
5656                                remove = true;
5657                            }
5658                        } else {
5659                            if (entUid == UserHandle.getUid(userId, appId)) {
5660                                remove = true;
5661                            }
5662                        }
5663                    } else if (UserHandle.getUserId(entUid) == userId) {
5664                        remove = true;
5665                    }
5666                    if (remove) {
5667                        ba.removeAt(i);
5668                    }
5669                }
5670                if (ba.size() == 0) {
5671                    pmap.removeAt(ip);
5672                }
5673            }
5674        }
5675
5676        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5677                -100, callerWillRestart, true, doit, evenPersistent,
5678                name == null ? ("stop user " + userId) : ("stop " + name));
5679
5680        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5681            if (!doit) {
5682                return true;
5683            }
5684            didSomething = true;
5685        }
5686
5687        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5688            if (!doit) {
5689                return true;
5690            }
5691            didSomething = true;
5692        }
5693
5694        if (name == null) {
5695            // Remove all sticky broadcasts from this user.
5696            mStickyBroadcasts.remove(userId);
5697        }
5698
5699        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5700        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5701                userId, providers)) {
5702            if (!doit) {
5703                return true;
5704            }
5705            didSomething = true;
5706        }
5707        N = providers.size();
5708        for (i=0; i<N; i++) {
5709            removeDyingProviderLocked(null, providers.get(i), true);
5710        }
5711
5712        // Remove transient permissions granted from/to this package/user
5713        removeUriPermissionsForPackageLocked(name, userId, false);
5714
5715        if (name == null || uninstalling) {
5716            // Remove pending intents.  For now we only do this when force
5717            // stopping users, because we have some problems when doing this
5718            // for packages -- app widgets are not currently cleaned up for
5719            // such packages, so they can be left with bad pending intents.
5720            if (mIntentSenderRecords.size() > 0) {
5721                Iterator<WeakReference<PendingIntentRecord>> it
5722                        = mIntentSenderRecords.values().iterator();
5723                while (it.hasNext()) {
5724                    WeakReference<PendingIntentRecord> wpir = it.next();
5725                    if (wpir == null) {
5726                        it.remove();
5727                        continue;
5728                    }
5729                    PendingIntentRecord pir = wpir.get();
5730                    if (pir == null) {
5731                        it.remove();
5732                        continue;
5733                    }
5734                    if (name == null) {
5735                        // Stopping user, remove all objects for the user.
5736                        if (pir.key.userId != userId) {
5737                            // Not the same user, skip it.
5738                            continue;
5739                        }
5740                    } else {
5741                        if (UserHandle.getAppId(pir.uid) != appId) {
5742                            // Different app id, skip it.
5743                            continue;
5744                        }
5745                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5746                            // Different user, skip it.
5747                            continue;
5748                        }
5749                        if (!pir.key.packageName.equals(name)) {
5750                            // Different package, skip it.
5751                            continue;
5752                        }
5753                    }
5754                    if (!doit) {
5755                        return true;
5756                    }
5757                    didSomething = true;
5758                    it.remove();
5759                    pir.canceled = true;
5760                    if (pir.key.activity != null) {
5761                        pir.key.activity.pendingResults.remove(pir.ref);
5762                    }
5763                }
5764            }
5765        }
5766
5767        if (doit) {
5768            if (purgeCache && name != null) {
5769                AttributeCache ac = AttributeCache.instance();
5770                if (ac != null) {
5771                    ac.removePackage(name);
5772                }
5773            }
5774            if (mBooted) {
5775                mStackSupervisor.resumeTopActivitiesLocked();
5776                mStackSupervisor.scheduleIdleLocked();
5777            }
5778        }
5779
5780        return didSomething;
5781    }
5782
5783    private final boolean removeProcessLocked(ProcessRecord app,
5784            boolean callerWillRestart, boolean allowRestart, String reason) {
5785        final String name = app.processName;
5786        final int uid = app.uid;
5787        if (DEBUG_PROCESSES) Slog.d(
5788            TAG, "Force removing proc " + app.toShortString() + " (" + name
5789            + "/" + uid + ")");
5790
5791        mProcessNames.remove(name, uid);
5792        mIsolatedProcesses.remove(app.uid);
5793        if (mHeavyWeightProcess == app) {
5794            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5795                    mHeavyWeightProcess.userId, 0));
5796            mHeavyWeightProcess = null;
5797        }
5798        boolean needRestart = false;
5799        if (app.pid > 0 && app.pid != MY_PID) {
5800            int pid = app.pid;
5801            synchronized (mPidsSelfLocked) {
5802                mPidsSelfLocked.remove(pid);
5803                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5804            }
5805            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5806            if (app.isolated) {
5807                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5808            }
5809            app.kill(reason, true);
5810            handleAppDiedLocked(app, true, allowRestart);
5811            removeLruProcessLocked(app);
5812
5813            if (app.persistent && !app.isolated) {
5814                if (!callerWillRestart) {
5815                    addAppLocked(app.info, false, null /* ABI override */);
5816                } else {
5817                    needRestart = true;
5818                }
5819            }
5820        } else {
5821            mRemovedProcesses.add(app);
5822        }
5823
5824        return needRestart;
5825    }
5826
5827    private final void processStartTimedOutLocked(ProcessRecord app) {
5828        final int pid = app.pid;
5829        boolean gone = false;
5830        synchronized (mPidsSelfLocked) {
5831            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5832            if (knownApp != null && knownApp.thread == null) {
5833                mPidsSelfLocked.remove(pid);
5834                gone = true;
5835            }
5836        }
5837
5838        if (gone) {
5839            Slog.w(TAG, "Process " + app + " failed to attach");
5840            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5841                    pid, app.uid, app.processName);
5842            mProcessNames.remove(app.processName, app.uid);
5843            mIsolatedProcesses.remove(app.uid);
5844            if (mHeavyWeightProcess == app) {
5845                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5846                        mHeavyWeightProcess.userId, 0));
5847                mHeavyWeightProcess = null;
5848            }
5849            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5850            if (app.isolated) {
5851                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5852            }
5853            // Take care of any launching providers waiting for this process.
5854            checkAppInLaunchingProvidersLocked(app, true);
5855            // Take care of any services that are waiting for the process.
5856            mServices.processStartTimedOutLocked(app);
5857            app.kill("start timeout", true);
5858            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5859                Slog.w(TAG, "Unattached app died before backup, skipping");
5860                try {
5861                    IBackupManager bm = IBackupManager.Stub.asInterface(
5862                            ServiceManager.getService(Context.BACKUP_SERVICE));
5863                    bm.agentDisconnected(app.info.packageName);
5864                } catch (RemoteException e) {
5865                    // Can't happen; the backup manager is local
5866                }
5867            }
5868            if (isPendingBroadcastProcessLocked(pid)) {
5869                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5870                skipPendingBroadcastLocked(pid);
5871            }
5872        } else {
5873            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5874        }
5875    }
5876
5877    private final boolean attachApplicationLocked(IApplicationThread thread,
5878            int pid) {
5879
5880        // Find the application record that is being attached...  either via
5881        // the pid if we are running in multiple processes, or just pull the
5882        // next app record if we are emulating process with anonymous threads.
5883        ProcessRecord app;
5884        if (pid != MY_PID && pid >= 0) {
5885            synchronized (mPidsSelfLocked) {
5886                app = mPidsSelfLocked.get(pid);
5887            }
5888        } else {
5889            app = null;
5890        }
5891
5892        if (app == null) {
5893            Slog.w(TAG, "No pending application record for pid " + pid
5894                    + " (IApplicationThread " + thread + "); dropping process");
5895            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5896            if (pid > 0 && pid != MY_PID) {
5897                Process.killProcessQuiet(pid);
5898                //TODO: Process.killProcessGroup(app.info.uid, pid);
5899            } else {
5900                try {
5901                    thread.scheduleExit();
5902                } catch (Exception e) {
5903                    // Ignore exceptions.
5904                }
5905            }
5906            return false;
5907        }
5908
5909        // If this application record is still attached to a previous
5910        // process, clean it up now.
5911        if (app.thread != null) {
5912            handleAppDiedLocked(app, true, true);
5913        }
5914
5915        // Tell the process all about itself.
5916
5917        if (localLOGV) Slog.v(
5918                TAG, "Binding process pid " + pid + " to record " + app);
5919
5920        final String processName = app.processName;
5921        try {
5922            AppDeathRecipient adr = new AppDeathRecipient(
5923                    app, pid, thread);
5924            thread.asBinder().linkToDeath(adr, 0);
5925            app.deathRecipient = adr;
5926        } catch (RemoteException e) {
5927            app.resetPackageList(mProcessStats);
5928            startProcessLocked(app, "link fail", processName);
5929            return false;
5930        }
5931
5932        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5933
5934        app.makeActive(thread, mProcessStats);
5935        app.curAdj = app.setAdj = -100;
5936        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5937        app.forcingToForeground = null;
5938        updateProcessForegroundLocked(app, false, false);
5939        app.hasShownUi = false;
5940        app.debugging = false;
5941        app.cached = false;
5942
5943        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5944
5945        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5946        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5947
5948        if (!normalMode) {
5949            Slog.i(TAG, "Launching preboot mode app: " + app);
5950        }
5951
5952        if (localLOGV) Slog.v(
5953            TAG, "New app record " + app
5954            + " thread=" + thread.asBinder() + " pid=" + pid);
5955        try {
5956            int testMode = IApplicationThread.DEBUG_OFF;
5957            if (mDebugApp != null && mDebugApp.equals(processName)) {
5958                testMode = mWaitForDebugger
5959                    ? IApplicationThread.DEBUG_WAIT
5960                    : IApplicationThread.DEBUG_ON;
5961                app.debugging = true;
5962                if (mDebugTransient) {
5963                    mDebugApp = mOrigDebugApp;
5964                    mWaitForDebugger = mOrigWaitForDebugger;
5965                }
5966            }
5967            String profileFile = app.instrumentationProfileFile;
5968            ParcelFileDescriptor profileFd = null;
5969            int samplingInterval = 0;
5970            boolean profileAutoStop = false;
5971            if (mProfileApp != null && mProfileApp.equals(processName)) {
5972                mProfileProc = app;
5973                profileFile = mProfileFile;
5974                profileFd = mProfileFd;
5975                samplingInterval = mSamplingInterval;
5976                profileAutoStop = mAutoStopProfiler;
5977            }
5978            boolean enableOpenGlTrace = false;
5979            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5980                enableOpenGlTrace = true;
5981                mOpenGlTraceApp = null;
5982            }
5983
5984            // If the app is being launched for restore or full backup, set it up specially
5985            boolean isRestrictedBackupMode = false;
5986            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5987                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5988                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5989                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5990            }
5991
5992            ensurePackageDexOpt(app.instrumentationInfo != null
5993                    ? app.instrumentationInfo.packageName
5994                    : app.info.packageName);
5995            if (app.instrumentationClass != null) {
5996                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5997            }
5998            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5999                    + processName + " with config " + mConfiguration);
6000            ApplicationInfo appInfo = app.instrumentationInfo != null
6001                    ? app.instrumentationInfo : app.info;
6002            app.compat = compatibilityInfoForPackageLocked(appInfo);
6003            if (profileFd != null) {
6004                profileFd = profileFd.dup();
6005            }
6006            ProfilerInfo profilerInfo = profileFile == null ? null
6007                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6008            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6009                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6010                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6011                    isRestrictedBackupMode || !normalMode, app.persistent,
6012                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6013                    mCoreSettingsObserver.getCoreSettingsLocked());
6014            updateLruProcessLocked(app, false, null);
6015            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6016        } catch (Exception e) {
6017            // todo: Yikes!  What should we do?  For now we will try to
6018            // start another process, but that could easily get us in
6019            // an infinite loop of restarting processes...
6020            Slog.w(TAG, "Exception thrown during bind!", e);
6021
6022            app.resetPackageList(mProcessStats);
6023            app.unlinkDeathRecipient();
6024            startProcessLocked(app, "bind fail", processName);
6025            return false;
6026        }
6027
6028        // Remove this record from the list of starting applications.
6029        mPersistentStartingProcesses.remove(app);
6030        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6031                "Attach application locked removing on hold: " + app);
6032        mProcessesOnHold.remove(app);
6033
6034        boolean badApp = false;
6035        boolean didSomething = false;
6036
6037        // See if the top visible activity is waiting to run in this process...
6038        if (normalMode) {
6039            try {
6040                if (mStackSupervisor.attachApplicationLocked(app)) {
6041                    didSomething = true;
6042                }
6043            } catch (Exception e) {
6044                badApp = true;
6045            }
6046        }
6047
6048        // Find any services that should be running in this process...
6049        if (!badApp) {
6050            try {
6051                didSomething |= mServices.attachApplicationLocked(app, processName);
6052            } catch (Exception e) {
6053                badApp = true;
6054            }
6055        }
6056
6057        // Check if a next-broadcast receiver is in this process...
6058        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6059            try {
6060                didSomething |= sendPendingBroadcastsLocked(app);
6061            } catch (Exception e) {
6062                // If the app died trying to launch the receiver we declare it 'bad'
6063                badApp = true;
6064            }
6065        }
6066
6067        // Check whether the next backup agent is in this process...
6068        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6069            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6070            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6071            try {
6072                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6073                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6074                        mBackupTarget.backupMode);
6075            } catch (Exception e) {
6076                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6077                e.printStackTrace();
6078            }
6079        }
6080
6081        if (badApp) {
6082            // todo: Also need to kill application to deal with all
6083            // kinds of exceptions.
6084            handleAppDiedLocked(app, false, true);
6085            return false;
6086        }
6087
6088        if (!didSomething) {
6089            updateOomAdjLocked();
6090        }
6091
6092        return true;
6093    }
6094
6095    @Override
6096    public final void attachApplication(IApplicationThread thread) {
6097        synchronized (this) {
6098            int callingPid = Binder.getCallingPid();
6099            final long origId = Binder.clearCallingIdentity();
6100            attachApplicationLocked(thread, callingPid);
6101            Binder.restoreCallingIdentity(origId);
6102        }
6103    }
6104
6105    @Override
6106    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6107        final long origId = Binder.clearCallingIdentity();
6108        synchronized (this) {
6109            ActivityStack stack = ActivityRecord.getStackLocked(token);
6110            if (stack != null) {
6111                ActivityRecord r =
6112                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6113                if (stopProfiling) {
6114                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6115                        try {
6116                            mProfileFd.close();
6117                        } catch (IOException e) {
6118                        }
6119                        clearProfilerLocked();
6120                    }
6121                }
6122            }
6123        }
6124        Binder.restoreCallingIdentity(origId);
6125    }
6126
6127    void postEnableScreenAfterBootLocked() {
6128        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6129    }
6130
6131    void enableScreenAfterBoot() {
6132        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6133                SystemClock.uptimeMillis());
6134        mWindowManager.enableScreenAfterBoot();
6135
6136        synchronized (this) {
6137            updateEventDispatchingLocked();
6138        }
6139    }
6140
6141    @Override
6142    public void showBootMessage(final CharSequence msg, final boolean always) {
6143        enforceNotIsolatedCaller("showBootMessage");
6144        mWindowManager.showBootMessage(msg, always);
6145    }
6146
6147    @Override
6148    public void keyguardWaitingForActivityDrawn() {
6149        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6150        final long token = Binder.clearCallingIdentity();
6151        try {
6152            synchronized (this) {
6153                if (DEBUG_LOCKSCREEN) logLockScreen("");
6154                mWindowManager.keyguardWaitingForActivityDrawn();
6155            }
6156        } finally {
6157            Binder.restoreCallingIdentity(token);
6158        }
6159    }
6160
6161    final void finishBooting() {
6162        // Register receivers to handle package update events
6163        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6164
6165        // Let system services know.
6166        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6167
6168        synchronized (this) {
6169            // Ensure that any processes we had put on hold are now started
6170            // up.
6171            final int NP = mProcessesOnHold.size();
6172            if (NP > 0) {
6173                ArrayList<ProcessRecord> procs =
6174                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6175                for (int ip=0; ip<NP; ip++) {
6176                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6177                            + procs.get(ip));
6178                    startProcessLocked(procs.get(ip), "on-hold", null);
6179                }
6180            }
6181
6182            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6183                // Start looking for apps that are abusing wake locks.
6184                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6185                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6186                // Tell anyone interested that we are done booting!
6187                SystemProperties.set("sys.boot_completed", "1");
6188                SystemProperties.set("dev.bootcomplete", "1");
6189                for (int i=0; i<mStartedUsers.size(); i++) {
6190                    UserStartedState uss = mStartedUsers.valueAt(i);
6191                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6192                        uss.mState = UserStartedState.STATE_RUNNING;
6193                        final int userId = mStartedUsers.keyAt(i);
6194                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6195                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6196                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6197                        broadcastIntentLocked(null, null, intent, null,
6198                                new IIntentReceiver.Stub() {
6199                                    @Override
6200                                    public void performReceive(Intent intent, int resultCode,
6201                                            String data, Bundle extras, boolean ordered,
6202                                            boolean sticky, int sendingUser) {
6203                                        synchronized (ActivityManagerService.this) {
6204                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6205                                                    true, false);
6206                                        }
6207                                    }
6208                                },
6209                                0, null, null,
6210                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6211                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6212                                userId);
6213                    }
6214                }
6215                scheduleStartProfilesLocked();
6216            }
6217        }
6218    }
6219
6220    final void ensureBootCompleted() {
6221        boolean booting;
6222        boolean enableScreen;
6223        synchronized (this) {
6224            booting = mBooting;
6225            mBooting = false;
6226            enableScreen = !mBooted;
6227            mBooted = true;
6228        }
6229
6230        if (booting) {
6231            finishBooting();
6232        }
6233
6234        if (enableScreen) {
6235            enableScreenAfterBoot();
6236        }
6237    }
6238
6239    @Override
6240    public final void activityResumed(IBinder token) {
6241        final long origId = Binder.clearCallingIdentity();
6242        synchronized(this) {
6243            ActivityStack stack = ActivityRecord.getStackLocked(token);
6244            if (stack != null) {
6245                ActivityRecord.activityResumedLocked(token);
6246            }
6247        }
6248        Binder.restoreCallingIdentity(origId);
6249    }
6250
6251    @Override
6252    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
6253        final long origId = Binder.clearCallingIdentity();
6254        synchronized(this) {
6255            ActivityStack stack = ActivityRecord.getStackLocked(token);
6256            if (stack != null) {
6257                stack.activityPausedLocked(token, false, persistentState);
6258            }
6259        }
6260        Binder.restoreCallingIdentity(origId);
6261    }
6262
6263    @Override
6264    public final void activityStopped(IBinder token, Bundle icicle,
6265            PersistableBundle persistentState, CharSequence description) {
6266        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6267
6268        // Refuse possible leaked file descriptors
6269        if (icicle != null && icicle.hasFileDescriptors()) {
6270            throw new IllegalArgumentException("File descriptors passed in Bundle");
6271        }
6272
6273        final long origId = Binder.clearCallingIdentity();
6274
6275        synchronized (this) {
6276            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6277            if (r != null) {
6278                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6279            }
6280        }
6281
6282        trimApplications();
6283
6284        Binder.restoreCallingIdentity(origId);
6285    }
6286
6287    @Override
6288    public final void activityDestroyed(IBinder token) {
6289        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6290        synchronized (this) {
6291            ActivityStack stack = ActivityRecord.getStackLocked(token);
6292            if (stack != null) {
6293                stack.activityDestroyedLocked(token);
6294            }
6295        }
6296    }
6297
6298    @Override
6299    public final void backgroundResourcesReleased(IBinder token) {
6300        final long origId = Binder.clearCallingIdentity();
6301        try {
6302            synchronized (this) {
6303                ActivityStack stack = ActivityRecord.getStackLocked(token);
6304                if (stack != null) {
6305                    stack.backgroundResourcesReleased(token);
6306                }
6307            }
6308        } finally {
6309            Binder.restoreCallingIdentity(origId);
6310        }
6311    }
6312
6313    @Override
6314    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6315        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6316    }
6317
6318    @Override
6319    public final void notifyEnterAnimationComplete(IBinder token) {
6320        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6321    }
6322
6323    @Override
6324    public String getCallingPackage(IBinder token) {
6325        synchronized (this) {
6326            ActivityRecord r = getCallingRecordLocked(token);
6327            return r != null ? r.info.packageName : null;
6328        }
6329    }
6330
6331    @Override
6332    public ComponentName getCallingActivity(IBinder token) {
6333        synchronized (this) {
6334            ActivityRecord r = getCallingRecordLocked(token);
6335            return r != null ? r.intent.getComponent() : null;
6336        }
6337    }
6338
6339    private ActivityRecord getCallingRecordLocked(IBinder token) {
6340        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6341        if (r == null) {
6342            return null;
6343        }
6344        return r.resultTo;
6345    }
6346
6347    @Override
6348    public ComponentName getActivityClassForToken(IBinder token) {
6349        synchronized(this) {
6350            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6351            if (r == null) {
6352                return null;
6353            }
6354            return r.intent.getComponent();
6355        }
6356    }
6357
6358    @Override
6359    public String getPackageForToken(IBinder token) {
6360        synchronized(this) {
6361            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6362            if (r == null) {
6363                return null;
6364            }
6365            return r.packageName;
6366        }
6367    }
6368
6369    @Override
6370    public IIntentSender getIntentSender(int type,
6371            String packageName, IBinder token, String resultWho,
6372            int requestCode, Intent[] intents, String[] resolvedTypes,
6373            int flags, Bundle options, int userId) {
6374        enforceNotIsolatedCaller("getIntentSender");
6375        // Refuse possible leaked file descriptors
6376        if (intents != null) {
6377            if (intents.length < 1) {
6378                throw new IllegalArgumentException("Intents array length must be >= 1");
6379            }
6380            for (int i=0; i<intents.length; i++) {
6381                Intent intent = intents[i];
6382                if (intent != null) {
6383                    if (intent.hasFileDescriptors()) {
6384                        throw new IllegalArgumentException("File descriptors passed in Intent");
6385                    }
6386                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6387                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6388                        throw new IllegalArgumentException(
6389                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6390                    }
6391                    intents[i] = new Intent(intent);
6392                }
6393            }
6394            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6395                throw new IllegalArgumentException(
6396                        "Intent array length does not match resolvedTypes length");
6397            }
6398        }
6399        if (options != null) {
6400            if (options.hasFileDescriptors()) {
6401                throw new IllegalArgumentException("File descriptors passed in options");
6402            }
6403        }
6404
6405        synchronized(this) {
6406            int callingUid = Binder.getCallingUid();
6407            int origUserId = userId;
6408            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6409                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6410                    ALLOW_NON_FULL, "getIntentSender", null);
6411            if (origUserId == UserHandle.USER_CURRENT) {
6412                // We don't want to evaluate this until the pending intent is
6413                // actually executed.  However, we do want to always do the
6414                // security checking for it above.
6415                userId = UserHandle.USER_CURRENT;
6416            }
6417            try {
6418                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6419                    int uid = AppGlobals.getPackageManager()
6420                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6421                    if (!UserHandle.isSameApp(callingUid, uid)) {
6422                        String msg = "Permission Denial: getIntentSender() from pid="
6423                            + Binder.getCallingPid()
6424                            + ", uid=" + Binder.getCallingUid()
6425                            + ", (need uid=" + uid + ")"
6426                            + " is not allowed to send as package " + packageName;
6427                        Slog.w(TAG, msg);
6428                        throw new SecurityException(msg);
6429                    }
6430                }
6431
6432                return getIntentSenderLocked(type, packageName, callingUid, userId,
6433                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6434
6435            } catch (RemoteException e) {
6436                throw new SecurityException(e);
6437            }
6438        }
6439    }
6440
6441    IIntentSender getIntentSenderLocked(int type, String packageName,
6442            int callingUid, int userId, IBinder token, String resultWho,
6443            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6444            Bundle options) {
6445        if (DEBUG_MU)
6446            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6447        ActivityRecord activity = null;
6448        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6449            activity = ActivityRecord.isInStackLocked(token);
6450            if (activity == null) {
6451                return null;
6452            }
6453            if (activity.finishing) {
6454                return null;
6455            }
6456        }
6457
6458        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6459        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6460        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6461        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6462                |PendingIntent.FLAG_UPDATE_CURRENT);
6463
6464        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6465                type, packageName, activity, resultWho,
6466                requestCode, intents, resolvedTypes, flags, options, userId);
6467        WeakReference<PendingIntentRecord> ref;
6468        ref = mIntentSenderRecords.get(key);
6469        PendingIntentRecord rec = ref != null ? ref.get() : null;
6470        if (rec != null) {
6471            if (!cancelCurrent) {
6472                if (updateCurrent) {
6473                    if (rec.key.requestIntent != null) {
6474                        rec.key.requestIntent.replaceExtras(intents != null ?
6475                                intents[intents.length - 1] : null);
6476                    }
6477                    if (intents != null) {
6478                        intents[intents.length-1] = rec.key.requestIntent;
6479                        rec.key.allIntents = intents;
6480                        rec.key.allResolvedTypes = resolvedTypes;
6481                    } else {
6482                        rec.key.allIntents = null;
6483                        rec.key.allResolvedTypes = null;
6484                    }
6485                }
6486                return rec;
6487            }
6488            rec.canceled = true;
6489            mIntentSenderRecords.remove(key);
6490        }
6491        if (noCreate) {
6492            return rec;
6493        }
6494        rec = new PendingIntentRecord(this, key, callingUid);
6495        mIntentSenderRecords.put(key, rec.ref);
6496        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6497            if (activity.pendingResults == null) {
6498                activity.pendingResults
6499                        = new HashSet<WeakReference<PendingIntentRecord>>();
6500            }
6501            activity.pendingResults.add(rec.ref);
6502        }
6503        return rec;
6504    }
6505
6506    @Override
6507    public void cancelIntentSender(IIntentSender sender) {
6508        if (!(sender instanceof PendingIntentRecord)) {
6509            return;
6510        }
6511        synchronized(this) {
6512            PendingIntentRecord rec = (PendingIntentRecord)sender;
6513            try {
6514                int uid = AppGlobals.getPackageManager()
6515                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6516                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6517                    String msg = "Permission Denial: cancelIntentSender() from pid="
6518                        + Binder.getCallingPid()
6519                        + ", uid=" + Binder.getCallingUid()
6520                        + " is not allowed to cancel packges "
6521                        + rec.key.packageName;
6522                    Slog.w(TAG, msg);
6523                    throw new SecurityException(msg);
6524                }
6525            } catch (RemoteException e) {
6526                throw new SecurityException(e);
6527            }
6528            cancelIntentSenderLocked(rec, true);
6529        }
6530    }
6531
6532    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6533        rec.canceled = true;
6534        mIntentSenderRecords.remove(rec.key);
6535        if (cleanActivity && rec.key.activity != null) {
6536            rec.key.activity.pendingResults.remove(rec.ref);
6537        }
6538    }
6539
6540    @Override
6541    public String getPackageForIntentSender(IIntentSender pendingResult) {
6542        if (!(pendingResult instanceof PendingIntentRecord)) {
6543            return null;
6544        }
6545        try {
6546            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6547            return res.key.packageName;
6548        } catch (ClassCastException e) {
6549        }
6550        return null;
6551    }
6552
6553    @Override
6554    public int getUidForIntentSender(IIntentSender sender) {
6555        if (sender instanceof PendingIntentRecord) {
6556            try {
6557                PendingIntentRecord res = (PendingIntentRecord)sender;
6558                return res.uid;
6559            } catch (ClassCastException e) {
6560            }
6561        }
6562        return -1;
6563    }
6564
6565    @Override
6566    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6567        if (!(pendingResult instanceof PendingIntentRecord)) {
6568            return false;
6569        }
6570        try {
6571            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6572            if (res.key.allIntents == null) {
6573                return false;
6574            }
6575            for (int i=0; i<res.key.allIntents.length; i++) {
6576                Intent intent = res.key.allIntents[i];
6577                if (intent.getPackage() != null && intent.getComponent() != null) {
6578                    return false;
6579                }
6580            }
6581            return true;
6582        } catch (ClassCastException e) {
6583        }
6584        return false;
6585    }
6586
6587    @Override
6588    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6589        if (!(pendingResult instanceof PendingIntentRecord)) {
6590            return false;
6591        }
6592        try {
6593            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6594            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6595                return true;
6596            }
6597            return false;
6598        } catch (ClassCastException e) {
6599        }
6600        return false;
6601    }
6602
6603    @Override
6604    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6605        if (!(pendingResult instanceof PendingIntentRecord)) {
6606            return null;
6607        }
6608        try {
6609            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6610            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6611        } catch (ClassCastException e) {
6612        }
6613        return null;
6614    }
6615
6616    @Override
6617    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6618        if (!(pendingResult instanceof PendingIntentRecord)) {
6619            return null;
6620        }
6621        try {
6622            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6623            Intent intent = res.key.requestIntent;
6624            if (intent != null) {
6625                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6626                        || res.lastTagPrefix.equals(prefix))) {
6627                    return res.lastTag;
6628                }
6629                res.lastTagPrefix = prefix;
6630                StringBuilder sb = new StringBuilder(128);
6631                if (prefix != null) {
6632                    sb.append(prefix);
6633                }
6634                if (intent.getAction() != null) {
6635                    sb.append(intent.getAction());
6636                } else if (intent.getComponent() != null) {
6637                    intent.getComponent().appendShortString(sb);
6638                } else {
6639                    sb.append("?");
6640                }
6641                return res.lastTag = sb.toString();
6642            }
6643        } catch (ClassCastException e) {
6644        }
6645        return null;
6646    }
6647
6648    @Override
6649    public void setProcessLimit(int max) {
6650        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6651                "setProcessLimit()");
6652        synchronized (this) {
6653            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6654            mProcessLimitOverride = max;
6655        }
6656        trimApplications();
6657    }
6658
6659    @Override
6660    public int getProcessLimit() {
6661        synchronized (this) {
6662            return mProcessLimitOverride;
6663        }
6664    }
6665
6666    void foregroundTokenDied(ForegroundToken token) {
6667        synchronized (ActivityManagerService.this) {
6668            synchronized (mPidsSelfLocked) {
6669                ForegroundToken cur
6670                    = mForegroundProcesses.get(token.pid);
6671                if (cur != token) {
6672                    return;
6673                }
6674                mForegroundProcesses.remove(token.pid);
6675                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6676                if (pr == null) {
6677                    return;
6678                }
6679                pr.forcingToForeground = null;
6680                updateProcessForegroundLocked(pr, false, false);
6681            }
6682            updateOomAdjLocked();
6683        }
6684    }
6685
6686    @Override
6687    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6688        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6689                "setProcessForeground()");
6690        synchronized(this) {
6691            boolean changed = false;
6692
6693            synchronized (mPidsSelfLocked) {
6694                ProcessRecord pr = mPidsSelfLocked.get(pid);
6695                if (pr == null && isForeground) {
6696                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6697                    return;
6698                }
6699                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6700                if (oldToken != null) {
6701                    oldToken.token.unlinkToDeath(oldToken, 0);
6702                    mForegroundProcesses.remove(pid);
6703                    if (pr != null) {
6704                        pr.forcingToForeground = null;
6705                    }
6706                    changed = true;
6707                }
6708                if (isForeground && token != null) {
6709                    ForegroundToken newToken = new ForegroundToken() {
6710                        @Override
6711                        public void binderDied() {
6712                            foregroundTokenDied(this);
6713                        }
6714                    };
6715                    newToken.pid = pid;
6716                    newToken.token = token;
6717                    try {
6718                        token.linkToDeath(newToken, 0);
6719                        mForegroundProcesses.put(pid, newToken);
6720                        pr.forcingToForeground = token;
6721                        changed = true;
6722                    } catch (RemoteException e) {
6723                        // If the process died while doing this, we will later
6724                        // do the cleanup with the process death link.
6725                    }
6726                }
6727            }
6728
6729            if (changed) {
6730                updateOomAdjLocked();
6731            }
6732        }
6733    }
6734
6735    // =========================================================
6736    // PERMISSIONS
6737    // =========================================================
6738
6739    static class PermissionController extends IPermissionController.Stub {
6740        ActivityManagerService mActivityManagerService;
6741        PermissionController(ActivityManagerService activityManagerService) {
6742            mActivityManagerService = activityManagerService;
6743        }
6744
6745        @Override
6746        public boolean checkPermission(String permission, int pid, int uid) {
6747            return mActivityManagerService.checkPermission(permission, pid,
6748                    uid) == PackageManager.PERMISSION_GRANTED;
6749        }
6750    }
6751
6752    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6753        @Override
6754        public int checkComponentPermission(String permission, int pid, int uid,
6755                int owningUid, boolean exported) {
6756            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6757                    owningUid, exported);
6758        }
6759
6760        @Override
6761        public Object getAMSLock() {
6762            return ActivityManagerService.this;
6763        }
6764    }
6765
6766    /**
6767     * This can be called with or without the global lock held.
6768     */
6769    int checkComponentPermission(String permission, int pid, int uid,
6770            int owningUid, boolean exported) {
6771        // We might be performing an operation on behalf of an indirect binder
6772        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6773        // client identity accordingly before proceeding.
6774        Identity tlsIdentity = sCallerIdentity.get();
6775        if (tlsIdentity != null) {
6776            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6777                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6778            uid = tlsIdentity.uid;
6779            pid = tlsIdentity.pid;
6780        }
6781
6782        if (pid == MY_PID) {
6783            return PackageManager.PERMISSION_GRANTED;
6784        }
6785
6786        return ActivityManager.checkComponentPermission(permission, uid,
6787                owningUid, exported);
6788    }
6789
6790    /**
6791     * As the only public entry point for permissions checking, this method
6792     * can enforce the semantic that requesting a check on a null global
6793     * permission is automatically denied.  (Internally a null permission
6794     * string is used when calling {@link #checkComponentPermission} in cases
6795     * when only uid-based security is needed.)
6796     *
6797     * This can be called with or without the global lock held.
6798     */
6799    @Override
6800    public int checkPermission(String permission, int pid, int uid) {
6801        if (permission == null) {
6802            return PackageManager.PERMISSION_DENIED;
6803        }
6804        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6805    }
6806
6807    /**
6808     * Binder IPC calls go through the public entry point.
6809     * This can be called with or without the global lock held.
6810     */
6811    int checkCallingPermission(String permission) {
6812        return checkPermission(permission,
6813                Binder.getCallingPid(),
6814                UserHandle.getAppId(Binder.getCallingUid()));
6815    }
6816
6817    /**
6818     * This can be called with or without the global lock held.
6819     */
6820    void enforceCallingPermission(String permission, String func) {
6821        if (checkCallingPermission(permission)
6822                == PackageManager.PERMISSION_GRANTED) {
6823            return;
6824        }
6825
6826        String msg = "Permission Denial: " + func + " from pid="
6827                + Binder.getCallingPid()
6828                + ", uid=" + Binder.getCallingUid()
6829                + " requires " + permission;
6830        Slog.w(TAG, msg);
6831        throw new SecurityException(msg);
6832    }
6833
6834    /**
6835     * Determine if UID is holding permissions required to access {@link Uri} in
6836     * the given {@link ProviderInfo}. Final permission checking is always done
6837     * in {@link ContentProvider}.
6838     */
6839    private final boolean checkHoldingPermissionsLocked(
6840            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6841        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6842                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6843        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6844            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6845                    != PERMISSION_GRANTED) {
6846                return false;
6847            }
6848        }
6849        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6850    }
6851
6852    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6853            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6854        if (pi.applicationInfo.uid == uid) {
6855            return true;
6856        } else if (!pi.exported) {
6857            return false;
6858        }
6859
6860        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6861        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6862        try {
6863            // check if target holds top-level <provider> permissions
6864            if (!readMet && pi.readPermission != null && considerUidPermissions
6865                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6866                readMet = true;
6867            }
6868            if (!writeMet && pi.writePermission != null && considerUidPermissions
6869                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6870                writeMet = true;
6871            }
6872
6873            // track if unprotected read/write is allowed; any denied
6874            // <path-permission> below removes this ability
6875            boolean allowDefaultRead = pi.readPermission == null;
6876            boolean allowDefaultWrite = pi.writePermission == null;
6877
6878            // check if target holds any <path-permission> that match uri
6879            final PathPermission[] pps = pi.pathPermissions;
6880            if (pps != null) {
6881                final String path = grantUri.uri.getPath();
6882                int i = pps.length;
6883                while (i > 0 && (!readMet || !writeMet)) {
6884                    i--;
6885                    PathPermission pp = pps[i];
6886                    if (pp.match(path)) {
6887                        if (!readMet) {
6888                            final String pprperm = pp.getReadPermission();
6889                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6890                                    + pprperm + " for " + pp.getPath()
6891                                    + ": match=" + pp.match(path)
6892                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6893                            if (pprperm != null) {
6894                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6895                                        == PERMISSION_GRANTED) {
6896                                    readMet = true;
6897                                } else {
6898                                    allowDefaultRead = false;
6899                                }
6900                            }
6901                        }
6902                        if (!writeMet) {
6903                            final String ppwperm = pp.getWritePermission();
6904                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6905                                    + ppwperm + " for " + pp.getPath()
6906                                    + ": match=" + pp.match(path)
6907                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6908                            if (ppwperm != null) {
6909                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6910                                        == PERMISSION_GRANTED) {
6911                                    writeMet = true;
6912                                } else {
6913                                    allowDefaultWrite = false;
6914                                }
6915                            }
6916                        }
6917                    }
6918                }
6919            }
6920
6921            // grant unprotected <provider> read/write, if not blocked by
6922            // <path-permission> above
6923            if (allowDefaultRead) readMet = true;
6924            if (allowDefaultWrite) writeMet = true;
6925
6926        } catch (RemoteException e) {
6927            return false;
6928        }
6929
6930        return readMet && writeMet;
6931    }
6932
6933    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6934        ProviderInfo pi = null;
6935        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6936        if (cpr != null) {
6937            pi = cpr.info;
6938        } else {
6939            try {
6940                pi = AppGlobals.getPackageManager().resolveContentProvider(
6941                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6942            } catch (RemoteException ex) {
6943            }
6944        }
6945        return pi;
6946    }
6947
6948    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6949        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6950        if (targetUris != null) {
6951            return targetUris.get(grantUri);
6952        }
6953        return null;
6954    }
6955
6956    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6957            String targetPkg, int targetUid, GrantUri grantUri) {
6958        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6959        if (targetUris == null) {
6960            targetUris = Maps.newArrayMap();
6961            mGrantedUriPermissions.put(targetUid, targetUris);
6962        }
6963
6964        UriPermission perm = targetUris.get(grantUri);
6965        if (perm == null) {
6966            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6967            targetUris.put(grantUri, perm);
6968        }
6969
6970        return perm;
6971    }
6972
6973    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6974            final int modeFlags) {
6975        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6976        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6977                : UriPermission.STRENGTH_OWNED;
6978
6979        // Root gets to do everything.
6980        if (uid == 0) {
6981            return true;
6982        }
6983
6984        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6985        if (perms == null) return false;
6986
6987        // First look for exact match
6988        final UriPermission exactPerm = perms.get(grantUri);
6989        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6990            return true;
6991        }
6992
6993        // No exact match, look for prefixes
6994        final int N = perms.size();
6995        for (int i = 0; i < N; i++) {
6996            final UriPermission perm = perms.valueAt(i);
6997            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6998                    && perm.getStrength(modeFlags) >= minStrength) {
6999                return true;
7000            }
7001        }
7002
7003        return false;
7004    }
7005
7006    /**
7007     * @param uri This uri must NOT contain an embedded userId.
7008     * @param userId The userId in which the uri is to be resolved.
7009     */
7010    @Override
7011    public int checkUriPermission(Uri uri, int pid, int uid,
7012            final int modeFlags, int userId) {
7013        enforceNotIsolatedCaller("checkUriPermission");
7014
7015        // Another redirected-binder-call permissions check as in
7016        // {@link checkComponentPermission}.
7017        Identity tlsIdentity = sCallerIdentity.get();
7018        if (tlsIdentity != null) {
7019            uid = tlsIdentity.uid;
7020            pid = tlsIdentity.pid;
7021        }
7022
7023        // Our own process gets to do everything.
7024        if (pid == MY_PID) {
7025            return PackageManager.PERMISSION_GRANTED;
7026        }
7027        synchronized (this) {
7028            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7029                    ? PackageManager.PERMISSION_GRANTED
7030                    : PackageManager.PERMISSION_DENIED;
7031        }
7032    }
7033
7034    /**
7035     * Check if the targetPkg can be granted permission to access uri by
7036     * the callingUid using the given modeFlags.  Throws a security exception
7037     * if callingUid is not allowed to do this.  Returns the uid of the target
7038     * if the URI permission grant should be performed; returns -1 if it is not
7039     * needed (for example targetPkg already has permission to access the URI).
7040     * If you already know the uid of the target, you can supply it in
7041     * lastTargetUid else set that to -1.
7042     */
7043    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7044            final int modeFlags, int lastTargetUid) {
7045        if (!Intent.isAccessUriMode(modeFlags)) {
7046            return -1;
7047        }
7048
7049        if (targetPkg != null) {
7050            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7051                    "Checking grant " + targetPkg + " permission to " + grantUri);
7052        }
7053
7054        final IPackageManager pm = AppGlobals.getPackageManager();
7055
7056        // If this is not a content: uri, we can't do anything with it.
7057        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7058            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7059                    "Can't grant URI permission for non-content URI: " + grantUri);
7060            return -1;
7061        }
7062
7063        final String authority = grantUri.uri.getAuthority();
7064        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7065        if (pi == null) {
7066            Slog.w(TAG, "No content provider found for permission check: " +
7067                    grantUri.uri.toSafeString());
7068            return -1;
7069        }
7070
7071        int targetUid = lastTargetUid;
7072        if (targetUid < 0 && targetPkg != null) {
7073            try {
7074                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7075                if (targetUid < 0) {
7076                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7077                            "Can't grant URI permission no uid for: " + targetPkg);
7078                    return -1;
7079                }
7080            } catch (RemoteException ex) {
7081                return -1;
7082            }
7083        }
7084
7085        if (targetUid >= 0) {
7086            // First...  does the target actually need this permission?
7087            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7088                // No need to grant the target this permission.
7089                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7090                        "Target " + targetPkg + " already has full permission to " + grantUri);
7091                return -1;
7092            }
7093        } else {
7094            // First...  there is no target package, so can anyone access it?
7095            boolean allowed = pi.exported;
7096            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7097                if (pi.readPermission != null) {
7098                    allowed = false;
7099                }
7100            }
7101            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7102                if (pi.writePermission != null) {
7103                    allowed = false;
7104                }
7105            }
7106            if (allowed) {
7107                return -1;
7108            }
7109        }
7110
7111        /* There is a special cross user grant if:
7112         * - The target is on another user.
7113         * - Apps on the current user can access the uri without any uid permissions.
7114         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7115         * grant uri permissions.
7116         */
7117        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7118                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7119                modeFlags, false /*without considering the uid permissions*/);
7120
7121        // Second...  is the provider allowing granting of URI permissions?
7122        if (!specialCrossUserGrant) {
7123            if (!pi.grantUriPermissions) {
7124                throw new SecurityException("Provider " + pi.packageName
7125                        + "/" + pi.name
7126                        + " does not allow granting of Uri permissions (uri "
7127                        + grantUri + ")");
7128            }
7129            if (pi.uriPermissionPatterns != null) {
7130                final int N = pi.uriPermissionPatterns.length;
7131                boolean allowed = false;
7132                for (int i=0; i<N; i++) {
7133                    if (pi.uriPermissionPatterns[i] != null
7134                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7135                        allowed = true;
7136                        break;
7137                    }
7138                }
7139                if (!allowed) {
7140                    throw new SecurityException("Provider " + pi.packageName
7141                            + "/" + pi.name
7142                            + " does not allow granting of permission to path of Uri "
7143                            + grantUri);
7144                }
7145            }
7146        }
7147
7148        // Third...  does the caller itself have permission to access
7149        // this uri?
7150        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7151            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7152                // Require they hold a strong enough Uri permission
7153                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7154                    throw new SecurityException("Uid " + callingUid
7155                            + " does not have permission to uri " + grantUri);
7156                }
7157            }
7158        }
7159        return targetUid;
7160    }
7161
7162    /**
7163     * @param uri This uri must NOT contain an embedded userId.
7164     * @param userId The userId in which the uri is to be resolved.
7165     */
7166    @Override
7167    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7168            final int modeFlags, int userId) {
7169        enforceNotIsolatedCaller("checkGrantUriPermission");
7170        synchronized(this) {
7171            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7172                    new GrantUri(userId, uri, false), modeFlags, -1);
7173        }
7174    }
7175
7176    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7177            final int modeFlags, UriPermissionOwner owner) {
7178        if (!Intent.isAccessUriMode(modeFlags)) {
7179            return;
7180        }
7181
7182        // So here we are: the caller has the assumed permission
7183        // to the uri, and the target doesn't.  Let's now give this to
7184        // the target.
7185
7186        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7187                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7188
7189        final String authority = grantUri.uri.getAuthority();
7190        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7191        if (pi == null) {
7192            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7193            return;
7194        }
7195
7196        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7197            grantUri.prefix = true;
7198        }
7199        final UriPermission perm = findOrCreateUriPermissionLocked(
7200                pi.packageName, targetPkg, targetUid, grantUri);
7201        perm.grantModes(modeFlags, owner);
7202    }
7203
7204    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7205            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7206        if (targetPkg == null) {
7207            throw new NullPointerException("targetPkg");
7208        }
7209        int targetUid;
7210        final IPackageManager pm = AppGlobals.getPackageManager();
7211        try {
7212            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7213        } catch (RemoteException ex) {
7214            return;
7215        }
7216
7217        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7218                targetUid);
7219        if (targetUid < 0) {
7220            return;
7221        }
7222
7223        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7224                owner);
7225    }
7226
7227    static class NeededUriGrants extends ArrayList<GrantUri> {
7228        final String targetPkg;
7229        final int targetUid;
7230        final int flags;
7231
7232        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7233            this.targetPkg = targetPkg;
7234            this.targetUid = targetUid;
7235            this.flags = flags;
7236        }
7237    }
7238
7239    /**
7240     * Like checkGrantUriPermissionLocked, but takes an Intent.
7241     */
7242    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7243            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7244        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7245                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7246                + " clip=" + (intent != null ? intent.getClipData() : null)
7247                + " from " + intent + "; flags=0x"
7248                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7249
7250        if (targetPkg == null) {
7251            throw new NullPointerException("targetPkg");
7252        }
7253
7254        if (intent == null) {
7255            return null;
7256        }
7257        Uri data = intent.getData();
7258        ClipData clip = intent.getClipData();
7259        if (data == null && clip == null) {
7260            return null;
7261        }
7262        // Default userId for uris in the intent (if they don't specify it themselves)
7263        int contentUserHint = intent.getContentUserHint();
7264        if (contentUserHint == UserHandle.USER_CURRENT) {
7265            contentUserHint = UserHandle.getUserId(callingUid);
7266        }
7267        final IPackageManager pm = AppGlobals.getPackageManager();
7268        int targetUid;
7269        if (needed != null) {
7270            targetUid = needed.targetUid;
7271        } else {
7272            try {
7273                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7274            } catch (RemoteException ex) {
7275                return null;
7276            }
7277            if (targetUid < 0) {
7278                if (DEBUG_URI_PERMISSION) {
7279                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7280                            + " on user " + targetUserId);
7281                }
7282                return null;
7283            }
7284        }
7285        if (data != null) {
7286            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7287            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7288                    targetUid);
7289            if (targetUid > 0) {
7290                if (needed == null) {
7291                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7292                }
7293                needed.add(grantUri);
7294            }
7295        }
7296        if (clip != null) {
7297            for (int i=0; i<clip.getItemCount(); i++) {
7298                Uri uri = clip.getItemAt(i).getUri();
7299                if (uri != null) {
7300                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7301                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7302                            targetUid);
7303                    if (targetUid > 0) {
7304                        if (needed == null) {
7305                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7306                        }
7307                        needed.add(grantUri);
7308                    }
7309                } else {
7310                    Intent clipIntent = clip.getItemAt(i).getIntent();
7311                    if (clipIntent != null) {
7312                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7313                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7314                        if (newNeeded != null) {
7315                            needed = newNeeded;
7316                        }
7317                    }
7318                }
7319            }
7320        }
7321
7322        return needed;
7323    }
7324
7325    /**
7326     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7327     */
7328    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7329            UriPermissionOwner owner) {
7330        if (needed != null) {
7331            for (int i=0; i<needed.size(); i++) {
7332                GrantUri grantUri = needed.get(i);
7333                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7334                        grantUri, needed.flags, owner);
7335            }
7336        }
7337    }
7338
7339    void grantUriPermissionFromIntentLocked(int callingUid,
7340            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7341        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7342                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7343        if (needed == null) {
7344            return;
7345        }
7346
7347        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7348    }
7349
7350    /**
7351     * @param uri This uri must NOT contain an embedded userId.
7352     * @param userId The userId in which the uri is to be resolved.
7353     */
7354    @Override
7355    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7356            final int modeFlags, int userId) {
7357        enforceNotIsolatedCaller("grantUriPermission");
7358        GrantUri grantUri = new GrantUri(userId, uri, false);
7359        synchronized(this) {
7360            final ProcessRecord r = getRecordForAppLocked(caller);
7361            if (r == null) {
7362                throw new SecurityException("Unable to find app for caller "
7363                        + caller
7364                        + " when granting permission to uri " + grantUri);
7365            }
7366            if (targetPkg == null) {
7367                throw new IllegalArgumentException("null target");
7368            }
7369            if (grantUri == null) {
7370                throw new IllegalArgumentException("null uri");
7371            }
7372
7373            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7374                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7375                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7376                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7377
7378            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7379                    UserHandle.getUserId(r.uid));
7380        }
7381    }
7382
7383    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7384        if (perm.modeFlags == 0) {
7385            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7386                    perm.targetUid);
7387            if (perms != null) {
7388                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7389                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7390
7391                perms.remove(perm.uri);
7392                if (perms.isEmpty()) {
7393                    mGrantedUriPermissions.remove(perm.targetUid);
7394                }
7395            }
7396        }
7397    }
7398
7399    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7400        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7401
7402        final IPackageManager pm = AppGlobals.getPackageManager();
7403        final String authority = grantUri.uri.getAuthority();
7404        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7405        if (pi == null) {
7406            Slog.w(TAG, "No content provider found for permission revoke: "
7407                    + grantUri.toSafeString());
7408            return;
7409        }
7410
7411        // Does the caller have this permission on the URI?
7412        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7413            // Right now, if you are not the original owner of the permission,
7414            // you are not allowed to revoke it.
7415            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7416                throw new SecurityException("Uid " + callingUid
7417                        + " does not have permission to uri " + grantUri);
7418            //}
7419        }
7420
7421        boolean persistChanged = false;
7422
7423        // Go through all of the permissions and remove any that match.
7424        int N = mGrantedUriPermissions.size();
7425        for (int i = 0; i < N; i++) {
7426            final int targetUid = mGrantedUriPermissions.keyAt(i);
7427            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7428
7429            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7430                final UriPermission perm = it.next();
7431                if (perm.uri.sourceUserId == grantUri.sourceUserId
7432                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7433                    if (DEBUG_URI_PERMISSION)
7434                        Slog.v(TAG,
7435                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7436                    persistChanged |= perm.revokeModes(
7437                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7438                    if (perm.modeFlags == 0) {
7439                        it.remove();
7440                    }
7441                }
7442            }
7443
7444            if (perms.isEmpty()) {
7445                mGrantedUriPermissions.remove(targetUid);
7446                N--;
7447                i--;
7448            }
7449        }
7450
7451        if (persistChanged) {
7452            schedulePersistUriGrants();
7453        }
7454    }
7455
7456    /**
7457     * @param uri This uri must NOT contain an embedded userId.
7458     * @param userId The userId in which the uri is to be resolved.
7459     */
7460    @Override
7461    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7462            int userId) {
7463        enforceNotIsolatedCaller("revokeUriPermission");
7464        synchronized(this) {
7465            final ProcessRecord r = getRecordForAppLocked(caller);
7466            if (r == null) {
7467                throw new SecurityException("Unable to find app for caller "
7468                        + caller
7469                        + " when revoking permission to uri " + uri);
7470            }
7471            if (uri == null) {
7472                Slog.w(TAG, "revokeUriPermission: null uri");
7473                return;
7474            }
7475
7476            if (!Intent.isAccessUriMode(modeFlags)) {
7477                return;
7478            }
7479
7480            final IPackageManager pm = AppGlobals.getPackageManager();
7481            final String authority = uri.getAuthority();
7482            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7483            if (pi == null) {
7484                Slog.w(TAG, "No content provider found for permission revoke: "
7485                        + uri.toSafeString());
7486                return;
7487            }
7488
7489            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7490        }
7491    }
7492
7493    /**
7494     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7495     * given package.
7496     *
7497     * @param packageName Package name to match, or {@code null} to apply to all
7498     *            packages.
7499     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7500     *            to all users.
7501     * @param persistable If persistable grants should be removed.
7502     */
7503    private void removeUriPermissionsForPackageLocked(
7504            String packageName, int userHandle, boolean persistable) {
7505        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7506            throw new IllegalArgumentException("Must narrow by either package or user");
7507        }
7508
7509        boolean persistChanged = false;
7510
7511        int N = mGrantedUriPermissions.size();
7512        for (int i = 0; i < N; i++) {
7513            final int targetUid = mGrantedUriPermissions.keyAt(i);
7514            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7515
7516            // Only inspect grants matching user
7517            if (userHandle == UserHandle.USER_ALL
7518                    || userHandle == UserHandle.getUserId(targetUid)) {
7519                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7520                    final UriPermission perm = it.next();
7521
7522                    // Only inspect grants matching package
7523                    if (packageName == null || perm.sourcePkg.equals(packageName)
7524                            || perm.targetPkg.equals(packageName)) {
7525                        persistChanged |= perm.revokeModes(
7526                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7527
7528                        // Only remove when no modes remain; any persisted grants
7529                        // will keep this alive.
7530                        if (perm.modeFlags == 0) {
7531                            it.remove();
7532                        }
7533                    }
7534                }
7535
7536                if (perms.isEmpty()) {
7537                    mGrantedUriPermissions.remove(targetUid);
7538                    N--;
7539                    i--;
7540                }
7541            }
7542        }
7543
7544        if (persistChanged) {
7545            schedulePersistUriGrants();
7546        }
7547    }
7548
7549    @Override
7550    public IBinder newUriPermissionOwner(String name) {
7551        enforceNotIsolatedCaller("newUriPermissionOwner");
7552        synchronized(this) {
7553            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7554            return owner.getExternalTokenLocked();
7555        }
7556    }
7557
7558    /**
7559     * @param uri This uri must NOT contain an embedded userId.
7560     * @param sourceUserId The userId in which the uri is to be resolved.
7561     * @param targetUserId The userId of the app that receives the grant.
7562     */
7563    @Override
7564    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7565            final int modeFlags, int sourceUserId, int targetUserId) {
7566        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7567                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7568        synchronized(this) {
7569            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7570            if (owner == null) {
7571                throw new IllegalArgumentException("Unknown owner: " + token);
7572            }
7573            if (fromUid != Binder.getCallingUid()) {
7574                if (Binder.getCallingUid() != Process.myUid()) {
7575                    // Only system code can grant URI permissions on behalf
7576                    // of other users.
7577                    throw new SecurityException("nice try");
7578                }
7579            }
7580            if (targetPkg == null) {
7581                throw new IllegalArgumentException("null target");
7582            }
7583            if (uri == null) {
7584                throw new IllegalArgumentException("null uri");
7585            }
7586
7587            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7588                    modeFlags, owner, targetUserId);
7589        }
7590    }
7591
7592    /**
7593     * @param uri This uri must NOT contain an embedded userId.
7594     * @param userId The userId in which the uri is to be resolved.
7595     */
7596    @Override
7597    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7598        synchronized(this) {
7599            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7600            if (owner == null) {
7601                throw new IllegalArgumentException("Unknown owner: " + token);
7602            }
7603
7604            if (uri == null) {
7605                owner.removeUriPermissionsLocked(mode);
7606            } else {
7607                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7608            }
7609        }
7610    }
7611
7612    private void schedulePersistUriGrants() {
7613        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7614            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7615                    10 * DateUtils.SECOND_IN_MILLIS);
7616        }
7617    }
7618
7619    private void writeGrantedUriPermissions() {
7620        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7621
7622        // Snapshot permissions so we can persist without lock
7623        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7624        synchronized (this) {
7625            final int size = mGrantedUriPermissions.size();
7626            for (int i = 0; i < size; i++) {
7627                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7628                for (UriPermission perm : perms.values()) {
7629                    if (perm.persistedModeFlags != 0) {
7630                        persist.add(perm.snapshot());
7631                    }
7632                }
7633            }
7634        }
7635
7636        FileOutputStream fos = null;
7637        try {
7638            fos = mGrantFile.startWrite();
7639
7640            XmlSerializer out = new FastXmlSerializer();
7641            out.setOutput(fos, "utf-8");
7642            out.startDocument(null, true);
7643            out.startTag(null, TAG_URI_GRANTS);
7644            for (UriPermission.Snapshot perm : persist) {
7645                out.startTag(null, TAG_URI_GRANT);
7646                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7647                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7648                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7649                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7650                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7651                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7652                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7653                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7654                out.endTag(null, TAG_URI_GRANT);
7655            }
7656            out.endTag(null, TAG_URI_GRANTS);
7657            out.endDocument();
7658
7659            mGrantFile.finishWrite(fos);
7660        } catch (IOException e) {
7661            if (fos != null) {
7662                mGrantFile.failWrite(fos);
7663            }
7664        }
7665    }
7666
7667    private void readGrantedUriPermissionsLocked() {
7668        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7669
7670        final long now = System.currentTimeMillis();
7671
7672        FileInputStream fis = null;
7673        try {
7674            fis = mGrantFile.openRead();
7675            final XmlPullParser in = Xml.newPullParser();
7676            in.setInput(fis, null);
7677
7678            int type;
7679            while ((type = in.next()) != END_DOCUMENT) {
7680                final String tag = in.getName();
7681                if (type == START_TAG) {
7682                    if (TAG_URI_GRANT.equals(tag)) {
7683                        final int sourceUserId;
7684                        final int targetUserId;
7685                        final int userHandle = readIntAttribute(in,
7686                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7687                        if (userHandle != UserHandle.USER_NULL) {
7688                            // For backwards compatibility.
7689                            sourceUserId = userHandle;
7690                            targetUserId = userHandle;
7691                        } else {
7692                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7693                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7694                        }
7695                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7696                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7697                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7698                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7699                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7700                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7701
7702                        // Sanity check that provider still belongs to source package
7703                        final ProviderInfo pi = getProviderInfoLocked(
7704                                uri.getAuthority(), sourceUserId);
7705                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7706                            int targetUid = -1;
7707                            try {
7708                                targetUid = AppGlobals.getPackageManager()
7709                                        .getPackageUid(targetPkg, targetUserId);
7710                            } catch (RemoteException e) {
7711                            }
7712                            if (targetUid != -1) {
7713                                final UriPermission perm = findOrCreateUriPermissionLocked(
7714                                        sourcePkg, targetPkg, targetUid,
7715                                        new GrantUri(sourceUserId, uri, prefix));
7716                                perm.initPersistedModes(modeFlags, createdTime);
7717                            }
7718                        } else {
7719                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7720                                    + " but instead found " + pi);
7721                        }
7722                    }
7723                }
7724            }
7725        } catch (FileNotFoundException e) {
7726            // Missing grants is okay
7727        } catch (IOException e) {
7728            Log.wtf(TAG, "Failed reading Uri grants", e);
7729        } catch (XmlPullParserException e) {
7730            Log.wtf(TAG, "Failed reading Uri grants", e);
7731        } finally {
7732            IoUtils.closeQuietly(fis);
7733        }
7734    }
7735
7736    /**
7737     * @param uri This uri must NOT contain an embedded userId.
7738     * @param userId The userId in which the uri is to be resolved.
7739     */
7740    @Override
7741    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7742        enforceNotIsolatedCaller("takePersistableUriPermission");
7743
7744        Preconditions.checkFlagsArgument(modeFlags,
7745                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7746
7747        synchronized (this) {
7748            final int callingUid = Binder.getCallingUid();
7749            boolean persistChanged = false;
7750            GrantUri grantUri = new GrantUri(userId, uri, false);
7751
7752            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7753                    new GrantUri(userId, uri, false));
7754            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7755                    new GrantUri(userId, uri, true));
7756
7757            final boolean exactValid = (exactPerm != null)
7758                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7759            final boolean prefixValid = (prefixPerm != null)
7760                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7761
7762            if (!(exactValid || prefixValid)) {
7763                throw new SecurityException("No persistable permission grants found for UID "
7764                        + callingUid + " and Uri " + grantUri.toSafeString());
7765            }
7766
7767            if (exactValid) {
7768                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7769            }
7770            if (prefixValid) {
7771                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7772            }
7773
7774            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7775
7776            if (persistChanged) {
7777                schedulePersistUriGrants();
7778            }
7779        }
7780    }
7781
7782    /**
7783     * @param uri This uri must NOT contain an embedded userId.
7784     * @param userId The userId in which the uri is to be resolved.
7785     */
7786    @Override
7787    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7788        enforceNotIsolatedCaller("releasePersistableUriPermission");
7789
7790        Preconditions.checkFlagsArgument(modeFlags,
7791                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7792
7793        synchronized (this) {
7794            final int callingUid = Binder.getCallingUid();
7795            boolean persistChanged = false;
7796
7797            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7798                    new GrantUri(userId, uri, false));
7799            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7800                    new GrantUri(userId, uri, true));
7801            if (exactPerm == null && prefixPerm == null) {
7802                throw new SecurityException("No permission grants found for UID " + callingUid
7803                        + " and Uri " + uri.toSafeString());
7804            }
7805
7806            if (exactPerm != null) {
7807                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7808                removeUriPermissionIfNeededLocked(exactPerm);
7809            }
7810            if (prefixPerm != null) {
7811                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7812                removeUriPermissionIfNeededLocked(prefixPerm);
7813            }
7814
7815            if (persistChanged) {
7816                schedulePersistUriGrants();
7817            }
7818        }
7819    }
7820
7821    /**
7822     * Prune any older {@link UriPermission} for the given UID until outstanding
7823     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7824     *
7825     * @return if any mutations occured that require persisting.
7826     */
7827    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7828        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7829        if (perms == null) return false;
7830        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7831
7832        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7833        for (UriPermission perm : perms.values()) {
7834            if (perm.persistedModeFlags != 0) {
7835                persisted.add(perm);
7836            }
7837        }
7838
7839        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7840        if (trimCount <= 0) return false;
7841
7842        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7843        for (int i = 0; i < trimCount; i++) {
7844            final UriPermission perm = persisted.get(i);
7845
7846            if (DEBUG_URI_PERMISSION) {
7847                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7848            }
7849
7850            perm.releasePersistableModes(~0);
7851            removeUriPermissionIfNeededLocked(perm);
7852        }
7853
7854        return true;
7855    }
7856
7857    @Override
7858    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7859            String packageName, boolean incoming) {
7860        enforceNotIsolatedCaller("getPersistedUriPermissions");
7861        Preconditions.checkNotNull(packageName, "packageName");
7862
7863        final int callingUid = Binder.getCallingUid();
7864        final IPackageManager pm = AppGlobals.getPackageManager();
7865        try {
7866            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7867            if (packageUid != callingUid) {
7868                throw new SecurityException(
7869                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7870            }
7871        } catch (RemoteException e) {
7872            throw new SecurityException("Failed to verify package name ownership");
7873        }
7874
7875        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7876        synchronized (this) {
7877            if (incoming) {
7878                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7879                        callingUid);
7880                if (perms == null) {
7881                    Slog.w(TAG, "No permission grants found for " + packageName);
7882                } else {
7883                    for (UriPermission perm : perms.values()) {
7884                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7885                            result.add(perm.buildPersistedPublicApiObject());
7886                        }
7887                    }
7888                }
7889            } else {
7890                final int size = mGrantedUriPermissions.size();
7891                for (int i = 0; i < size; i++) {
7892                    final ArrayMap<GrantUri, UriPermission> perms =
7893                            mGrantedUriPermissions.valueAt(i);
7894                    for (UriPermission perm : perms.values()) {
7895                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7896                            result.add(perm.buildPersistedPublicApiObject());
7897                        }
7898                    }
7899                }
7900            }
7901        }
7902        return new ParceledListSlice<android.content.UriPermission>(result);
7903    }
7904
7905    @Override
7906    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7907        synchronized (this) {
7908            ProcessRecord app =
7909                who != null ? getRecordForAppLocked(who) : null;
7910            if (app == null) return;
7911
7912            Message msg = Message.obtain();
7913            msg.what = WAIT_FOR_DEBUGGER_MSG;
7914            msg.obj = app;
7915            msg.arg1 = waiting ? 1 : 0;
7916            mHandler.sendMessage(msg);
7917        }
7918    }
7919
7920    @Override
7921    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7922        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7923        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7924        outInfo.availMem = Process.getFreeMemory();
7925        outInfo.totalMem = Process.getTotalMemory();
7926        outInfo.threshold = homeAppMem;
7927        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7928        outInfo.hiddenAppThreshold = cachedAppMem;
7929        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7930                ProcessList.SERVICE_ADJ);
7931        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7932                ProcessList.VISIBLE_APP_ADJ);
7933        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7934                ProcessList.FOREGROUND_APP_ADJ);
7935    }
7936
7937    // =========================================================
7938    // TASK MANAGEMENT
7939    // =========================================================
7940
7941    @Override
7942    public List<IAppTask> getAppTasks(String callingPackage) {
7943        int callingUid = Binder.getCallingUid();
7944        long ident = Binder.clearCallingIdentity();
7945
7946        synchronized(this) {
7947            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7948            try {
7949                if (localLOGV) Slog.v(TAG, "getAppTasks");
7950
7951                final int N = mRecentTasks.size();
7952                for (int i = 0; i < N; i++) {
7953                    TaskRecord tr = mRecentTasks.get(i);
7954                    // Skip tasks that do not match the caller.  We don't need to verify
7955                    // callingPackage, because we are also limiting to callingUid and know
7956                    // that will limit to the correct security sandbox.
7957                    if (tr.effectiveUid != callingUid) {
7958                        continue;
7959                    }
7960                    Intent intent = tr.getBaseIntent();
7961                    if (intent == null ||
7962                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7963                        continue;
7964                    }
7965                    ActivityManager.RecentTaskInfo taskInfo =
7966                            createRecentTaskInfoFromTaskRecord(tr);
7967                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7968                    list.add(taskImpl);
7969                }
7970            } finally {
7971                Binder.restoreCallingIdentity(ident);
7972            }
7973            return list;
7974        }
7975    }
7976
7977    @Override
7978    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7979        final int callingUid = Binder.getCallingUid();
7980        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7981
7982        synchronized(this) {
7983            if (localLOGV) Slog.v(
7984                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7985
7986            final boolean allowed = checkCallingPermission(
7987                    android.Manifest.permission.GET_TASKS)
7988                    == PackageManager.PERMISSION_GRANTED;
7989            if (!allowed) {
7990                Slog.w(TAG, "getTasks: caller " + callingUid
7991                        + " does not hold GET_TASKS; limiting output");
7992            }
7993
7994            // TODO: Improve with MRU list from all ActivityStacks.
7995            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7996        }
7997
7998        return list;
7999    }
8000
8001    TaskRecord getMostRecentTask() {
8002        return mRecentTasks.get(0);
8003    }
8004
8005    /**
8006     * Creates a new RecentTaskInfo from a TaskRecord.
8007     */
8008    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8009        // Update the task description to reflect any changes in the task stack
8010        tr.updateTaskDescription();
8011
8012        // Compose the recent task info
8013        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8014        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8015        rti.persistentId = tr.taskId;
8016        rti.baseIntent = new Intent(tr.getBaseIntent());
8017        rti.origActivity = tr.origActivity;
8018        rti.description = tr.lastDescription;
8019        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8020        rti.userId = tr.userId;
8021        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8022        rti.firstActiveTime = tr.firstActiveTime;
8023        rti.lastActiveTime = tr.lastActiveTime;
8024        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8025        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8026        return rti;
8027    }
8028
8029    @Override
8030    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8031        final int callingUid = Binder.getCallingUid();
8032        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8033                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8034
8035        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8036        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8037        synchronized (this) {
8038            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8039                    == PackageManager.PERMISSION_GRANTED;
8040            if (!allowed) {
8041                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8042                        + " does not hold GET_TASKS; limiting output");
8043            }
8044            final boolean detailed = checkCallingPermission(
8045                    android.Manifest.permission.GET_DETAILED_TASKS)
8046                    == PackageManager.PERMISSION_GRANTED;
8047
8048            final int N = mRecentTasks.size();
8049            ArrayList<ActivityManager.RecentTaskInfo> res
8050                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8051                            maxNum < N ? maxNum : N);
8052
8053            final Set<Integer> includedUsers;
8054            if (includeProfiles) {
8055                includedUsers = getProfileIdsLocked(userId);
8056            } else {
8057                includedUsers = new HashSet<Integer>();
8058            }
8059            includedUsers.add(Integer.valueOf(userId));
8060
8061            for (int i=0; i<N && maxNum > 0; i++) {
8062                TaskRecord tr = mRecentTasks.get(i);
8063                // Only add calling user or related users recent tasks
8064                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8065                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8066                    continue;
8067                }
8068
8069                // Return the entry if desired by the caller.  We always return
8070                // the first entry, because callers always expect this to be the
8071                // foreground app.  We may filter others if the caller has
8072                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8073                // we should exclude the entry.
8074
8075                if (i == 0
8076                        || withExcluded
8077                        || (tr.intent == null)
8078                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8079                                == 0)) {
8080                    if (!allowed) {
8081                        // If the caller doesn't have the GET_TASKS permission, then only
8082                        // allow them to see a small subset of tasks -- their own and home.
8083                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8084                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8085                            continue;
8086                        }
8087                    }
8088                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8089                        if (tr.stack != null && tr.stack.isHomeStack()) {
8090                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8091                            continue;
8092                        }
8093                    }
8094                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8095                        // Don't include auto remove tasks that are finished or finishing.
8096                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8097                                + tr);
8098                        continue;
8099                    }
8100                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8101                            && !tr.isAvailable) {
8102                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8103                        continue;
8104                    }
8105
8106                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8107                    if (!detailed) {
8108                        rti.baseIntent.replaceExtras((Bundle)null);
8109                    }
8110
8111                    res.add(rti);
8112                    maxNum--;
8113                }
8114            }
8115            return res;
8116        }
8117    }
8118
8119    private TaskRecord recentTaskForIdLocked(int id) {
8120        final int N = mRecentTasks.size();
8121            for (int i=0; i<N; i++) {
8122                TaskRecord tr = mRecentTasks.get(i);
8123                if (tr.taskId == id) {
8124                    return tr;
8125                }
8126            }
8127            return null;
8128    }
8129
8130    @Override
8131    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8132        synchronized (this) {
8133            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8134                    "getTaskThumbnail()");
8135            TaskRecord tr = recentTaskForIdLocked(id);
8136            if (tr != null) {
8137                return tr.getTaskThumbnailLocked();
8138            }
8139        }
8140        return null;
8141    }
8142
8143    @Override
8144    public int addAppTask(IBinder activityToken, Intent intent,
8145            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8146        final int callingUid = Binder.getCallingUid();
8147        final long callingIdent = Binder.clearCallingIdentity();
8148
8149        try {
8150            synchronized (this) {
8151                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8152                if (r == null) {
8153                    throw new IllegalArgumentException("Activity does not exist; token="
8154                            + activityToken);
8155                }
8156                ComponentName comp = intent.getComponent();
8157                if (comp == null) {
8158                    throw new IllegalArgumentException("Intent " + intent
8159                            + " must specify explicit component");
8160                }
8161                if (thumbnail.getWidth() != mThumbnailWidth
8162                        || thumbnail.getHeight() != mThumbnailHeight) {
8163                    throw new IllegalArgumentException("Bad thumbnail size: got "
8164                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8165                            + mThumbnailWidth + "x" + mThumbnailHeight);
8166                }
8167                if (intent.getSelector() != null) {
8168                    intent.setSelector(null);
8169                }
8170                if (intent.getSourceBounds() != null) {
8171                    intent.setSourceBounds(null);
8172                }
8173                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8174                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8175                        // The caller has added this as an auto-remove task...  that makes no
8176                        // sense, so turn off auto-remove.
8177                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8178                    }
8179                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8180                    // Must be a new task.
8181                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8182                }
8183                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8184                    mLastAddedTaskActivity = null;
8185                }
8186                ActivityInfo ainfo = mLastAddedTaskActivity;
8187                if (ainfo == null) {
8188                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8189                            comp, 0, UserHandle.getUserId(callingUid));
8190                    if (ainfo.applicationInfo.uid != callingUid) {
8191                        throw new SecurityException(
8192                                "Can't add task for another application: target uid="
8193                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8194                    }
8195                }
8196
8197                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8198                        intent, description);
8199
8200                int trimIdx = trimRecentsForTask(task, false);
8201                if (trimIdx >= 0) {
8202                    // If this would have caused a trim, then we'll abort because that
8203                    // means it would be added at the end of the list but then just removed.
8204                    return -1;
8205                }
8206
8207                final int N = mRecentTasks.size();
8208                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8209                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8210                    tr.removedFromRecents(mTaskPersister);
8211                }
8212
8213                task.inRecents = true;
8214                mRecentTasks.add(task);
8215                r.task.stack.addTask(task, false, false);
8216
8217                task.setLastThumbnail(thumbnail);
8218                task.freeLastThumbnail();
8219
8220                return task.taskId;
8221            }
8222        } finally {
8223            Binder.restoreCallingIdentity(callingIdent);
8224        }
8225    }
8226
8227    @Override
8228    public Point getAppTaskThumbnailSize() {
8229        synchronized (this) {
8230            return new Point(mThumbnailWidth,  mThumbnailHeight);
8231        }
8232    }
8233
8234    @Override
8235    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8236        synchronized (this) {
8237            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8238            if (r != null) {
8239                r.taskDescription = td;
8240                r.task.updateTaskDescription();
8241            }
8242        }
8243    }
8244
8245    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8246        mRecentTasks.remove(tr);
8247        tr.removedFromRecents(mTaskPersister);
8248        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8249        Intent baseIntent = new Intent(
8250                tr.intent != null ? tr.intent : tr.affinityIntent);
8251        ComponentName component = baseIntent.getComponent();
8252        if (component == null) {
8253            Slog.w(TAG, "Now component for base intent of task: " + tr);
8254            return;
8255        }
8256
8257        // Find any running services associated with this app.
8258        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8259
8260        if (killProcesses) {
8261            // Find any running processes associated with this app.
8262            final String pkg = component.getPackageName();
8263            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8264            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8265            for (int i=0; i<pmap.size(); i++) {
8266                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8267                for (int j=0; j<uids.size(); j++) {
8268                    ProcessRecord proc = uids.valueAt(j);
8269                    if (proc.userId != tr.userId) {
8270                        continue;
8271                    }
8272                    if (!proc.pkgList.containsKey(pkg)) {
8273                        continue;
8274                    }
8275                    procs.add(proc);
8276                }
8277            }
8278
8279            // Kill the running processes.
8280            for (int i=0; i<procs.size(); i++) {
8281                ProcessRecord pr = procs.get(i);
8282                if (pr == mHomeProcess) {
8283                    // Don't kill the home process along with tasks from the same package.
8284                    continue;
8285                }
8286                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8287                    pr.kill("remove task", true);
8288                } else {
8289                    pr.waitingToKill = "remove task";
8290                }
8291            }
8292        }
8293    }
8294
8295    /**
8296     * Removes the task with the specified task id.
8297     *
8298     * @param taskId Identifier of the task to be removed.
8299     * @param flags Additional operational flags.  May be 0 or
8300     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8301     * @return Returns true if the given task was found and removed.
8302     */
8303    private boolean removeTaskByIdLocked(int taskId, int flags) {
8304        TaskRecord tr = recentTaskForIdLocked(taskId);
8305        if (tr != null) {
8306            tr.removeTaskActivitiesLocked();
8307            cleanUpRemovedTaskLocked(tr, flags);
8308            if (tr.isPersistable) {
8309                notifyTaskPersisterLocked(null, true);
8310            }
8311            return true;
8312        }
8313        return false;
8314    }
8315
8316    @Override
8317    public boolean removeTask(int taskId, int flags) {
8318        synchronized (this) {
8319            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8320                    "removeTask()");
8321            long ident = Binder.clearCallingIdentity();
8322            try {
8323                return removeTaskByIdLocked(taskId, flags);
8324            } finally {
8325                Binder.restoreCallingIdentity(ident);
8326            }
8327        }
8328    }
8329
8330    /**
8331     * TODO: Add mController hook
8332     */
8333    @Override
8334    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8335        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8336                "moveTaskToFront()");
8337
8338        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8339        synchronized(this) {
8340            moveTaskToFrontLocked(taskId, flags, options);
8341        }
8342    }
8343
8344    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8345        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8346                Binder.getCallingUid(), "Task to front")) {
8347            ActivityOptions.abort(options);
8348            return;
8349        }
8350        final long origId = Binder.clearCallingIdentity();
8351        try {
8352            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8353            if (task == null) {
8354                return;
8355            }
8356            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8357                mStackSupervisor.showLockTaskToast();
8358                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8359                return;
8360            }
8361            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8362            if (prev != null && prev.isRecentsActivity()) {
8363                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8364            }
8365            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8366        } finally {
8367            Binder.restoreCallingIdentity(origId);
8368        }
8369        ActivityOptions.abort(options);
8370    }
8371
8372    @Override
8373    public void moveTaskToBack(int taskId) {
8374        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8375                "moveTaskToBack()");
8376
8377        synchronized(this) {
8378            TaskRecord tr = recentTaskForIdLocked(taskId);
8379            if (tr != null) {
8380                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8381                ActivityStack stack = tr.stack;
8382                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8383                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8384                            Binder.getCallingUid(), "Task to back")) {
8385                        return;
8386                    }
8387                }
8388                final long origId = Binder.clearCallingIdentity();
8389                try {
8390                    stack.moveTaskToBackLocked(taskId, null);
8391                } finally {
8392                    Binder.restoreCallingIdentity(origId);
8393                }
8394            }
8395        }
8396    }
8397
8398    /**
8399     * Moves an activity, and all of the other activities within the same task, to the bottom
8400     * of the history stack.  The activity's order within the task is unchanged.
8401     *
8402     * @param token A reference to the activity we wish to move
8403     * @param nonRoot If false then this only works if the activity is the root
8404     *                of a task; if true it will work for any activity in a task.
8405     * @return Returns true if the move completed, false if not.
8406     */
8407    @Override
8408    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8409        enforceNotIsolatedCaller("moveActivityTaskToBack");
8410        synchronized(this) {
8411            final long origId = Binder.clearCallingIdentity();
8412            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8413            if (taskId >= 0) {
8414                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8415            }
8416            Binder.restoreCallingIdentity(origId);
8417        }
8418        return false;
8419    }
8420
8421    @Override
8422    public void moveTaskBackwards(int task) {
8423        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8424                "moveTaskBackwards()");
8425
8426        synchronized(this) {
8427            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8428                    Binder.getCallingUid(), "Task backwards")) {
8429                return;
8430            }
8431            final long origId = Binder.clearCallingIdentity();
8432            moveTaskBackwardsLocked(task);
8433            Binder.restoreCallingIdentity(origId);
8434        }
8435    }
8436
8437    private final void moveTaskBackwardsLocked(int task) {
8438        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8439    }
8440
8441    @Override
8442    public IBinder getHomeActivityToken() throws RemoteException {
8443        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8444                "getHomeActivityToken()");
8445        synchronized (this) {
8446            return mStackSupervisor.getHomeActivityToken();
8447        }
8448    }
8449
8450    @Override
8451    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8452            IActivityContainerCallback callback) throws RemoteException {
8453        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8454                "createActivityContainer()");
8455        synchronized (this) {
8456            if (parentActivityToken == null) {
8457                throw new IllegalArgumentException("parent token must not be null");
8458            }
8459            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8460            if (r == null) {
8461                return null;
8462            }
8463            if (callback == null) {
8464                throw new IllegalArgumentException("callback must not be null");
8465            }
8466            return mStackSupervisor.createActivityContainer(r, callback);
8467        }
8468    }
8469
8470    @Override
8471    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8472        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8473                "deleteActivityContainer()");
8474        synchronized (this) {
8475            mStackSupervisor.deleteActivityContainer(container);
8476        }
8477    }
8478
8479    @Override
8480    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8481            throws RemoteException {
8482        synchronized (this) {
8483            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8484            if (stack != null) {
8485                return stack.mActivityContainer;
8486            }
8487            return null;
8488        }
8489    }
8490
8491    @Override
8492    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8493        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8494                "moveTaskToStack()");
8495        if (stackId == HOME_STACK_ID) {
8496            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8497                    new RuntimeException("here").fillInStackTrace());
8498        }
8499        synchronized (this) {
8500            long ident = Binder.clearCallingIdentity();
8501            try {
8502                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8503                        + stackId + " toTop=" + toTop);
8504                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8505            } finally {
8506                Binder.restoreCallingIdentity(ident);
8507            }
8508        }
8509    }
8510
8511    @Override
8512    public void resizeStack(int stackBoxId, Rect bounds) {
8513        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8514                "resizeStackBox()");
8515        long ident = Binder.clearCallingIdentity();
8516        try {
8517            mWindowManager.resizeStack(stackBoxId, bounds);
8518        } finally {
8519            Binder.restoreCallingIdentity(ident);
8520        }
8521    }
8522
8523    @Override
8524    public List<StackInfo> getAllStackInfos() {
8525        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8526                "getAllStackInfos()");
8527        long ident = Binder.clearCallingIdentity();
8528        try {
8529            synchronized (this) {
8530                return mStackSupervisor.getAllStackInfosLocked();
8531            }
8532        } finally {
8533            Binder.restoreCallingIdentity(ident);
8534        }
8535    }
8536
8537    @Override
8538    public StackInfo getStackInfo(int stackId) {
8539        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8540                "getStackInfo()");
8541        long ident = Binder.clearCallingIdentity();
8542        try {
8543            synchronized (this) {
8544                return mStackSupervisor.getStackInfoLocked(stackId);
8545            }
8546        } finally {
8547            Binder.restoreCallingIdentity(ident);
8548        }
8549    }
8550
8551    @Override
8552    public boolean isInHomeStack(int taskId) {
8553        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8554                "getStackInfo()");
8555        long ident = Binder.clearCallingIdentity();
8556        try {
8557            synchronized (this) {
8558                TaskRecord tr = recentTaskForIdLocked(taskId);
8559                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8560            }
8561        } finally {
8562            Binder.restoreCallingIdentity(ident);
8563        }
8564    }
8565
8566    @Override
8567    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8568        synchronized(this) {
8569            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8570        }
8571    }
8572
8573    private boolean isLockTaskAuthorized(String pkg) {
8574        final DevicePolicyManager dpm = (DevicePolicyManager)
8575                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8576        try {
8577            int uid = mContext.getPackageManager().getPackageUid(pkg,
8578                    Binder.getCallingUserHandle().getIdentifier());
8579            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8580        } catch (NameNotFoundException e) {
8581            return false;
8582        }
8583    }
8584
8585    void startLockTaskMode(TaskRecord task) {
8586        final String pkg;
8587        synchronized (this) {
8588            pkg = task.intent.getComponent().getPackageName();
8589        }
8590        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8591        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8592            final TaskRecord taskRecord = task;
8593            mHandler.post(new Runnable() {
8594                @Override
8595                public void run() {
8596                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8597                }
8598            });
8599            return;
8600        }
8601        long ident = Binder.clearCallingIdentity();
8602        try {
8603            synchronized (this) {
8604                // Since we lost lock on task, make sure it is still there.
8605                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8606                if (task != null) {
8607                    if (!isSystemInitiated
8608                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8609                        throw new IllegalArgumentException("Invalid task, not in foreground");
8610                    }
8611                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8612                }
8613            }
8614        } finally {
8615            Binder.restoreCallingIdentity(ident);
8616        }
8617    }
8618
8619    @Override
8620    public void startLockTaskMode(int taskId) {
8621        final TaskRecord task;
8622        long ident = Binder.clearCallingIdentity();
8623        try {
8624            synchronized (this) {
8625                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8626            }
8627        } finally {
8628            Binder.restoreCallingIdentity(ident);
8629        }
8630        if (task != null) {
8631            startLockTaskMode(task);
8632        }
8633    }
8634
8635    @Override
8636    public void startLockTaskMode(IBinder token) {
8637        final TaskRecord task;
8638        long ident = Binder.clearCallingIdentity();
8639        try {
8640            synchronized (this) {
8641                final ActivityRecord r = ActivityRecord.forToken(token);
8642                if (r == null) {
8643                    return;
8644                }
8645                task = r.task;
8646            }
8647        } finally {
8648            Binder.restoreCallingIdentity(ident);
8649        }
8650        if (task != null) {
8651            startLockTaskMode(task);
8652        }
8653    }
8654
8655    @Override
8656    public void startLockTaskModeOnCurrent() throws RemoteException {
8657        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8658        ActivityRecord r = null;
8659        synchronized (this) {
8660            r = mStackSupervisor.topRunningActivityLocked();
8661        }
8662        startLockTaskMode(r.task);
8663    }
8664
8665    @Override
8666    public void stopLockTaskMode() {
8667        // Verify that the user matches the package of the intent for the TaskRecord
8668        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8669        // and stopLockTaskMode.
8670        final int callingUid = Binder.getCallingUid();
8671        if (callingUid != Process.SYSTEM_UID) {
8672            try {
8673                String pkg =
8674                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8675                int uid = mContext.getPackageManager().getPackageUid(pkg,
8676                        Binder.getCallingUserHandle().getIdentifier());
8677                if (uid != callingUid) {
8678                    throw new SecurityException("Invalid uid, expected " + uid);
8679                }
8680            } catch (NameNotFoundException e) {
8681                Log.d(TAG, "stopLockTaskMode " + e);
8682                return;
8683            }
8684        }
8685        long ident = Binder.clearCallingIdentity();
8686        try {
8687            Log.d(TAG, "stopLockTaskMode");
8688            // Stop lock task
8689            synchronized (this) {
8690                mStackSupervisor.setLockTaskModeLocked(null, false);
8691            }
8692        } finally {
8693            Binder.restoreCallingIdentity(ident);
8694        }
8695    }
8696
8697    @Override
8698    public void stopLockTaskModeOnCurrent() throws RemoteException {
8699        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8700        long ident = Binder.clearCallingIdentity();
8701        try {
8702            stopLockTaskMode();
8703        } finally {
8704            Binder.restoreCallingIdentity(ident);
8705        }
8706    }
8707
8708    @Override
8709    public boolean isInLockTaskMode() {
8710        synchronized (this) {
8711            return mStackSupervisor.isInLockTaskMode();
8712        }
8713    }
8714
8715    // =========================================================
8716    // CONTENT PROVIDERS
8717    // =========================================================
8718
8719    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8720        List<ProviderInfo> providers = null;
8721        try {
8722            providers = AppGlobals.getPackageManager().
8723                queryContentProviders(app.processName, app.uid,
8724                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8725        } catch (RemoteException ex) {
8726        }
8727        if (DEBUG_MU)
8728            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8729        int userId = app.userId;
8730        if (providers != null) {
8731            int N = providers.size();
8732            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8733            for (int i=0; i<N; i++) {
8734                ProviderInfo cpi =
8735                    (ProviderInfo)providers.get(i);
8736                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8737                        cpi.name, cpi.flags);
8738                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8739                    // This is a singleton provider, but a user besides the
8740                    // default user is asking to initialize a process it runs
8741                    // in...  well, no, it doesn't actually run in this process,
8742                    // it runs in the process of the default user.  Get rid of it.
8743                    providers.remove(i);
8744                    N--;
8745                    i--;
8746                    continue;
8747                }
8748
8749                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8750                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8751                if (cpr == null) {
8752                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8753                    mProviderMap.putProviderByClass(comp, cpr);
8754                }
8755                if (DEBUG_MU)
8756                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8757                app.pubProviders.put(cpi.name, cpr);
8758                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8759                    // Don't add this if it is a platform component that is marked
8760                    // to run in multiple processes, because this is actually
8761                    // part of the framework so doesn't make sense to track as a
8762                    // separate apk in the process.
8763                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8764                            mProcessStats);
8765                }
8766                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8767            }
8768        }
8769        return providers;
8770    }
8771
8772    /**
8773     * Check if {@link ProcessRecord} has a possible chance at accessing the
8774     * given {@link ProviderInfo}. Final permission checking is always done
8775     * in {@link ContentProvider}.
8776     */
8777    private final String checkContentProviderPermissionLocked(
8778            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8779        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8780        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8781        boolean checkedGrants = false;
8782        if (checkUser) {
8783            // Looking for cross-user grants before enforcing the typical cross-users permissions
8784            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8785            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8786                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8787                    return null;
8788                }
8789                checkedGrants = true;
8790            }
8791            userId = handleIncomingUser(callingPid, callingUid, userId,
8792                    false, ALLOW_NON_FULL,
8793                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8794            if (userId != tmpTargetUserId) {
8795                // When we actually went to determine the final targer user ID, this ended
8796                // up different than our initial check for the authority.  This is because
8797                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8798                // SELF.  So we need to re-check the grants again.
8799                checkedGrants = false;
8800            }
8801        }
8802        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8803                cpi.applicationInfo.uid, cpi.exported)
8804                == PackageManager.PERMISSION_GRANTED) {
8805            return null;
8806        }
8807        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8808                cpi.applicationInfo.uid, cpi.exported)
8809                == PackageManager.PERMISSION_GRANTED) {
8810            return null;
8811        }
8812
8813        PathPermission[] pps = cpi.pathPermissions;
8814        if (pps != null) {
8815            int i = pps.length;
8816            while (i > 0) {
8817                i--;
8818                PathPermission pp = pps[i];
8819                String pprperm = pp.getReadPermission();
8820                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8821                        cpi.applicationInfo.uid, cpi.exported)
8822                        == PackageManager.PERMISSION_GRANTED) {
8823                    return null;
8824                }
8825                String ppwperm = pp.getWritePermission();
8826                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8827                        cpi.applicationInfo.uid, cpi.exported)
8828                        == PackageManager.PERMISSION_GRANTED) {
8829                    return null;
8830                }
8831            }
8832        }
8833        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8834            return null;
8835        }
8836
8837        String msg;
8838        if (!cpi.exported) {
8839            msg = "Permission Denial: opening provider " + cpi.name
8840                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8841                    + ", uid=" + callingUid + ") that is not exported from uid "
8842                    + cpi.applicationInfo.uid;
8843        } else {
8844            msg = "Permission Denial: opening provider " + cpi.name
8845                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8846                    + ", uid=" + callingUid + ") requires "
8847                    + cpi.readPermission + " or " + cpi.writePermission;
8848        }
8849        Slog.w(TAG, msg);
8850        return msg;
8851    }
8852
8853    /**
8854     * Returns if the ContentProvider has granted a uri to callingUid
8855     */
8856    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8857        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8858        if (perms != null) {
8859            for (int i=perms.size()-1; i>=0; i--) {
8860                GrantUri grantUri = perms.keyAt(i);
8861                if (grantUri.sourceUserId == userId || !checkUser) {
8862                    if (matchesProvider(grantUri.uri, cpi)) {
8863                        return true;
8864                    }
8865                }
8866            }
8867        }
8868        return false;
8869    }
8870
8871    /**
8872     * Returns true if the uri authority is one of the authorities specified in the provider.
8873     */
8874    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8875        String uriAuth = uri.getAuthority();
8876        String cpiAuth = cpi.authority;
8877        if (cpiAuth.indexOf(';') == -1) {
8878            return cpiAuth.equals(uriAuth);
8879        }
8880        String[] cpiAuths = cpiAuth.split(";");
8881        int length = cpiAuths.length;
8882        for (int i = 0; i < length; i++) {
8883            if (cpiAuths[i].equals(uriAuth)) return true;
8884        }
8885        return false;
8886    }
8887
8888    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8889            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8890        if (r != null) {
8891            for (int i=0; i<r.conProviders.size(); i++) {
8892                ContentProviderConnection conn = r.conProviders.get(i);
8893                if (conn.provider == cpr) {
8894                    if (DEBUG_PROVIDER) Slog.v(TAG,
8895                            "Adding provider requested by "
8896                            + r.processName + " from process "
8897                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8898                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8899                    if (stable) {
8900                        conn.stableCount++;
8901                        conn.numStableIncs++;
8902                    } else {
8903                        conn.unstableCount++;
8904                        conn.numUnstableIncs++;
8905                    }
8906                    return conn;
8907                }
8908            }
8909            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8910            if (stable) {
8911                conn.stableCount = 1;
8912                conn.numStableIncs = 1;
8913            } else {
8914                conn.unstableCount = 1;
8915                conn.numUnstableIncs = 1;
8916            }
8917            cpr.connections.add(conn);
8918            r.conProviders.add(conn);
8919            return conn;
8920        }
8921        cpr.addExternalProcessHandleLocked(externalProcessToken);
8922        return null;
8923    }
8924
8925    boolean decProviderCountLocked(ContentProviderConnection conn,
8926            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8927        if (conn != null) {
8928            cpr = conn.provider;
8929            if (DEBUG_PROVIDER) Slog.v(TAG,
8930                    "Removing provider requested by "
8931                    + conn.client.processName + " from process "
8932                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8933                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8934            if (stable) {
8935                conn.stableCount--;
8936            } else {
8937                conn.unstableCount--;
8938            }
8939            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8940                cpr.connections.remove(conn);
8941                conn.client.conProviders.remove(conn);
8942                return true;
8943            }
8944            return false;
8945        }
8946        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8947        return false;
8948    }
8949
8950    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8951            String name, IBinder token, boolean stable, int userId) {
8952        ContentProviderRecord cpr;
8953        ContentProviderConnection conn = null;
8954        ProviderInfo cpi = null;
8955
8956        synchronized(this) {
8957            ProcessRecord r = null;
8958            if (caller != null) {
8959                r = getRecordForAppLocked(caller);
8960                if (r == null) {
8961                    throw new SecurityException(
8962                            "Unable to find app for caller " + caller
8963                          + " (pid=" + Binder.getCallingPid()
8964                          + ") when getting content provider " + name);
8965                }
8966            }
8967
8968            boolean checkCrossUser = true;
8969
8970            // First check if this content provider has been published...
8971            cpr = mProviderMap.getProviderByName(name, userId);
8972            // If that didn't work, check if it exists for user 0 and then
8973            // verify that it's a singleton provider before using it.
8974            if (cpr == null && userId != UserHandle.USER_OWNER) {
8975                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8976                if (cpr != null) {
8977                    cpi = cpr.info;
8978                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8979                            cpi.name, cpi.flags)
8980                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8981                        userId = UserHandle.USER_OWNER;
8982                        checkCrossUser = false;
8983                    } else {
8984                        cpr = null;
8985                        cpi = null;
8986                    }
8987                }
8988            }
8989
8990            boolean providerRunning = cpr != null;
8991            if (providerRunning) {
8992                cpi = cpr.info;
8993                String msg;
8994                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8995                        != null) {
8996                    throw new SecurityException(msg);
8997                }
8998
8999                if (r != null && cpr.canRunHere(r)) {
9000                    // This provider has been published or is in the process
9001                    // of being published...  but it is also allowed to run
9002                    // in the caller's process, so don't make a connection
9003                    // and just let the caller instantiate its own instance.
9004                    ContentProviderHolder holder = cpr.newHolder(null);
9005                    // don't give caller the provider object, it needs
9006                    // to make its own.
9007                    holder.provider = null;
9008                    return holder;
9009                }
9010
9011                final long origId = Binder.clearCallingIdentity();
9012
9013                // In this case the provider instance already exists, so we can
9014                // return it right away.
9015                conn = incProviderCountLocked(r, cpr, token, stable);
9016                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9017                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9018                        // If this is a perceptible app accessing the provider,
9019                        // make sure to count it as being accessed and thus
9020                        // back up on the LRU list.  This is good because
9021                        // content providers are often expensive to start.
9022                        updateLruProcessLocked(cpr.proc, false, null);
9023                    }
9024                }
9025
9026                if (cpr.proc != null) {
9027                    if (false) {
9028                        if (cpr.name.flattenToShortString().equals(
9029                                "com.android.providers.calendar/.CalendarProvider2")) {
9030                            Slog.v(TAG, "****************** KILLING "
9031                                + cpr.name.flattenToShortString());
9032                            Process.killProcess(cpr.proc.pid);
9033                        }
9034                    }
9035                    boolean success = updateOomAdjLocked(cpr.proc);
9036                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9037                    // NOTE: there is still a race here where a signal could be
9038                    // pending on the process even though we managed to update its
9039                    // adj level.  Not sure what to do about this, but at least
9040                    // the race is now smaller.
9041                    if (!success) {
9042                        // Uh oh...  it looks like the provider's process
9043                        // has been killed on us.  We need to wait for a new
9044                        // process to be started, and make sure its death
9045                        // doesn't kill our process.
9046                        Slog.i(TAG,
9047                                "Existing provider " + cpr.name.flattenToShortString()
9048                                + " is crashing; detaching " + r);
9049                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9050                        appDiedLocked(cpr.proc);
9051                        if (!lastRef) {
9052                            // This wasn't the last ref our process had on
9053                            // the provider...  we have now been killed, bail.
9054                            return null;
9055                        }
9056                        providerRunning = false;
9057                        conn = null;
9058                    }
9059                }
9060
9061                Binder.restoreCallingIdentity(origId);
9062            }
9063
9064            boolean singleton;
9065            if (!providerRunning) {
9066                try {
9067                    cpi = AppGlobals.getPackageManager().
9068                        resolveContentProvider(name,
9069                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9070                } catch (RemoteException ex) {
9071                }
9072                if (cpi == null) {
9073                    return null;
9074                }
9075                // If the provider is a singleton AND
9076                // (it's a call within the same user || the provider is a
9077                // privileged app)
9078                // Then allow connecting to the singleton provider
9079                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9080                        cpi.name, cpi.flags)
9081                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9082                if (singleton) {
9083                    userId = UserHandle.USER_OWNER;
9084                }
9085                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9086
9087                String msg;
9088                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9089                        != null) {
9090                    throw new SecurityException(msg);
9091                }
9092
9093                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9094                        && !cpi.processName.equals("system")) {
9095                    // If this content provider does not run in the system
9096                    // process, and the system is not yet ready to run other
9097                    // processes, then fail fast instead of hanging.
9098                    throw new IllegalArgumentException(
9099                            "Attempt to launch content provider before system ready");
9100                }
9101
9102                // Make sure that the user who owns this provider is started.  If not,
9103                // we don't want to allow it to run.
9104                if (mStartedUsers.get(userId) == null) {
9105                    Slog.w(TAG, "Unable to launch app "
9106                            + cpi.applicationInfo.packageName + "/"
9107                            + cpi.applicationInfo.uid + " for provider "
9108                            + name + ": user " + userId + " is stopped");
9109                    return null;
9110                }
9111
9112                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9113                cpr = mProviderMap.getProviderByClass(comp, userId);
9114                final boolean firstClass = cpr == null;
9115                if (firstClass) {
9116                    try {
9117                        ApplicationInfo ai =
9118                            AppGlobals.getPackageManager().
9119                                getApplicationInfo(
9120                                        cpi.applicationInfo.packageName,
9121                                        STOCK_PM_FLAGS, userId);
9122                        if (ai == null) {
9123                            Slog.w(TAG, "No package info for content provider "
9124                                    + cpi.name);
9125                            return null;
9126                        }
9127                        ai = getAppInfoForUser(ai, userId);
9128                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9129                    } catch (RemoteException ex) {
9130                        // pm is in same process, this will never happen.
9131                    }
9132                }
9133
9134                if (r != null && cpr.canRunHere(r)) {
9135                    // If this is a multiprocess provider, then just return its
9136                    // info and allow the caller to instantiate it.  Only do
9137                    // this if the provider is the same user as the caller's
9138                    // process, or can run as root (so can be in any process).
9139                    return cpr.newHolder(null);
9140                }
9141
9142                if (DEBUG_PROVIDER) {
9143                    RuntimeException e = new RuntimeException("here");
9144                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9145                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9146                }
9147
9148                // This is single process, and our app is now connecting to it.
9149                // See if we are already in the process of launching this
9150                // provider.
9151                final int N = mLaunchingProviders.size();
9152                int i;
9153                for (i=0; i<N; i++) {
9154                    if (mLaunchingProviders.get(i) == cpr) {
9155                        break;
9156                    }
9157                }
9158
9159                // If the provider is not already being launched, then get it
9160                // started.
9161                if (i >= N) {
9162                    final long origId = Binder.clearCallingIdentity();
9163
9164                    try {
9165                        // Content provider is now in use, its package can't be stopped.
9166                        try {
9167                            AppGlobals.getPackageManager().setPackageStoppedState(
9168                                    cpr.appInfo.packageName, false, userId);
9169                        } catch (RemoteException e) {
9170                        } catch (IllegalArgumentException e) {
9171                            Slog.w(TAG, "Failed trying to unstop package "
9172                                    + cpr.appInfo.packageName + ": " + e);
9173                        }
9174
9175                        // Use existing process if already started
9176                        ProcessRecord proc = getProcessRecordLocked(
9177                                cpi.processName, cpr.appInfo.uid, false);
9178                        if (proc != null && proc.thread != null) {
9179                            if (DEBUG_PROVIDER) {
9180                                Slog.d(TAG, "Installing in existing process " + proc);
9181                            }
9182                            proc.pubProviders.put(cpi.name, cpr);
9183                            try {
9184                                proc.thread.scheduleInstallProvider(cpi);
9185                            } catch (RemoteException e) {
9186                            }
9187                        } else {
9188                            proc = startProcessLocked(cpi.processName,
9189                                    cpr.appInfo, false, 0, "content provider",
9190                                    new ComponentName(cpi.applicationInfo.packageName,
9191                                            cpi.name), false, false, false);
9192                            if (proc == null) {
9193                                Slog.w(TAG, "Unable to launch app "
9194                                        + cpi.applicationInfo.packageName + "/"
9195                                        + cpi.applicationInfo.uid + " for provider "
9196                                        + name + ": process is bad");
9197                                return null;
9198                            }
9199                        }
9200                        cpr.launchingApp = proc;
9201                        mLaunchingProviders.add(cpr);
9202                    } finally {
9203                        Binder.restoreCallingIdentity(origId);
9204                    }
9205                }
9206
9207                // Make sure the provider is published (the same provider class
9208                // may be published under multiple names).
9209                if (firstClass) {
9210                    mProviderMap.putProviderByClass(comp, cpr);
9211                }
9212
9213                mProviderMap.putProviderByName(name, cpr);
9214                conn = incProviderCountLocked(r, cpr, token, stable);
9215                if (conn != null) {
9216                    conn.waiting = true;
9217                }
9218            }
9219        }
9220
9221        // Wait for the provider to be published...
9222        synchronized (cpr) {
9223            while (cpr.provider == null) {
9224                if (cpr.launchingApp == null) {
9225                    Slog.w(TAG, "Unable to launch app "
9226                            + cpi.applicationInfo.packageName + "/"
9227                            + cpi.applicationInfo.uid + " for provider "
9228                            + name + ": launching app became null");
9229                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9230                            UserHandle.getUserId(cpi.applicationInfo.uid),
9231                            cpi.applicationInfo.packageName,
9232                            cpi.applicationInfo.uid, name);
9233                    return null;
9234                }
9235                try {
9236                    if (DEBUG_MU) {
9237                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9238                                + cpr.launchingApp);
9239                    }
9240                    if (conn != null) {
9241                        conn.waiting = true;
9242                    }
9243                    cpr.wait();
9244                } catch (InterruptedException ex) {
9245                } finally {
9246                    if (conn != null) {
9247                        conn.waiting = false;
9248                    }
9249                }
9250            }
9251        }
9252        return cpr != null ? cpr.newHolder(conn) : null;
9253    }
9254
9255    @Override
9256    public final ContentProviderHolder getContentProvider(
9257            IApplicationThread caller, String name, int userId, boolean stable) {
9258        enforceNotIsolatedCaller("getContentProvider");
9259        if (caller == null) {
9260            String msg = "null IApplicationThread when getting content provider "
9261                    + name;
9262            Slog.w(TAG, msg);
9263            throw new SecurityException(msg);
9264        }
9265        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9266        // with cross-user grant.
9267        return getContentProviderImpl(caller, name, null, stable, userId);
9268    }
9269
9270    public ContentProviderHolder getContentProviderExternal(
9271            String name, int userId, IBinder token) {
9272        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9273            "Do not have permission in call getContentProviderExternal()");
9274        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9275                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9276        return getContentProviderExternalUnchecked(name, token, userId);
9277    }
9278
9279    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9280            IBinder token, int userId) {
9281        return getContentProviderImpl(null, name, token, true, userId);
9282    }
9283
9284    /**
9285     * Drop a content provider from a ProcessRecord's bookkeeping
9286     */
9287    public void removeContentProvider(IBinder connection, boolean stable) {
9288        enforceNotIsolatedCaller("removeContentProvider");
9289        long ident = Binder.clearCallingIdentity();
9290        try {
9291            synchronized (this) {
9292                ContentProviderConnection conn;
9293                try {
9294                    conn = (ContentProviderConnection)connection;
9295                } catch (ClassCastException e) {
9296                    String msg ="removeContentProvider: " + connection
9297                            + " not a ContentProviderConnection";
9298                    Slog.w(TAG, msg);
9299                    throw new IllegalArgumentException(msg);
9300                }
9301                if (conn == null) {
9302                    throw new NullPointerException("connection is null");
9303                }
9304                if (decProviderCountLocked(conn, null, null, stable)) {
9305                    updateOomAdjLocked();
9306                }
9307            }
9308        } finally {
9309            Binder.restoreCallingIdentity(ident);
9310        }
9311    }
9312
9313    public void removeContentProviderExternal(String name, IBinder token) {
9314        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9315            "Do not have permission in call removeContentProviderExternal()");
9316        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9317    }
9318
9319    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9320        synchronized (this) {
9321            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9322            if(cpr == null) {
9323                //remove from mProvidersByClass
9324                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9325                return;
9326            }
9327
9328            //update content provider record entry info
9329            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9330            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9331            if (localCpr.hasExternalProcessHandles()) {
9332                if (localCpr.removeExternalProcessHandleLocked(token)) {
9333                    updateOomAdjLocked();
9334                } else {
9335                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9336                            + " with no external reference for token: "
9337                            + token + ".");
9338                }
9339            } else {
9340                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9341                        + " with no external references.");
9342            }
9343        }
9344    }
9345
9346    public final void publishContentProviders(IApplicationThread caller,
9347            List<ContentProviderHolder> providers) {
9348        if (providers == null) {
9349            return;
9350        }
9351
9352        enforceNotIsolatedCaller("publishContentProviders");
9353        synchronized (this) {
9354            final ProcessRecord r = getRecordForAppLocked(caller);
9355            if (DEBUG_MU)
9356                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9357            if (r == null) {
9358                throw new SecurityException(
9359                        "Unable to find app for caller " + caller
9360                      + " (pid=" + Binder.getCallingPid()
9361                      + ") when publishing content providers");
9362            }
9363
9364            final long origId = Binder.clearCallingIdentity();
9365
9366            final int N = providers.size();
9367            for (int i=0; i<N; i++) {
9368                ContentProviderHolder src = providers.get(i);
9369                if (src == null || src.info == null || src.provider == null) {
9370                    continue;
9371                }
9372                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9373                if (DEBUG_MU)
9374                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9375                if (dst != null) {
9376                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9377                    mProviderMap.putProviderByClass(comp, dst);
9378                    String names[] = dst.info.authority.split(";");
9379                    for (int j = 0; j < names.length; j++) {
9380                        mProviderMap.putProviderByName(names[j], dst);
9381                    }
9382
9383                    int NL = mLaunchingProviders.size();
9384                    int j;
9385                    for (j=0; j<NL; j++) {
9386                        if (mLaunchingProviders.get(j) == dst) {
9387                            mLaunchingProviders.remove(j);
9388                            j--;
9389                            NL--;
9390                        }
9391                    }
9392                    synchronized (dst) {
9393                        dst.provider = src.provider;
9394                        dst.proc = r;
9395                        dst.notifyAll();
9396                    }
9397                    updateOomAdjLocked(r);
9398                }
9399            }
9400
9401            Binder.restoreCallingIdentity(origId);
9402        }
9403    }
9404
9405    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9406        ContentProviderConnection conn;
9407        try {
9408            conn = (ContentProviderConnection)connection;
9409        } catch (ClassCastException e) {
9410            String msg ="refContentProvider: " + connection
9411                    + " not a ContentProviderConnection";
9412            Slog.w(TAG, msg);
9413            throw new IllegalArgumentException(msg);
9414        }
9415        if (conn == null) {
9416            throw new NullPointerException("connection is null");
9417        }
9418
9419        synchronized (this) {
9420            if (stable > 0) {
9421                conn.numStableIncs += stable;
9422            }
9423            stable = conn.stableCount + stable;
9424            if (stable < 0) {
9425                throw new IllegalStateException("stableCount < 0: " + stable);
9426            }
9427
9428            if (unstable > 0) {
9429                conn.numUnstableIncs += unstable;
9430            }
9431            unstable = conn.unstableCount + unstable;
9432            if (unstable < 0) {
9433                throw new IllegalStateException("unstableCount < 0: " + unstable);
9434            }
9435
9436            if ((stable+unstable) <= 0) {
9437                throw new IllegalStateException("ref counts can't go to zero here: stable="
9438                        + stable + " unstable=" + unstable);
9439            }
9440            conn.stableCount = stable;
9441            conn.unstableCount = unstable;
9442            return !conn.dead;
9443        }
9444    }
9445
9446    public void unstableProviderDied(IBinder connection) {
9447        ContentProviderConnection conn;
9448        try {
9449            conn = (ContentProviderConnection)connection;
9450        } catch (ClassCastException e) {
9451            String msg ="refContentProvider: " + connection
9452                    + " not a ContentProviderConnection";
9453            Slog.w(TAG, msg);
9454            throw new IllegalArgumentException(msg);
9455        }
9456        if (conn == null) {
9457            throw new NullPointerException("connection is null");
9458        }
9459
9460        // Safely retrieve the content provider associated with the connection.
9461        IContentProvider provider;
9462        synchronized (this) {
9463            provider = conn.provider.provider;
9464        }
9465
9466        if (provider == null) {
9467            // Um, yeah, we're way ahead of you.
9468            return;
9469        }
9470
9471        // Make sure the caller is being honest with us.
9472        if (provider.asBinder().pingBinder()) {
9473            // Er, no, still looks good to us.
9474            synchronized (this) {
9475                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9476                        + " says " + conn + " died, but we don't agree");
9477                return;
9478            }
9479        }
9480
9481        // Well look at that!  It's dead!
9482        synchronized (this) {
9483            if (conn.provider.provider != provider) {
9484                // But something changed...  good enough.
9485                return;
9486            }
9487
9488            ProcessRecord proc = conn.provider.proc;
9489            if (proc == null || proc.thread == null) {
9490                // Seems like the process is already cleaned up.
9491                return;
9492            }
9493
9494            // As far as we're concerned, this is just like receiving a
9495            // death notification...  just a bit prematurely.
9496            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9497                    + ") early provider death");
9498            final long ident = Binder.clearCallingIdentity();
9499            try {
9500                appDiedLocked(proc);
9501            } finally {
9502                Binder.restoreCallingIdentity(ident);
9503            }
9504        }
9505    }
9506
9507    @Override
9508    public void appNotRespondingViaProvider(IBinder connection) {
9509        enforceCallingPermission(
9510                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9511
9512        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9513        if (conn == null) {
9514            Slog.w(TAG, "ContentProviderConnection is null");
9515            return;
9516        }
9517
9518        final ProcessRecord host = conn.provider.proc;
9519        if (host == null) {
9520            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9521            return;
9522        }
9523
9524        final long token = Binder.clearCallingIdentity();
9525        try {
9526            appNotResponding(host, null, null, false, "ContentProvider not responding");
9527        } finally {
9528            Binder.restoreCallingIdentity(token);
9529        }
9530    }
9531
9532    public final void installSystemProviders() {
9533        List<ProviderInfo> providers;
9534        synchronized (this) {
9535            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9536            providers = generateApplicationProvidersLocked(app);
9537            if (providers != null) {
9538                for (int i=providers.size()-1; i>=0; i--) {
9539                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9540                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9541                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9542                                + ": not system .apk");
9543                        providers.remove(i);
9544                    }
9545                }
9546            }
9547        }
9548        if (providers != null) {
9549            mSystemThread.installSystemProviders(providers);
9550        }
9551
9552        mCoreSettingsObserver = new CoreSettingsObserver(this);
9553
9554        //mUsageStatsService.monitorPackages();
9555    }
9556
9557    /**
9558     * Allows apps to retrieve the MIME type of a URI.
9559     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9560     * users, then it does not need permission to access the ContentProvider.
9561     * Either, it needs cross-user uri grants.
9562     *
9563     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9564     *
9565     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9566     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9567     */
9568    public String getProviderMimeType(Uri uri, int userId) {
9569        enforceNotIsolatedCaller("getProviderMimeType");
9570        final String name = uri.getAuthority();
9571        int callingUid = Binder.getCallingUid();
9572        int callingPid = Binder.getCallingPid();
9573        long ident = 0;
9574        boolean clearedIdentity = false;
9575        userId = unsafeConvertIncomingUser(userId);
9576        if (UserHandle.getUserId(callingUid) != userId) {
9577            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9578                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9579                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9580                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9581                clearedIdentity = true;
9582                ident = Binder.clearCallingIdentity();
9583            }
9584        }
9585        ContentProviderHolder holder = null;
9586        try {
9587            holder = getContentProviderExternalUnchecked(name, null, userId);
9588            if (holder != null) {
9589                return holder.provider.getType(uri);
9590            }
9591        } catch (RemoteException e) {
9592            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9593            return null;
9594        } finally {
9595            // We need to clear the identity to call removeContentProviderExternalUnchecked
9596            if (!clearedIdentity) {
9597                ident = Binder.clearCallingIdentity();
9598            }
9599            try {
9600                if (holder != null) {
9601                    removeContentProviderExternalUnchecked(name, null, userId);
9602                }
9603            } finally {
9604                Binder.restoreCallingIdentity(ident);
9605            }
9606        }
9607
9608        return null;
9609    }
9610
9611    // =========================================================
9612    // GLOBAL MANAGEMENT
9613    // =========================================================
9614
9615    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9616            boolean isolated, int isolatedUid) {
9617        String proc = customProcess != null ? customProcess : info.processName;
9618        BatteryStatsImpl.Uid.Proc ps = null;
9619        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9620        int uid = info.uid;
9621        if (isolated) {
9622            if (isolatedUid == 0) {
9623                int userId = UserHandle.getUserId(uid);
9624                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9625                while (true) {
9626                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9627                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9628                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9629                    }
9630                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9631                    mNextIsolatedProcessUid++;
9632                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9633                        // No process for this uid, use it.
9634                        break;
9635                    }
9636                    stepsLeft--;
9637                    if (stepsLeft <= 0) {
9638                        return null;
9639                    }
9640                }
9641            } else {
9642                // Special case for startIsolatedProcess (internal only), where
9643                // the uid of the isolated process is specified by the caller.
9644                uid = isolatedUid;
9645            }
9646        }
9647        return new ProcessRecord(stats, info, proc, uid);
9648    }
9649
9650    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9651            String abiOverride) {
9652        ProcessRecord app;
9653        if (!isolated) {
9654            app = getProcessRecordLocked(info.processName, info.uid, true);
9655        } else {
9656            app = null;
9657        }
9658
9659        if (app == null) {
9660            app = newProcessRecordLocked(info, null, isolated, 0);
9661            mProcessNames.put(info.processName, app.uid, app);
9662            if (isolated) {
9663                mIsolatedProcesses.put(app.uid, app);
9664            }
9665            updateLruProcessLocked(app, false, null);
9666            updateOomAdjLocked();
9667        }
9668
9669        // This package really, really can not be stopped.
9670        try {
9671            AppGlobals.getPackageManager().setPackageStoppedState(
9672                    info.packageName, false, UserHandle.getUserId(app.uid));
9673        } catch (RemoteException e) {
9674        } catch (IllegalArgumentException e) {
9675            Slog.w(TAG, "Failed trying to unstop package "
9676                    + info.packageName + ": " + e);
9677        }
9678
9679        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9680                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9681            app.persistent = true;
9682            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9683        }
9684        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9685            mPersistentStartingProcesses.add(app);
9686            startProcessLocked(app, "added application", app.processName, abiOverride,
9687                    null /* entryPoint */, null /* entryPointArgs */);
9688        }
9689
9690        return app;
9691    }
9692
9693    public void unhandledBack() {
9694        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9695                "unhandledBack()");
9696
9697        synchronized(this) {
9698            final long origId = Binder.clearCallingIdentity();
9699            try {
9700                getFocusedStack().unhandledBackLocked();
9701            } finally {
9702                Binder.restoreCallingIdentity(origId);
9703            }
9704        }
9705    }
9706
9707    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9708        enforceNotIsolatedCaller("openContentUri");
9709        final int userId = UserHandle.getCallingUserId();
9710        String name = uri.getAuthority();
9711        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9712        ParcelFileDescriptor pfd = null;
9713        if (cph != null) {
9714            // We record the binder invoker's uid in thread-local storage before
9715            // going to the content provider to open the file.  Later, in the code
9716            // that handles all permissions checks, we look for this uid and use
9717            // that rather than the Activity Manager's own uid.  The effect is that
9718            // we do the check against the caller's permissions even though it looks
9719            // to the content provider like the Activity Manager itself is making
9720            // the request.
9721            sCallerIdentity.set(new Identity(
9722                    Binder.getCallingPid(), Binder.getCallingUid()));
9723            try {
9724                pfd = cph.provider.openFile(null, uri, "r", null);
9725            } catch (FileNotFoundException e) {
9726                // do nothing; pfd will be returned null
9727            } finally {
9728                // Ensure that whatever happens, we clean up the identity state
9729                sCallerIdentity.remove();
9730            }
9731
9732            // We've got the fd now, so we're done with the provider.
9733            removeContentProviderExternalUnchecked(name, null, userId);
9734        } else {
9735            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9736        }
9737        return pfd;
9738    }
9739
9740    // Actually is sleeping or shutting down or whatever else in the future
9741    // is an inactive state.
9742    public boolean isSleepingOrShuttingDown() {
9743        return mSleeping || mShuttingDown;
9744    }
9745
9746    public boolean isSleeping() {
9747        return mSleeping;
9748    }
9749
9750    void goingToSleep() {
9751        synchronized(this) {
9752            mWentToSleep = true;
9753            updateEventDispatchingLocked();
9754            goToSleepIfNeededLocked();
9755        }
9756    }
9757
9758    void finishRunningVoiceLocked() {
9759        if (mRunningVoice) {
9760            mRunningVoice = false;
9761            goToSleepIfNeededLocked();
9762        }
9763    }
9764
9765    void goToSleepIfNeededLocked() {
9766        if (mWentToSleep && !mRunningVoice) {
9767            if (!mSleeping) {
9768                mSleeping = true;
9769                mStackSupervisor.goingToSleepLocked();
9770
9771                // Initialize the wake times of all processes.
9772                checkExcessivePowerUsageLocked(false);
9773                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9774                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9775                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9776            }
9777        }
9778    }
9779
9780    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9781        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9782            // Never persist the home stack.
9783            return;
9784        }
9785        mTaskPersister.wakeup(task, flush);
9786    }
9787
9788    @Override
9789    public boolean shutdown(int timeout) {
9790        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9791                != PackageManager.PERMISSION_GRANTED) {
9792            throw new SecurityException("Requires permission "
9793                    + android.Manifest.permission.SHUTDOWN);
9794        }
9795
9796        boolean timedout = false;
9797
9798        synchronized(this) {
9799            mShuttingDown = true;
9800            updateEventDispatchingLocked();
9801            timedout = mStackSupervisor.shutdownLocked(timeout);
9802        }
9803
9804        mAppOpsService.shutdown();
9805        if (mUsageStatsService != null) {
9806            mUsageStatsService.prepareShutdown();
9807        }
9808        mBatteryStatsService.shutdown();
9809        synchronized (this) {
9810            mProcessStats.shutdownLocked();
9811        }
9812        notifyTaskPersisterLocked(null, true);
9813
9814        return timedout;
9815    }
9816
9817    public final void activitySlept(IBinder token) {
9818        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9819
9820        final long origId = Binder.clearCallingIdentity();
9821
9822        synchronized (this) {
9823            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9824            if (r != null) {
9825                mStackSupervisor.activitySleptLocked(r);
9826            }
9827        }
9828
9829        Binder.restoreCallingIdentity(origId);
9830    }
9831
9832    void logLockScreen(String msg) {
9833        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9834                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9835                mWentToSleep + " mSleeping=" + mSleeping);
9836    }
9837
9838    private void comeOutOfSleepIfNeededLocked() {
9839        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9840            if (mSleeping) {
9841                mSleeping = false;
9842                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9843            }
9844        }
9845    }
9846
9847    void wakingUp() {
9848        synchronized(this) {
9849            mWentToSleep = false;
9850            updateEventDispatchingLocked();
9851            comeOutOfSleepIfNeededLocked();
9852        }
9853    }
9854
9855    void startRunningVoiceLocked() {
9856        if (!mRunningVoice) {
9857            mRunningVoice = true;
9858            comeOutOfSleepIfNeededLocked();
9859        }
9860    }
9861
9862    private void updateEventDispatchingLocked() {
9863        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9864    }
9865
9866    public void setLockScreenShown(boolean shown) {
9867        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9868                != PackageManager.PERMISSION_GRANTED) {
9869            throw new SecurityException("Requires permission "
9870                    + android.Manifest.permission.DEVICE_POWER);
9871        }
9872
9873        synchronized(this) {
9874            long ident = Binder.clearCallingIdentity();
9875            try {
9876                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9877                mLockScreenShown = shown;
9878                comeOutOfSleepIfNeededLocked();
9879            } finally {
9880                Binder.restoreCallingIdentity(ident);
9881            }
9882        }
9883    }
9884
9885    @Override
9886    public void stopAppSwitches() {
9887        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9888                != PackageManager.PERMISSION_GRANTED) {
9889            throw new SecurityException("Requires permission "
9890                    + android.Manifest.permission.STOP_APP_SWITCHES);
9891        }
9892
9893        synchronized(this) {
9894            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9895                    + APP_SWITCH_DELAY_TIME;
9896            mDidAppSwitch = false;
9897            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9898            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9899            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9900        }
9901    }
9902
9903    public void resumeAppSwitches() {
9904        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9905                != PackageManager.PERMISSION_GRANTED) {
9906            throw new SecurityException("Requires permission "
9907                    + android.Manifest.permission.STOP_APP_SWITCHES);
9908        }
9909
9910        synchronized(this) {
9911            // Note that we don't execute any pending app switches... we will
9912            // let those wait until either the timeout, or the next start
9913            // activity request.
9914            mAppSwitchesAllowedTime = 0;
9915        }
9916    }
9917
9918    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9919            String name) {
9920        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9921            return true;
9922        }
9923
9924        final int perm = checkComponentPermission(
9925                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9926                callingUid, -1, true);
9927        if (perm == PackageManager.PERMISSION_GRANTED) {
9928            return true;
9929        }
9930
9931        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9932        return false;
9933    }
9934
9935    public void setDebugApp(String packageName, boolean waitForDebugger,
9936            boolean persistent) {
9937        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9938                "setDebugApp()");
9939
9940        long ident = Binder.clearCallingIdentity();
9941        try {
9942            // Note that this is not really thread safe if there are multiple
9943            // callers into it at the same time, but that's not a situation we
9944            // care about.
9945            if (persistent) {
9946                final ContentResolver resolver = mContext.getContentResolver();
9947                Settings.Global.putString(
9948                    resolver, Settings.Global.DEBUG_APP,
9949                    packageName);
9950                Settings.Global.putInt(
9951                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9952                    waitForDebugger ? 1 : 0);
9953            }
9954
9955            synchronized (this) {
9956                if (!persistent) {
9957                    mOrigDebugApp = mDebugApp;
9958                    mOrigWaitForDebugger = mWaitForDebugger;
9959                }
9960                mDebugApp = packageName;
9961                mWaitForDebugger = waitForDebugger;
9962                mDebugTransient = !persistent;
9963                if (packageName != null) {
9964                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9965                            false, UserHandle.USER_ALL, "set debug app");
9966                }
9967            }
9968        } finally {
9969            Binder.restoreCallingIdentity(ident);
9970        }
9971    }
9972
9973    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9974        synchronized (this) {
9975            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9976            if (!isDebuggable) {
9977                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9978                    throw new SecurityException("Process not debuggable: " + app.packageName);
9979                }
9980            }
9981
9982            mOpenGlTraceApp = processName;
9983        }
9984    }
9985
9986    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
9987        synchronized (this) {
9988            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9989            if (!isDebuggable) {
9990                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9991                    throw new SecurityException("Process not debuggable: " + app.packageName);
9992                }
9993            }
9994            mProfileApp = processName;
9995            mProfileFile = profilerInfo.profileFile;
9996            if (mProfileFd != null) {
9997                try {
9998                    mProfileFd.close();
9999                } catch (IOException e) {
10000                }
10001                mProfileFd = null;
10002            }
10003            mProfileFd = profilerInfo.profileFd;
10004            mSamplingInterval = profilerInfo.samplingInterval;
10005            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10006            mProfileType = 0;
10007        }
10008    }
10009
10010    @Override
10011    public void setAlwaysFinish(boolean enabled) {
10012        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10013                "setAlwaysFinish()");
10014
10015        Settings.Global.putInt(
10016                mContext.getContentResolver(),
10017                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10018
10019        synchronized (this) {
10020            mAlwaysFinishActivities = enabled;
10021        }
10022    }
10023
10024    @Override
10025    public void setActivityController(IActivityController controller) {
10026        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10027                "setActivityController()");
10028        synchronized (this) {
10029            mController = controller;
10030            Watchdog.getInstance().setActivityController(controller);
10031        }
10032    }
10033
10034    @Override
10035    public void setUserIsMonkey(boolean userIsMonkey) {
10036        synchronized (this) {
10037            synchronized (mPidsSelfLocked) {
10038                final int callingPid = Binder.getCallingPid();
10039                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10040                if (precessRecord == null) {
10041                    throw new SecurityException("Unknown process: " + callingPid);
10042                }
10043                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10044                    throw new SecurityException("Only an instrumentation process "
10045                            + "with a UiAutomation can call setUserIsMonkey");
10046                }
10047            }
10048            mUserIsMonkey = userIsMonkey;
10049        }
10050    }
10051
10052    @Override
10053    public boolean isUserAMonkey() {
10054        synchronized (this) {
10055            // If there is a controller also implies the user is a monkey.
10056            return (mUserIsMonkey || mController != null);
10057        }
10058    }
10059
10060    public void requestBugReport() {
10061        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10062        SystemProperties.set("ctl.start", "bugreport");
10063    }
10064
10065    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10066        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10067    }
10068
10069    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10070        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10071            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10072        }
10073        return KEY_DISPATCHING_TIMEOUT;
10074    }
10075
10076    @Override
10077    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10078        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10079                != PackageManager.PERMISSION_GRANTED) {
10080            throw new SecurityException("Requires permission "
10081                    + android.Manifest.permission.FILTER_EVENTS);
10082        }
10083        ProcessRecord proc;
10084        long timeout;
10085        synchronized (this) {
10086            synchronized (mPidsSelfLocked) {
10087                proc = mPidsSelfLocked.get(pid);
10088            }
10089            timeout = getInputDispatchingTimeoutLocked(proc);
10090        }
10091
10092        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10093            return -1;
10094        }
10095
10096        return timeout;
10097    }
10098
10099    /**
10100     * Handle input dispatching timeouts.
10101     * Returns whether input dispatching should be aborted or not.
10102     */
10103    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10104            final ActivityRecord activity, final ActivityRecord parent,
10105            final boolean aboveSystem, String reason) {
10106        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10107                != PackageManager.PERMISSION_GRANTED) {
10108            throw new SecurityException("Requires permission "
10109                    + android.Manifest.permission.FILTER_EVENTS);
10110        }
10111
10112        final String annotation;
10113        if (reason == null) {
10114            annotation = "Input dispatching timed out";
10115        } else {
10116            annotation = "Input dispatching timed out (" + reason + ")";
10117        }
10118
10119        if (proc != null) {
10120            synchronized (this) {
10121                if (proc.debugging) {
10122                    return false;
10123                }
10124
10125                if (mDidDexOpt) {
10126                    // Give more time since we were dexopting.
10127                    mDidDexOpt = false;
10128                    return false;
10129                }
10130
10131                if (proc.instrumentationClass != null) {
10132                    Bundle info = new Bundle();
10133                    info.putString("shortMsg", "keyDispatchingTimedOut");
10134                    info.putString("longMsg", annotation);
10135                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10136                    return true;
10137                }
10138            }
10139            mHandler.post(new Runnable() {
10140                @Override
10141                public void run() {
10142                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10143                }
10144            });
10145        }
10146
10147        return true;
10148    }
10149
10150    public Bundle getAssistContextExtras(int requestType) {
10151        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10152                "getAssistContextExtras()");
10153        PendingAssistExtras pae;
10154        Bundle extras = new Bundle();
10155        synchronized (this) {
10156            ActivityRecord activity = getFocusedStack().mResumedActivity;
10157            if (activity == null) {
10158                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10159                return null;
10160            }
10161            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10162            if (activity.app == null || activity.app.thread == null) {
10163                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10164                return extras;
10165            }
10166            if (activity.app.pid == Binder.getCallingPid()) {
10167                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10168                return extras;
10169            }
10170            pae = new PendingAssistExtras(activity);
10171            try {
10172                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10173                        requestType);
10174                mPendingAssistExtras.add(pae);
10175                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10176            } catch (RemoteException e) {
10177                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10178                return extras;
10179            }
10180        }
10181        synchronized (pae) {
10182            while (!pae.haveResult) {
10183                try {
10184                    pae.wait();
10185                } catch (InterruptedException e) {
10186                }
10187            }
10188            if (pae.result != null) {
10189                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10190            }
10191        }
10192        synchronized (this) {
10193            mPendingAssistExtras.remove(pae);
10194            mHandler.removeCallbacks(pae);
10195        }
10196        return extras;
10197    }
10198
10199    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10200        PendingAssistExtras pae = (PendingAssistExtras)token;
10201        synchronized (pae) {
10202            pae.result = extras;
10203            pae.haveResult = true;
10204            pae.notifyAll();
10205        }
10206    }
10207
10208    public void registerProcessObserver(IProcessObserver observer) {
10209        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10210                "registerProcessObserver()");
10211        synchronized (this) {
10212            mProcessObservers.register(observer);
10213        }
10214    }
10215
10216    @Override
10217    public void unregisterProcessObserver(IProcessObserver observer) {
10218        synchronized (this) {
10219            mProcessObservers.unregister(observer);
10220        }
10221    }
10222
10223    @Override
10224    public boolean convertFromTranslucent(IBinder token) {
10225        final long origId = Binder.clearCallingIdentity();
10226        try {
10227            synchronized (this) {
10228                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10229                if (r == null) {
10230                    return false;
10231                }
10232                final boolean translucentChanged = r.changeWindowTranslucency(true);
10233                if (translucentChanged) {
10234                    r.task.stack.releaseBackgroundResources();
10235                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10236                }
10237                mWindowManager.setAppFullscreen(token, true);
10238                return translucentChanged;
10239            }
10240        } finally {
10241            Binder.restoreCallingIdentity(origId);
10242        }
10243    }
10244
10245    @Override
10246    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10247        final long origId = Binder.clearCallingIdentity();
10248        try {
10249            synchronized (this) {
10250                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10251                if (r == null) {
10252                    return false;
10253                }
10254                int index = r.task.mActivities.lastIndexOf(r);
10255                if (index > 0) {
10256                    ActivityRecord under = r.task.mActivities.get(index - 1);
10257                    under.returningOptions = options;
10258                }
10259                final boolean translucentChanged = r.changeWindowTranslucency(false);
10260                if (translucentChanged) {
10261                    r.task.stack.convertToTranslucent(r);
10262                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10263                }
10264                mWindowManager.setAppFullscreen(token, false);
10265                return translucentChanged;
10266            }
10267        } finally {
10268            Binder.restoreCallingIdentity(origId);
10269        }
10270    }
10271
10272    @Override
10273    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10274        final long origId = Binder.clearCallingIdentity();
10275        try {
10276            synchronized (this) {
10277                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10278                if (r != null) {
10279                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10280                }
10281            }
10282            return false;
10283        } finally {
10284            Binder.restoreCallingIdentity(origId);
10285        }
10286    }
10287
10288    @Override
10289    public boolean isBackgroundVisibleBehind(IBinder token) {
10290        final long origId = Binder.clearCallingIdentity();
10291        try {
10292            synchronized (this) {
10293                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10294                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10295                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10296                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10297                return visible;
10298            }
10299        } finally {
10300            Binder.restoreCallingIdentity(origId);
10301        }
10302    }
10303
10304    @Override
10305    public ActivityOptions getActivityOptions(IBinder token) {
10306        final long origId = Binder.clearCallingIdentity();
10307        try {
10308            synchronized (this) {
10309                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10310                if (r != null) {
10311                    final ActivityOptions activityOptions = r.pendingOptions;
10312                    r.pendingOptions = null;
10313                    return activityOptions;
10314                }
10315                return null;
10316            }
10317        } finally {
10318            Binder.restoreCallingIdentity(origId);
10319        }
10320    }
10321
10322    @Override
10323    public void setImmersive(IBinder token, boolean immersive) {
10324        synchronized(this) {
10325            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10326            if (r == null) {
10327                throw new IllegalArgumentException();
10328            }
10329            r.immersive = immersive;
10330
10331            // update associated state if we're frontmost
10332            if (r == mFocusedActivity) {
10333                if (DEBUG_IMMERSIVE) {
10334                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10335                }
10336                applyUpdateLockStateLocked(r);
10337            }
10338        }
10339    }
10340
10341    @Override
10342    public boolean isImmersive(IBinder token) {
10343        synchronized (this) {
10344            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10345            if (r == null) {
10346                throw new IllegalArgumentException();
10347            }
10348            return r.immersive;
10349        }
10350    }
10351
10352    public boolean isTopActivityImmersive() {
10353        enforceNotIsolatedCaller("startActivity");
10354        synchronized (this) {
10355            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10356            return (r != null) ? r.immersive : false;
10357        }
10358    }
10359
10360    @Override
10361    public boolean isTopOfTask(IBinder token) {
10362        synchronized (this) {
10363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10364            if (r == null) {
10365                throw new IllegalArgumentException();
10366            }
10367            return r.task.getTopActivity() == r;
10368        }
10369    }
10370
10371    public final void enterSafeMode() {
10372        synchronized(this) {
10373            // It only makes sense to do this before the system is ready
10374            // and started launching other packages.
10375            if (!mSystemReady) {
10376                try {
10377                    AppGlobals.getPackageManager().enterSafeMode();
10378                } catch (RemoteException e) {
10379                }
10380            }
10381
10382            mSafeMode = true;
10383        }
10384    }
10385
10386    public final void showSafeModeOverlay() {
10387        View v = LayoutInflater.from(mContext).inflate(
10388                com.android.internal.R.layout.safe_mode, null);
10389        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10390        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10391        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10392        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10393        lp.gravity = Gravity.BOTTOM | Gravity.START;
10394        lp.format = v.getBackground().getOpacity();
10395        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10396                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10397        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10398        ((WindowManager)mContext.getSystemService(
10399                Context.WINDOW_SERVICE)).addView(v, lp);
10400    }
10401
10402    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10403        if (!(sender instanceof PendingIntentRecord)) {
10404            return;
10405        }
10406        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10407        synchronized (stats) {
10408            if (mBatteryStatsService.isOnBattery()) {
10409                mBatteryStatsService.enforceCallingPermission();
10410                PendingIntentRecord rec = (PendingIntentRecord)sender;
10411                int MY_UID = Binder.getCallingUid();
10412                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10413                BatteryStatsImpl.Uid.Pkg pkg =
10414                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10415                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10416                pkg.incWakeupsLocked();
10417            }
10418        }
10419    }
10420
10421    public boolean killPids(int[] pids, String pReason, boolean secure) {
10422        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10423            throw new SecurityException("killPids only available to the system");
10424        }
10425        String reason = (pReason == null) ? "Unknown" : pReason;
10426        // XXX Note: don't acquire main activity lock here, because the window
10427        // manager calls in with its locks held.
10428
10429        boolean killed = false;
10430        synchronized (mPidsSelfLocked) {
10431            int[] types = new int[pids.length];
10432            int worstType = 0;
10433            for (int i=0; i<pids.length; i++) {
10434                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10435                if (proc != null) {
10436                    int type = proc.setAdj;
10437                    types[i] = type;
10438                    if (type > worstType) {
10439                        worstType = type;
10440                    }
10441                }
10442            }
10443
10444            // If the worst oom_adj is somewhere in the cached proc LRU range,
10445            // then constrain it so we will kill all cached procs.
10446            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10447                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10448                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10449            }
10450
10451            // If this is not a secure call, don't let it kill processes that
10452            // are important.
10453            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10454                worstType = ProcessList.SERVICE_ADJ;
10455            }
10456
10457            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10458            for (int i=0; i<pids.length; i++) {
10459                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10460                if (proc == null) {
10461                    continue;
10462                }
10463                int adj = proc.setAdj;
10464                if (adj >= worstType && !proc.killedByAm) {
10465                    proc.kill(reason, true);
10466                    killed = true;
10467                }
10468            }
10469        }
10470        return killed;
10471    }
10472
10473    @Override
10474    public void killUid(int uid, String reason) {
10475        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10476            throw new SecurityException("killUid only available to the system");
10477        }
10478        synchronized (this) {
10479            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10480                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10481                    reason != null ? reason : "kill uid");
10482        }
10483    }
10484
10485    @Override
10486    public boolean killProcessesBelowForeground(String reason) {
10487        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10488            throw new SecurityException("killProcessesBelowForeground() only available to system");
10489        }
10490
10491        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10492    }
10493
10494    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10495        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10496            throw new SecurityException("killProcessesBelowAdj() only available to system");
10497        }
10498
10499        boolean killed = false;
10500        synchronized (mPidsSelfLocked) {
10501            final int size = mPidsSelfLocked.size();
10502            for (int i = 0; i < size; i++) {
10503                final int pid = mPidsSelfLocked.keyAt(i);
10504                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10505                if (proc == null) continue;
10506
10507                final int adj = proc.setAdj;
10508                if (adj > belowAdj && !proc.killedByAm) {
10509                    proc.kill(reason, true);
10510                    killed = true;
10511                }
10512            }
10513        }
10514        return killed;
10515    }
10516
10517    @Override
10518    public void hang(final IBinder who, boolean allowRestart) {
10519        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10520                != PackageManager.PERMISSION_GRANTED) {
10521            throw new SecurityException("Requires permission "
10522                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10523        }
10524
10525        final IBinder.DeathRecipient death = new DeathRecipient() {
10526            @Override
10527            public void binderDied() {
10528                synchronized (this) {
10529                    notifyAll();
10530                }
10531            }
10532        };
10533
10534        try {
10535            who.linkToDeath(death, 0);
10536        } catch (RemoteException e) {
10537            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10538            return;
10539        }
10540
10541        synchronized (this) {
10542            Watchdog.getInstance().setAllowRestart(allowRestart);
10543            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10544            synchronized (death) {
10545                while (who.isBinderAlive()) {
10546                    try {
10547                        death.wait();
10548                    } catch (InterruptedException e) {
10549                    }
10550                }
10551            }
10552            Watchdog.getInstance().setAllowRestart(true);
10553        }
10554    }
10555
10556    @Override
10557    public void restart() {
10558        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10559                != PackageManager.PERMISSION_GRANTED) {
10560            throw new SecurityException("Requires permission "
10561                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10562        }
10563
10564        Log.i(TAG, "Sending shutdown broadcast...");
10565
10566        BroadcastReceiver br = new BroadcastReceiver() {
10567            @Override public void onReceive(Context context, Intent intent) {
10568                // Now the broadcast is done, finish up the low-level shutdown.
10569                Log.i(TAG, "Shutting down activity manager...");
10570                shutdown(10000);
10571                Log.i(TAG, "Shutdown complete, restarting!");
10572                Process.killProcess(Process.myPid());
10573                System.exit(10);
10574            }
10575        };
10576
10577        // First send the high-level shut down broadcast.
10578        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10579        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10580        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10581        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10582        mContext.sendOrderedBroadcastAsUser(intent,
10583                UserHandle.ALL, null, br, mHandler, 0, null, null);
10584        */
10585        br.onReceive(mContext, intent);
10586    }
10587
10588    private long getLowRamTimeSinceIdle(long now) {
10589        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10590    }
10591
10592    @Override
10593    public void performIdleMaintenance() {
10594        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10595                != PackageManager.PERMISSION_GRANTED) {
10596            throw new SecurityException("Requires permission "
10597                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10598        }
10599
10600        synchronized (this) {
10601            final long now = SystemClock.uptimeMillis();
10602            final long timeSinceLastIdle = now - mLastIdleTime;
10603            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10604            mLastIdleTime = now;
10605            mLowRamTimeSinceLastIdle = 0;
10606            if (mLowRamStartTime != 0) {
10607                mLowRamStartTime = now;
10608            }
10609
10610            StringBuilder sb = new StringBuilder(128);
10611            sb.append("Idle maintenance over ");
10612            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10613            sb.append(" low RAM for ");
10614            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10615            Slog.i(TAG, sb.toString());
10616
10617            // If at least 1/3 of our time since the last idle period has been spent
10618            // with RAM low, then we want to kill processes.
10619            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10620
10621            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10622                ProcessRecord proc = mLruProcesses.get(i);
10623                if (proc.notCachedSinceIdle) {
10624                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10625                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10626                        if (doKilling && proc.initialIdlePss != 0
10627                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10628                            proc.kill("idle maint (pss " + proc.lastPss
10629                                    + " from " + proc.initialIdlePss + ")", true);
10630                        }
10631                    }
10632                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10633                    proc.notCachedSinceIdle = true;
10634                    proc.initialIdlePss = 0;
10635                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10636                            isSleeping(), now);
10637                }
10638            }
10639
10640            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10641            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10642        }
10643    }
10644
10645    private void retrieveSettings() {
10646        final ContentResolver resolver = mContext.getContentResolver();
10647        String debugApp = Settings.Global.getString(
10648            resolver, Settings.Global.DEBUG_APP);
10649        boolean waitForDebugger = Settings.Global.getInt(
10650            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10651        boolean alwaysFinishActivities = Settings.Global.getInt(
10652            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10653        boolean forceRtl = Settings.Global.getInt(
10654                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10655        // Transfer any global setting for forcing RTL layout, into a System Property
10656        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10657
10658        Configuration configuration = new Configuration();
10659        Settings.System.getConfiguration(resolver, configuration);
10660        if (forceRtl) {
10661            // This will take care of setting the correct layout direction flags
10662            configuration.setLayoutDirection(configuration.locale);
10663        }
10664
10665        synchronized (this) {
10666            mDebugApp = mOrigDebugApp = debugApp;
10667            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10668            mAlwaysFinishActivities = alwaysFinishActivities;
10669            // This happens before any activities are started, so we can
10670            // change mConfiguration in-place.
10671            updateConfigurationLocked(configuration, null, false, true);
10672            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10673        }
10674    }
10675
10676    public boolean testIsSystemReady() {
10677        // no need to synchronize(this) just to read & return the value
10678        return mSystemReady;
10679    }
10680
10681    private static File getCalledPreBootReceiversFile() {
10682        File dataDir = Environment.getDataDirectory();
10683        File systemDir = new File(dataDir, "system");
10684        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10685        return fname;
10686    }
10687
10688    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10689        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10690        File file = getCalledPreBootReceiversFile();
10691        FileInputStream fis = null;
10692        try {
10693            fis = new FileInputStream(file);
10694            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10695            int fvers = dis.readInt();
10696            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10697                String vers = dis.readUTF();
10698                String codename = dis.readUTF();
10699                String build = dis.readUTF();
10700                if (android.os.Build.VERSION.RELEASE.equals(vers)
10701                        && android.os.Build.VERSION.CODENAME.equals(codename)
10702                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10703                    int num = dis.readInt();
10704                    while (num > 0) {
10705                        num--;
10706                        String pkg = dis.readUTF();
10707                        String cls = dis.readUTF();
10708                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10709                    }
10710                }
10711            }
10712        } catch (FileNotFoundException e) {
10713        } catch (IOException e) {
10714            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10715        } finally {
10716            if (fis != null) {
10717                try {
10718                    fis.close();
10719                } catch (IOException e) {
10720                }
10721            }
10722        }
10723        return lastDoneReceivers;
10724    }
10725
10726    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10727        File file = getCalledPreBootReceiversFile();
10728        FileOutputStream fos = null;
10729        DataOutputStream dos = null;
10730        try {
10731            fos = new FileOutputStream(file);
10732            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10733            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10734            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10735            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10736            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10737            dos.writeInt(list.size());
10738            for (int i=0; i<list.size(); i++) {
10739                dos.writeUTF(list.get(i).getPackageName());
10740                dos.writeUTF(list.get(i).getClassName());
10741            }
10742        } catch (IOException e) {
10743            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10744            file.delete();
10745        } finally {
10746            FileUtils.sync(fos);
10747            if (dos != null) {
10748                try {
10749                    dos.close();
10750                } catch (IOException e) {
10751                    // TODO Auto-generated catch block
10752                    e.printStackTrace();
10753                }
10754            }
10755        }
10756    }
10757
10758    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10759            ArrayList<ComponentName> doneReceivers, int userId) {
10760        boolean waitingUpdate = false;
10761        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10762        List<ResolveInfo> ris = null;
10763        try {
10764            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10765                    intent, null, 0, userId);
10766        } catch (RemoteException e) {
10767        }
10768        if (ris != null) {
10769            for (int i=ris.size()-1; i>=0; i--) {
10770                if ((ris.get(i).activityInfo.applicationInfo.flags
10771                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10772                    ris.remove(i);
10773                }
10774            }
10775            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10776
10777            // For User 0, load the version number. When delivering to a new user, deliver
10778            // to all receivers.
10779            if (userId == UserHandle.USER_OWNER) {
10780                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10781                for (int i=0; i<ris.size(); i++) {
10782                    ActivityInfo ai = ris.get(i).activityInfo;
10783                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10784                    if (lastDoneReceivers.contains(comp)) {
10785                        // We already did the pre boot receiver for this app with the current
10786                        // platform version, so don't do it again...
10787                        ris.remove(i);
10788                        i--;
10789                        // ...however, do keep it as one that has been done, so we don't
10790                        // forget about it when rewriting the file of last done receivers.
10791                        doneReceivers.add(comp);
10792                    }
10793                }
10794            }
10795
10796            // If primary user, send broadcast to all available users, else just to userId
10797            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10798                    : new int[] { userId };
10799            for (int i = 0; i < ris.size(); i++) {
10800                ActivityInfo ai = ris.get(i).activityInfo;
10801                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10802                doneReceivers.add(comp);
10803                intent.setComponent(comp);
10804                for (int j=0; j<users.length; j++) {
10805                    IIntentReceiver finisher = null;
10806                    // On last receiver and user, set up a completion callback
10807                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10808                        finisher = new IIntentReceiver.Stub() {
10809                            public void performReceive(Intent intent, int resultCode,
10810                                    String data, Bundle extras, boolean ordered,
10811                                    boolean sticky, int sendingUser) {
10812                                // The raw IIntentReceiver interface is called
10813                                // with the AM lock held, so redispatch to
10814                                // execute our code without the lock.
10815                                mHandler.post(onFinishCallback);
10816                            }
10817                        };
10818                    }
10819                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10820                            + " for user " + users[j]);
10821                    broadcastIntentLocked(null, null, intent, null, finisher,
10822                            0, null, null, null, AppOpsManager.OP_NONE,
10823                            true, false, MY_PID, Process.SYSTEM_UID,
10824                            users[j]);
10825                    if (finisher != null) {
10826                        waitingUpdate = true;
10827                    }
10828                }
10829            }
10830        }
10831
10832        return waitingUpdate;
10833    }
10834
10835    public void systemReady(final Runnable goingCallback) {
10836        synchronized(this) {
10837            if (mSystemReady) {
10838                // If we're done calling all the receivers, run the next "boot phase" passed in
10839                // by the SystemServer
10840                if (goingCallback != null) {
10841                    goingCallback.run();
10842                }
10843                return;
10844            }
10845
10846            // Make sure we have the current profile info, since it is needed for
10847            // security checks.
10848            updateCurrentProfileIdsLocked();
10849
10850            if (mRecentTasks == null) {
10851                mRecentTasks = mTaskPersister.restoreTasksLocked();
10852                if (!mRecentTasks.isEmpty()) {
10853                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10854                }
10855                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10856                mTaskPersister.startPersisting();
10857            }
10858
10859            // Check to see if there are any update receivers to run.
10860            if (!mDidUpdate) {
10861                if (mWaitingUpdate) {
10862                    return;
10863                }
10864                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10865                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10866                    public void run() {
10867                        synchronized (ActivityManagerService.this) {
10868                            mDidUpdate = true;
10869                        }
10870                        writeLastDonePreBootReceivers(doneReceivers);
10871                        showBootMessage(mContext.getText(
10872                                R.string.android_upgrading_complete),
10873                                false);
10874                        systemReady(goingCallback);
10875                    }
10876                }, doneReceivers, UserHandle.USER_OWNER);
10877
10878                if (mWaitingUpdate) {
10879                    return;
10880                }
10881                mDidUpdate = true;
10882            }
10883
10884            mAppOpsService.systemReady();
10885            mSystemReady = true;
10886        }
10887
10888        ArrayList<ProcessRecord> procsToKill = null;
10889        synchronized(mPidsSelfLocked) {
10890            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10891                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10892                if (!isAllowedWhileBooting(proc.info)){
10893                    if (procsToKill == null) {
10894                        procsToKill = new ArrayList<ProcessRecord>();
10895                    }
10896                    procsToKill.add(proc);
10897                }
10898            }
10899        }
10900
10901        synchronized(this) {
10902            if (procsToKill != null) {
10903                for (int i=procsToKill.size()-1; i>=0; i--) {
10904                    ProcessRecord proc = procsToKill.get(i);
10905                    Slog.i(TAG, "Removing system update proc: " + proc);
10906                    removeProcessLocked(proc, true, false, "system update done");
10907                }
10908            }
10909
10910            // Now that we have cleaned up any update processes, we
10911            // are ready to start launching real processes and know that
10912            // we won't trample on them any more.
10913            mProcessesReady = true;
10914        }
10915
10916        Slog.i(TAG, "System now ready");
10917        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10918            SystemClock.uptimeMillis());
10919
10920        synchronized(this) {
10921            // Make sure we have no pre-ready processes sitting around.
10922
10923            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10924                ResolveInfo ri = mContext.getPackageManager()
10925                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10926                                STOCK_PM_FLAGS);
10927                CharSequence errorMsg = null;
10928                if (ri != null) {
10929                    ActivityInfo ai = ri.activityInfo;
10930                    ApplicationInfo app = ai.applicationInfo;
10931                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10932                        mTopAction = Intent.ACTION_FACTORY_TEST;
10933                        mTopData = null;
10934                        mTopComponent = new ComponentName(app.packageName,
10935                                ai.name);
10936                    } else {
10937                        errorMsg = mContext.getResources().getText(
10938                                com.android.internal.R.string.factorytest_not_system);
10939                    }
10940                } else {
10941                    errorMsg = mContext.getResources().getText(
10942                            com.android.internal.R.string.factorytest_no_action);
10943                }
10944                if (errorMsg != null) {
10945                    mTopAction = null;
10946                    mTopData = null;
10947                    mTopComponent = null;
10948                    Message msg = Message.obtain();
10949                    msg.what = SHOW_FACTORY_ERROR_MSG;
10950                    msg.getData().putCharSequence("msg", errorMsg);
10951                    mHandler.sendMessage(msg);
10952                }
10953            }
10954        }
10955
10956        retrieveSettings();
10957
10958        synchronized (this) {
10959            readGrantedUriPermissionsLocked();
10960        }
10961
10962        if (goingCallback != null) goingCallback.run();
10963
10964        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10965                Integer.toString(mCurrentUserId), mCurrentUserId);
10966        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10967                Integer.toString(mCurrentUserId), mCurrentUserId);
10968        mSystemServiceManager.startUser(mCurrentUserId);
10969
10970        synchronized (this) {
10971            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10972                try {
10973                    List apps = AppGlobals.getPackageManager().
10974                        getPersistentApplications(STOCK_PM_FLAGS);
10975                    if (apps != null) {
10976                        int N = apps.size();
10977                        int i;
10978                        for (i=0; i<N; i++) {
10979                            ApplicationInfo info
10980                                = (ApplicationInfo)apps.get(i);
10981                            if (info != null &&
10982                                    !info.packageName.equals("android")) {
10983                                addAppLocked(info, false, null /* ABI override */);
10984                            }
10985                        }
10986                    }
10987                } catch (RemoteException ex) {
10988                    // pm is in same process, this will never happen.
10989                }
10990            }
10991
10992            // Start up initial activity.
10993            mBooting = true;
10994
10995            try {
10996                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10997                    Message msg = Message.obtain();
10998                    msg.what = SHOW_UID_ERROR_MSG;
10999                    mHandler.sendMessage(msg);
11000                }
11001            } catch (RemoteException e) {
11002            }
11003
11004            long ident = Binder.clearCallingIdentity();
11005            try {
11006                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11007                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11008                        | Intent.FLAG_RECEIVER_FOREGROUND);
11009                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11010                broadcastIntentLocked(null, null, intent,
11011                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11012                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11013                intent = new Intent(Intent.ACTION_USER_STARTING);
11014                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11015                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11016                broadcastIntentLocked(null, null, intent,
11017                        null, new IIntentReceiver.Stub() {
11018                            @Override
11019                            public void performReceive(Intent intent, int resultCode, String data,
11020                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11021                                    throws RemoteException {
11022                            }
11023                        }, 0, null, null,
11024                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11025                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11026            } catch (Throwable t) {
11027                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11028            } finally {
11029                Binder.restoreCallingIdentity(ident);
11030            }
11031            mStackSupervisor.resumeTopActivitiesLocked();
11032            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11033        }
11034    }
11035
11036    private boolean makeAppCrashingLocked(ProcessRecord app,
11037            String shortMsg, String longMsg, String stackTrace) {
11038        app.crashing = true;
11039        app.crashingReport = generateProcessError(app,
11040                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11041        startAppProblemLocked(app);
11042        app.stopFreezingAllLocked();
11043        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11044    }
11045
11046    private void makeAppNotRespondingLocked(ProcessRecord app,
11047            String activity, String shortMsg, String longMsg) {
11048        app.notResponding = true;
11049        app.notRespondingReport = generateProcessError(app,
11050                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11051                activity, shortMsg, longMsg, null);
11052        startAppProblemLocked(app);
11053        app.stopFreezingAllLocked();
11054    }
11055
11056    /**
11057     * Generate a process error record, suitable for attachment to a ProcessRecord.
11058     *
11059     * @param app The ProcessRecord in which the error occurred.
11060     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11061     *                      ActivityManager.AppErrorStateInfo
11062     * @param activity The activity associated with the crash, if known.
11063     * @param shortMsg Short message describing the crash.
11064     * @param longMsg Long message describing the crash.
11065     * @param stackTrace Full crash stack trace, may be null.
11066     *
11067     * @return Returns a fully-formed AppErrorStateInfo record.
11068     */
11069    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11070            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11071        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11072
11073        report.condition = condition;
11074        report.processName = app.processName;
11075        report.pid = app.pid;
11076        report.uid = app.info.uid;
11077        report.tag = activity;
11078        report.shortMsg = shortMsg;
11079        report.longMsg = longMsg;
11080        report.stackTrace = stackTrace;
11081
11082        return report;
11083    }
11084
11085    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11086        synchronized (this) {
11087            app.crashing = false;
11088            app.crashingReport = null;
11089            app.notResponding = false;
11090            app.notRespondingReport = null;
11091            if (app.anrDialog == fromDialog) {
11092                app.anrDialog = null;
11093            }
11094            if (app.waitDialog == fromDialog) {
11095                app.waitDialog = null;
11096            }
11097            if (app.pid > 0 && app.pid != MY_PID) {
11098                handleAppCrashLocked(app, null, null, null);
11099                app.kill("user request after error", true);
11100            }
11101        }
11102    }
11103
11104    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11105            String stackTrace) {
11106        long now = SystemClock.uptimeMillis();
11107
11108        Long crashTime;
11109        if (!app.isolated) {
11110            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11111        } else {
11112            crashTime = null;
11113        }
11114        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11115            // This process loses!
11116            Slog.w(TAG, "Process " + app.info.processName
11117                    + " has crashed too many times: killing!");
11118            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11119                    app.userId, app.info.processName, app.uid);
11120            mStackSupervisor.handleAppCrashLocked(app);
11121            if (!app.persistent) {
11122                // We don't want to start this process again until the user
11123                // explicitly does so...  but for persistent process, we really
11124                // need to keep it running.  If a persistent process is actually
11125                // repeatedly crashing, then badness for everyone.
11126                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11127                        app.info.processName);
11128                if (!app.isolated) {
11129                    // XXX We don't have a way to mark isolated processes
11130                    // as bad, since they don't have a peristent identity.
11131                    mBadProcesses.put(app.info.processName, app.uid,
11132                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11133                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11134                }
11135                app.bad = true;
11136                app.removed = true;
11137                // Don't let services in this process be restarted and potentially
11138                // annoy the user repeatedly.  Unless it is persistent, since those
11139                // processes run critical code.
11140                removeProcessLocked(app, false, false, "crash");
11141                mStackSupervisor.resumeTopActivitiesLocked();
11142                return false;
11143            }
11144            mStackSupervisor.resumeTopActivitiesLocked();
11145        } else {
11146            mStackSupervisor.finishTopRunningActivityLocked(app);
11147        }
11148
11149        // Bump up the crash count of any services currently running in the proc.
11150        for (int i=app.services.size()-1; i>=0; i--) {
11151            // Any services running in the application need to be placed
11152            // back in the pending list.
11153            ServiceRecord sr = app.services.valueAt(i);
11154            sr.crashCount++;
11155        }
11156
11157        // If the crashing process is what we consider to be the "home process" and it has been
11158        // replaced by a third-party app, clear the package preferred activities from packages
11159        // with a home activity running in the process to prevent a repeatedly crashing app
11160        // from blocking the user to manually clear the list.
11161        final ArrayList<ActivityRecord> activities = app.activities;
11162        if (app == mHomeProcess && activities.size() > 0
11163                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11164            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11165                final ActivityRecord r = activities.get(activityNdx);
11166                if (r.isHomeActivity()) {
11167                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11168                    try {
11169                        ActivityThread.getPackageManager()
11170                                .clearPackagePreferredActivities(r.packageName);
11171                    } catch (RemoteException c) {
11172                        // pm is in same process, this will never happen.
11173                    }
11174                }
11175            }
11176        }
11177
11178        if (!app.isolated) {
11179            // XXX Can't keep track of crash times for isolated processes,
11180            // because they don't have a perisistent identity.
11181            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11182        }
11183
11184        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11185        return true;
11186    }
11187
11188    void startAppProblemLocked(ProcessRecord app) {
11189        // If this app is not running under the current user, then we
11190        // can't give it a report button because that would require
11191        // launching the report UI under a different user.
11192        app.errorReportReceiver = null;
11193
11194        for (int userId : mCurrentProfileIds) {
11195            if (app.userId == userId) {
11196                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11197                        mContext, app.info.packageName, app.info.flags);
11198            }
11199        }
11200        skipCurrentReceiverLocked(app);
11201    }
11202
11203    void skipCurrentReceiverLocked(ProcessRecord app) {
11204        for (BroadcastQueue queue : mBroadcastQueues) {
11205            queue.skipCurrentReceiverLocked(app);
11206        }
11207    }
11208
11209    /**
11210     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11211     * The application process will exit immediately after this call returns.
11212     * @param app object of the crashing app, null for the system server
11213     * @param crashInfo describing the exception
11214     */
11215    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11216        ProcessRecord r = findAppProcess(app, "Crash");
11217        final String processName = app == null ? "system_server"
11218                : (r == null ? "unknown" : r.processName);
11219
11220        handleApplicationCrashInner("crash", r, processName, crashInfo);
11221    }
11222
11223    /* Native crash reporting uses this inner version because it needs to be somewhat
11224     * decoupled from the AM-managed cleanup lifecycle
11225     */
11226    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11227            ApplicationErrorReport.CrashInfo crashInfo) {
11228        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11229                UserHandle.getUserId(Binder.getCallingUid()), processName,
11230                r == null ? -1 : r.info.flags,
11231                crashInfo.exceptionClassName,
11232                crashInfo.exceptionMessage,
11233                crashInfo.throwFileName,
11234                crashInfo.throwLineNumber);
11235
11236        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11237
11238        crashApplication(r, crashInfo);
11239    }
11240
11241    public void handleApplicationStrictModeViolation(
11242            IBinder app,
11243            int violationMask,
11244            StrictMode.ViolationInfo info) {
11245        ProcessRecord r = findAppProcess(app, "StrictMode");
11246        if (r == null) {
11247            return;
11248        }
11249
11250        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11251            Integer stackFingerprint = info.hashCode();
11252            boolean logIt = true;
11253            synchronized (mAlreadyLoggedViolatedStacks) {
11254                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11255                    logIt = false;
11256                    // TODO: sub-sample into EventLog for these, with
11257                    // the info.durationMillis?  Then we'd get
11258                    // the relative pain numbers, without logging all
11259                    // the stack traces repeatedly.  We'd want to do
11260                    // likewise in the client code, which also does
11261                    // dup suppression, before the Binder call.
11262                } else {
11263                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11264                        mAlreadyLoggedViolatedStacks.clear();
11265                    }
11266                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11267                }
11268            }
11269            if (logIt) {
11270                logStrictModeViolationToDropBox(r, info);
11271            }
11272        }
11273
11274        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11275            AppErrorResult result = new AppErrorResult();
11276            synchronized (this) {
11277                final long origId = Binder.clearCallingIdentity();
11278
11279                Message msg = Message.obtain();
11280                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11281                HashMap<String, Object> data = new HashMap<String, Object>();
11282                data.put("result", result);
11283                data.put("app", r);
11284                data.put("violationMask", violationMask);
11285                data.put("info", info);
11286                msg.obj = data;
11287                mHandler.sendMessage(msg);
11288
11289                Binder.restoreCallingIdentity(origId);
11290            }
11291            int res = result.get();
11292            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11293        }
11294    }
11295
11296    // Depending on the policy in effect, there could be a bunch of
11297    // these in quick succession so we try to batch these together to
11298    // minimize disk writes, number of dropbox entries, and maximize
11299    // compression, by having more fewer, larger records.
11300    private void logStrictModeViolationToDropBox(
11301            ProcessRecord process,
11302            StrictMode.ViolationInfo info) {
11303        if (info == null) {
11304            return;
11305        }
11306        final boolean isSystemApp = process == null ||
11307                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11308                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11309        final String processName = process == null ? "unknown" : process.processName;
11310        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11311        final DropBoxManager dbox = (DropBoxManager)
11312                mContext.getSystemService(Context.DROPBOX_SERVICE);
11313
11314        // Exit early if the dropbox isn't configured to accept this report type.
11315        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11316
11317        boolean bufferWasEmpty;
11318        boolean needsFlush;
11319        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11320        synchronized (sb) {
11321            bufferWasEmpty = sb.length() == 0;
11322            appendDropBoxProcessHeaders(process, processName, sb);
11323            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11324            sb.append("System-App: ").append(isSystemApp).append("\n");
11325            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11326            if (info.violationNumThisLoop != 0) {
11327                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11328            }
11329            if (info.numAnimationsRunning != 0) {
11330                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11331            }
11332            if (info.broadcastIntentAction != null) {
11333                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11334            }
11335            if (info.durationMillis != -1) {
11336                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11337            }
11338            if (info.numInstances != -1) {
11339                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11340            }
11341            if (info.tags != null) {
11342                for (String tag : info.tags) {
11343                    sb.append("Span-Tag: ").append(tag).append("\n");
11344                }
11345            }
11346            sb.append("\n");
11347            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11348                sb.append(info.crashInfo.stackTrace);
11349            }
11350            sb.append("\n");
11351
11352            // Only buffer up to ~64k.  Various logging bits truncate
11353            // things at 128k.
11354            needsFlush = (sb.length() > 64 * 1024);
11355        }
11356
11357        // Flush immediately if the buffer's grown too large, or this
11358        // is a non-system app.  Non-system apps are isolated with a
11359        // different tag & policy and not batched.
11360        //
11361        // Batching is useful during internal testing with
11362        // StrictMode settings turned up high.  Without batching,
11363        // thousands of separate files could be created on boot.
11364        if (!isSystemApp || needsFlush) {
11365            new Thread("Error dump: " + dropboxTag) {
11366                @Override
11367                public void run() {
11368                    String report;
11369                    synchronized (sb) {
11370                        report = sb.toString();
11371                        sb.delete(0, sb.length());
11372                        sb.trimToSize();
11373                    }
11374                    if (report.length() != 0) {
11375                        dbox.addText(dropboxTag, report);
11376                    }
11377                }
11378            }.start();
11379            return;
11380        }
11381
11382        // System app batching:
11383        if (!bufferWasEmpty) {
11384            // An existing dropbox-writing thread is outstanding, so
11385            // we don't need to start it up.  The existing thread will
11386            // catch the buffer appends we just did.
11387            return;
11388        }
11389
11390        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11391        // (After this point, we shouldn't access AMS internal data structures.)
11392        new Thread("Error dump: " + dropboxTag) {
11393            @Override
11394            public void run() {
11395                // 5 second sleep to let stacks arrive and be batched together
11396                try {
11397                    Thread.sleep(5000);  // 5 seconds
11398                } catch (InterruptedException e) {}
11399
11400                String errorReport;
11401                synchronized (mStrictModeBuffer) {
11402                    errorReport = mStrictModeBuffer.toString();
11403                    if (errorReport.length() == 0) {
11404                        return;
11405                    }
11406                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11407                    mStrictModeBuffer.trimToSize();
11408                }
11409                dbox.addText(dropboxTag, errorReport);
11410            }
11411        }.start();
11412    }
11413
11414    /**
11415     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11416     * @param app object of the crashing app, null for the system server
11417     * @param tag reported by the caller
11418     * @param system whether this wtf is coming from the system
11419     * @param crashInfo describing the context of the error
11420     * @return true if the process should exit immediately (WTF is fatal)
11421     */
11422    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11423            final ApplicationErrorReport.CrashInfo crashInfo) {
11424        final ProcessRecord r = findAppProcess(app, "WTF");
11425        final String processName = app == null ? "system_server"
11426                : (r == null ? "unknown" : r.processName);
11427
11428        EventLog.writeEvent(EventLogTags.AM_WTF,
11429                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11430                processName,
11431                r == null ? -1 : r.info.flags,
11432                tag, crashInfo.exceptionMessage);
11433
11434        if (system) {
11435            // If this is coming from the system, we could very well have low-level
11436            // system locks held, so we want to do this all asynchronously.  And we
11437            // never want this to become fatal, so there is that too.
11438            mHandler.post(new Runnable() {
11439                @Override public void run() {
11440                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11441                            crashInfo);
11442                }
11443            });
11444            return false;
11445        }
11446
11447        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11448
11449        if (r != null && r.pid != Process.myPid() &&
11450                Settings.Global.getInt(mContext.getContentResolver(),
11451                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11452            crashApplication(r, crashInfo);
11453            return true;
11454        } else {
11455            return false;
11456        }
11457    }
11458
11459    /**
11460     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11461     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11462     */
11463    private ProcessRecord findAppProcess(IBinder app, String reason) {
11464        if (app == null) {
11465            return null;
11466        }
11467
11468        synchronized (this) {
11469            final int NP = mProcessNames.getMap().size();
11470            for (int ip=0; ip<NP; ip++) {
11471                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11472                final int NA = apps.size();
11473                for (int ia=0; ia<NA; ia++) {
11474                    ProcessRecord p = apps.valueAt(ia);
11475                    if (p.thread != null && p.thread.asBinder() == app) {
11476                        return p;
11477                    }
11478                }
11479            }
11480
11481            Slog.w(TAG, "Can't find mystery application for " + reason
11482                    + " from pid=" + Binder.getCallingPid()
11483                    + " uid=" + Binder.getCallingUid() + ": " + app);
11484            return null;
11485        }
11486    }
11487
11488    /**
11489     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11490     * to append various headers to the dropbox log text.
11491     */
11492    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11493            StringBuilder sb) {
11494        // Watchdog thread ends up invoking this function (with
11495        // a null ProcessRecord) to add the stack file to dropbox.
11496        // Do not acquire a lock on this (am) in such cases, as it
11497        // could cause a potential deadlock, if and when watchdog
11498        // is invoked due to unavailability of lock on am and it
11499        // would prevent watchdog from killing system_server.
11500        if (process == null) {
11501            sb.append("Process: ").append(processName).append("\n");
11502            return;
11503        }
11504        // Note: ProcessRecord 'process' is guarded by the service
11505        // instance.  (notably process.pkgList, which could otherwise change
11506        // concurrently during execution of this method)
11507        synchronized (this) {
11508            sb.append("Process: ").append(processName).append("\n");
11509            int flags = process.info.flags;
11510            IPackageManager pm = AppGlobals.getPackageManager();
11511            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11512            for (int ip=0; ip<process.pkgList.size(); ip++) {
11513                String pkg = process.pkgList.keyAt(ip);
11514                sb.append("Package: ").append(pkg);
11515                try {
11516                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11517                    if (pi != null) {
11518                        sb.append(" v").append(pi.versionCode);
11519                        if (pi.versionName != null) {
11520                            sb.append(" (").append(pi.versionName).append(")");
11521                        }
11522                    }
11523                } catch (RemoteException e) {
11524                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11525                }
11526                sb.append("\n");
11527            }
11528        }
11529    }
11530
11531    private static String processClass(ProcessRecord process) {
11532        if (process == null || process.pid == MY_PID) {
11533            return "system_server";
11534        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11535            return "system_app";
11536        } else {
11537            return "data_app";
11538        }
11539    }
11540
11541    /**
11542     * Write a description of an error (crash, WTF, ANR) to the drop box.
11543     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11544     * @param process which caused the error, null means the system server
11545     * @param activity which triggered the error, null if unknown
11546     * @param parent activity related to the error, null if unknown
11547     * @param subject line related to the error, null if absent
11548     * @param report in long form describing the error, null if absent
11549     * @param logFile to include in the report, null if none
11550     * @param crashInfo giving an application stack trace, null if absent
11551     */
11552    public void addErrorToDropBox(String eventType,
11553            ProcessRecord process, String processName, ActivityRecord activity,
11554            ActivityRecord parent, String subject,
11555            final String report, final File logFile,
11556            final ApplicationErrorReport.CrashInfo crashInfo) {
11557        // NOTE -- this must never acquire the ActivityManagerService lock,
11558        // otherwise the watchdog may be prevented from resetting the system.
11559
11560        final String dropboxTag = processClass(process) + "_" + eventType;
11561        final DropBoxManager dbox = (DropBoxManager)
11562                mContext.getSystemService(Context.DROPBOX_SERVICE);
11563
11564        // Exit early if the dropbox isn't configured to accept this report type.
11565        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11566
11567        final StringBuilder sb = new StringBuilder(1024);
11568        appendDropBoxProcessHeaders(process, processName, sb);
11569        if (activity != null) {
11570            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11571        }
11572        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11573            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11574        }
11575        if (parent != null && parent != activity) {
11576            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11577        }
11578        if (subject != null) {
11579            sb.append("Subject: ").append(subject).append("\n");
11580        }
11581        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11582        if (Debug.isDebuggerConnected()) {
11583            sb.append("Debugger: Connected\n");
11584        }
11585        sb.append("\n");
11586
11587        // Do the rest in a worker thread to avoid blocking the caller on I/O
11588        // (After this point, we shouldn't access AMS internal data structures.)
11589        Thread worker = new Thread("Error dump: " + dropboxTag) {
11590            @Override
11591            public void run() {
11592                if (report != null) {
11593                    sb.append(report);
11594                }
11595                if (logFile != null) {
11596                    try {
11597                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11598                                    "\n\n[[TRUNCATED]]"));
11599                    } catch (IOException e) {
11600                        Slog.e(TAG, "Error reading " + logFile, e);
11601                    }
11602                }
11603                if (crashInfo != null && crashInfo.stackTrace != null) {
11604                    sb.append(crashInfo.stackTrace);
11605                }
11606
11607                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11608                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11609                if (lines > 0) {
11610                    sb.append("\n");
11611
11612                    // Merge several logcat streams, and take the last N lines
11613                    InputStreamReader input = null;
11614                    try {
11615                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11616                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11617                                "-b", "crash",
11618                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11619
11620                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11621                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11622                        input = new InputStreamReader(logcat.getInputStream());
11623
11624                        int num;
11625                        char[] buf = new char[8192];
11626                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11627                    } catch (IOException e) {
11628                        Slog.e(TAG, "Error running logcat", e);
11629                    } finally {
11630                        if (input != null) try { input.close(); } catch (IOException e) {}
11631                    }
11632                }
11633
11634                dbox.addText(dropboxTag, sb.toString());
11635            }
11636        };
11637
11638        if (process == null) {
11639            // If process is null, we are being called from some internal code
11640            // and may be about to die -- run this synchronously.
11641            worker.run();
11642        } else {
11643            worker.start();
11644        }
11645    }
11646
11647    /**
11648     * Bring up the "unexpected error" dialog box for a crashing app.
11649     * Deal with edge cases (intercepts from instrumented applications,
11650     * ActivityController, error intent receivers, that sort of thing).
11651     * @param r the application crashing
11652     * @param crashInfo describing the failure
11653     */
11654    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11655        long timeMillis = System.currentTimeMillis();
11656        String shortMsg = crashInfo.exceptionClassName;
11657        String longMsg = crashInfo.exceptionMessage;
11658        String stackTrace = crashInfo.stackTrace;
11659        if (shortMsg != null && longMsg != null) {
11660            longMsg = shortMsg + ": " + longMsg;
11661        } else if (shortMsg != null) {
11662            longMsg = shortMsg;
11663        }
11664
11665        AppErrorResult result = new AppErrorResult();
11666        synchronized (this) {
11667            if (mController != null) {
11668                try {
11669                    String name = r != null ? r.processName : null;
11670                    int pid = r != null ? r.pid : Binder.getCallingPid();
11671                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11672                    if (!mController.appCrashed(name, pid,
11673                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11674                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11675                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11676                            Slog.w(TAG, "Skip killing native crashed app " + name
11677                                    + "(" + pid + ") during testing");
11678                        } else {
11679                            Slog.w(TAG, "Force-killing crashed app " + name
11680                                    + " at watcher's request");
11681                            if (r != null) {
11682                                r.kill("crash", true);
11683                            } else {
11684                                // Huh.
11685                                Process.killProcess(pid);
11686                                Process.killProcessGroup(uid, pid);
11687                            }
11688                        }
11689                        return;
11690                    }
11691                } catch (RemoteException e) {
11692                    mController = null;
11693                    Watchdog.getInstance().setActivityController(null);
11694                }
11695            }
11696
11697            final long origId = Binder.clearCallingIdentity();
11698
11699            // If this process is running instrumentation, finish it.
11700            if (r != null && r.instrumentationClass != null) {
11701                Slog.w(TAG, "Error in app " + r.processName
11702                      + " running instrumentation " + r.instrumentationClass + ":");
11703                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11704                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11705                Bundle info = new Bundle();
11706                info.putString("shortMsg", shortMsg);
11707                info.putString("longMsg", longMsg);
11708                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11709                Binder.restoreCallingIdentity(origId);
11710                return;
11711            }
11712
11713            // If we can't identify the process or it's already exceeded its crash quota,
11714            // quit right away without showing a crash dialog.
11715            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11716                Binder.restoreCallingIdentity(origId);
11717                return;
11718            }
11719
11720            Message msg = Message.obtain();
11721            msg.what = SHOW_ERROR_MSG;
11722            HashMap data = new HashMap();
11723            data.put("result", result);
11724            data.put("app", r);
11725            msg.obj = data;
11726            mHandler.sendMessage(msg);
11727
11728            Binder.restoreCallingIdentity(origId);
11729        }
11730
11731        int res = result.get();
11732
11733        Intent appErrorIntent = null;
11734        synchronized (this) {
11735            if (r != null && !r.isolated) {
11736                // XXX Can't keep track of crash time for isolated processes,
11737                // since they don't have a persistent identity.
11738                mProcessCrashTimes.put(r.info.processName, r.uid,
11739                        SystemClock.uptimeMillis());
11740            }
11741            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11742                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11743            }
11744        }
11745
11746        if (appErrorIntent != null) {
11747            try {
11748                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11749            } catch (ActivityNotFoundException e) {
11750                Slog.w(TAG, "bug report receiver dissappeared", e);
11751            }
11752        }
11753    }
11754
11755    Intent createAppErrorIntentLocked(ProcessRecord r,
11756            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11757        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11758        if (report == null) {
11759            return null;
11760        }
11761        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11762        result.setComponent(r.errorReportReceiver);
11763        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11764        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11765        return result;
11766    }
11767
11768    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11769            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11770        if (r.errorReportReceiver == null) {
11771            return null;
11772        }
11773
11774        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11775            return null;
11776        }
11777
11778        ApplicationErrorReport report = new ApplicationErrorReport();
11779        report.packageName = r.info.packageName;
11780        report.installerPackageName = r.errorReportReceiver.getPackageName();
11781        report.processName = r.processName;
11782        report.time = timeMillis;
11783        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11784
11785        if (r.crashing || r.forceCrashReport) {
11786            report.type = ApplicationErrorReport.TYPE_CRASH;
11787            report.crashInfo = crashInfo;
11788        } else if (r.notResponding) {
11789            report.type = ApplicationErrorReport.TYPE_ANR;
11790            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11791
11792            report.anrInfo.activity = r.notRespondingReport.tag;
11793            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11794            report.anrInfo.info = r.notRespondingReport.longMsg;
11795        }
11796
11797        return report;
11798    }
11799
11800    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11801        enforceNotIsolatedCaller("getProcessesInErrorState");
11802        // assume our apps are happy - lazy create the list
11803        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11804
11805        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11806                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11807        int userId = UserHandle.getUserId(Binder.getCallingUid());
11808
11809        synchronized (this) {
11810
11811            // iterate across all processes
11812            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11813                ProcessRecord app = mLruProcesses.get(i);
11814                if (!allUsers && app.userId != userId) {
11815                    continue;
11816                }
11817                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11818                    // This one's in trouble, so we'll generate a report for it
11819                    // crashes are higher priority (in case there's a crash *and* an anr)
11820                    ActivityManager.ProcessErrorStateInfo report = null;
11821                    if (app.crashing) {
11822                        report = app.crashingReport;
11823                    } else if (app.notResponding) {
11824                        report = app.notRespondingReport;
11825                    }
11826
11827                    if (report != null) {
11828                        if (errList == null) {
11829                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11830                        }
11831                        errList.add(report);
11832                    } else {
11833                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11834                                " crashing = " + app.crashing +
11835                                " notResponding = " + app.notResponding);
11836                    }
11837                }
11838            }
11839        }
11840
11841        return errList;
11842    }
11843
11844    static int procStateToImportance(int procState, int memAdj,
11845            ActivityManager.RunningAppProcessInfo currApp) {
11846        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11847        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11848            currApp.lru = memAdj;
11849        } else {
11850            currApp.lru = 0;
11851        }
11852        return imp;
11853    }
11854
11855    private void fillInProcMemInfo(ProcessRecord app,
11856            ActivityManager.RunningAppProcessInfo outInfo) {
11857        outInfo.pid = app.pid;
11858        outInfo.uid = app.info.uid;
11859        if (mHeavyWeightProcess == app) {
11860            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11861        }
11862        if (app.persistent) {
11863            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11864        }
11865        if (app.activities.size() > 0) {
11866            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11867        }
11868        outInfo.lastTrimLevel = app.trimMemoryLevel;
11869        int adj = app.curAdj;
11870        int procState = app.curProcState;
11871        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11872        outInfo.importanceReasonCode = app.adjTypeCode;
11873        outInfo.processState = app.curProcState;
11874    }
11875
11876    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11877        enforceNotIsolatedCaller("getRunningAppProcesses");
11878        // Lazy instantiation of list
11879        List<ActivityManager.RunningAppProcessInfo> runList = null;
11880        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11881                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11882        int userId = UserHandle.getUserId(Binder.getCallingUid());
11883        synchronized (this) {
11884            // Iterate across all processes
11885            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11886                ProcessRecord app = mLruProcesses.get(i);
11887                if (!allUsers && app.userId != userId) {
11888                    continue;
11889                }
11890                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11891                    // Generate process state info for running application
11892                    ActivityManager.RunningAppProcessInfo currApp =
11893                        new ActivityManager.RunningAppProcessInfo(app.processName,
11894                                app.pid, app.getPackageList());
11895                    fillInProcMemInfo(app, currApp);
11896                    if (app.adjSource instanceof ProcessRecord) {
11897                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11898                        currApp.importanceReasonImportance =
11899                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11900                                        app.adjSourceProcState);
11901                    } else if (app.adjSource instanceof ActivityRecord) {
11902                        ActivityRecord r = (ActivityRecord)app.adjSource;
11903                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11904                    }
11905                    if (app.adjTarget instanceof ComponentName) {
11906                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11907                    }
11908                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11909                    //        + " lru=" + currApp.lru);
11910                    if (runList == null) {
11911                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11912                    }
11913                    runList.add(currApp);
11914                }
11915            }
11916        }
11917        return runList;
11918    }
11919
11920    public List<ApplicationInfo> getRunningExternalApplications() {
11921        enforceNotIsolatedCaller("getRunningExternalApplications");
11922        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11923        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11924        if (runningApps != null && runningApps.size() > 0) {
11925            Set<String> extList = new HashSet<String>();
11926            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11927                if (app.pkgList != null) {
11928                    for (String pkg : app.pkgList) {
11929                        extList.add(pkg);
11930                    }
11931                }
11932            }
11933            IPackageManager pm = AppGlobals.getPackageManager();
11934            for (String pkg : extList) {
11935                try {
11936                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11937                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11938                        retList.add(info);
11939                    }
11940                } catch (RemoteException e) {
11941                }
11942            }
11943        }
11944        return retList;
11945    }
11946
11947    @Override
11948    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11949        enforceNotIsolatedCaller("getMyMemoryState");
11950        synchronized (this) {
11951            ProcessRecord proc;
11952            synchronized (mPidsSelfLocked) {
11953                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11954            }
11955            fillInProcMemInfo(proc, outInfo);
11956        }
11957    }
11958
11959    @Override
11960    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11961        if (checkCallingPermission(android.Manifest.permission.DUMP)
11962                != PackageManager.PERMISSION_GRANTED) {
11963            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11964                    + Binder.getCallingPid()
11965                    + ", uid=" + Binder.getCallingUid()
11966                    + " without permission "
11967                    + android.Manifest.permission.DUMP);
11968            return;
11969        }
11970
11971        boolean dumpAll = false;
11972        boolean dumpClient = false;
11973        String dumpPackage = null;
11974
11975        int opti = 0;
11976        while (opti < args.length) {
11977            String opt = args[opti];
11978            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11979                break;
11980            }
11981            opti++;
11982            if ("-a".equals(opt)) {
11983                dumpAll = true;
11984            } else if ("-c".equals(opt)) {
11985                dumpClient = true;
11986            } else if ("-h".equals(opt)) {
11987                pw.println("Activity manager dump options:");
11988                pw.println("  [-a] [-c] [-h] [cmd] ...");
11989                pw.println("  cmd may be one of:");
11990                pw.println("    a[ctivities]: activity stack state");
11991                pw.println("    r[recents]: recent activities state");
11992                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11993                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11994                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11995                pw.println("    o[om]: out of memory management");
11996                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11997                pw.println("    provider [COMP_SPEC]: provider client-side state");
11998                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11999                pw.println("    service [COMP_SPEC]: service client-side state");
12000                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12001                pw.println("    all: dump all activities");
12002                pw.println("    top: dump the top activity");
12003                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12004                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12005                pw.println("    a partial substring in a component name, a");
12006                pw.println("    hex object identifier.");
12007                pw.println("  -a: include all available server state.");
12008                pw.println("  -c: include client state.");
12009                return;
12010            } else {
12011                pw.println("Unknown argument: " + opt + "; use -h for help");
12012            }
12013        }
12014
12015        long origId = Binder.clearCallingIdentity();
12016        boolean more = false;
12017        // Is the caller requesting to dump a particular piece of data?
12018        if (opti < args.length) {
12019            String cmd = args[opti];
12020            opti++;
12021            if ("activities".equals(cmd) || "a".equals(cmd)) {
12022                synchronized (this) {
12023                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12024                }
12025            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12026                synchronized (this) {
12027                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12028                }
12029            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12030                String[] newArgs;
12031                String name;
12032                if (opti >= args.length) {
12033                    name = null;
12034                    newArgs = EMPTY_STRING_ARRAY;
12035                } else {
12036                    name = args[opti];
12037                    opti++;
12038                    newArgs = new String[args.length - opti];
12039                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12040                            args.length - opti);
12041                }
12042                synchronized (this) {
12043                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12044                }
12045            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12046                String[] newArgs;
12047                String name;
12048                if (opti >= args.length) {
12049                    name = null;
12050                    newArgs = EMPTY_STRING_ARRAY;
12051                } else {
12052                    name = args[opti];
12053                    opti++;
12054                    newArgs = new String[args.length - opti];
12055                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12056                            args.length - opti);
12057                }
12058                synchronized (this) {
12059                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12060                }
12061            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12062                String[] newArgs;
12063                String name;
12064                if (opti >= args.length) {
12065                    name = null;
12066                    newArgs = EMPTY_STRING_ARRAY;
12067                } else {
12068                    name = args[opti];
12069                    opti++;
12070                    newArgs = new String[args.length - opti];
12071                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12072                            args.length - opti);
12073                }
12074                synchronized (this) {
12075                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12076                }
12077            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12078                synchronized (this) {
12079                    dumpOomLocked(fd, pw, args, opti, true);
12080                }
12081            } else if ("provider".equals(cmd)) {
12082                String[] newArgs;
12083                String name;
12084                if (opti >= args.length) {
12085                    name = null;
12086                    newArgs = EMPTY_STRING_ARRAY;
12087                } else {
12088                    name = args[opti];
12089                    opti++;
12090                    newArgs = new String[args.length - opti];
12091                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12092                }
12093                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12094                    pw.println("No providers match: " + name);
12095                    pw.println("Use -h for help.");
12096                }
12097            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12098                synchronized (this) {
12099                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12100                }
12101            } else if ("service".equals(cmd)) {
12102                String[] newArgs;
12103                String name;
12104                if (opti >= args.length) {
12105                    name = null;
12106                    newArgs = EMPTY_STRING_ARRAY;
12107                } else {
12108                    name = args[opti];
12109                    opti++;
12110                    newArgs = new String[args.length - opti];
12111                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12112                            args.length - opti);
12113                }
12114                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12115                    pw.println("No services match: " + name);
12116                    pw.println("Use -h for help.");
12117                }
12118            } else if ("package".equals(cmd)) {
12119                String[] newArgs;
12120                if (opti >= args.length) {
12121                    pw.println("package: no package name specified");
12122                    pw.println("Use -h for help.");
12123                } else {
12124                    dumpPackage = args[opti];
12125                    opti++;
12126                    newArgs = new String[args.length - opti];
12127                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12128                            args.length - opti);
12129                    args = newArgs;
12130                    opti = 0;
12131                    more = true;
12132                }
12133            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12134                synchronized (this) {
12135                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12136                }
12137            } else {
12138                // Dumping a single activity?
12139                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12140                    pw.println("Bad activity command, or no activities match: " + cmd);
12141                    pw.println("Use -h for help.");
12142                }
12143            }
12144            if (!more) {
12145                Binder.restoreCallingIdentity(origId);
12146                return;
12147            }
12148        }
12149
12150        // No piece of data specified, dump everything.
12151        synchronized (this) {
12152            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12153            pw.println();
12154            if (dumpAll) {
12155                pw.println("-------------------------------------------------------------------------------");
12156            }
12157            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12158            pw.println();
12159            if (dumpAll) {
12160                pw.println("-------------------------------------------------------------------------------");
12161            }
12162            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12163            pw.println();
12164            if (dumpAll) {
12165                pw.println("-------------------------------------------------------------------------------");
12166            }
12167            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12168            pw.println();
12169            if (dumpAll) {
12170                pw.println("-------------------------------------------------------------------------------");
12171            }
12172            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12173            pw.println();
12174            if (dumpAll) {
12175                pw.println("-------------------------------------------------------------------------------");
12176            }
12177            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12178            pw.println();
12179            if (dumpAll) {
12180                pw.println("-------------------------------------------------------------------------------");
12181            }
12182            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12183        }
12184        Binder.restoreCallingIdentity(origId);
12185    }
12186
12187    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12188            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12189        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12190
12191        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12192                dumpPackage);
12193        boolean needSep = printedAnything;
12194
12195        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12196                dumpPackage, needSep, "  mFocusedActivity: ");
12197        if (printed) {
12198            printedAnything = true;
12199            needSep = false;
12200        }
12201
12202        if (dumpPackage == null) {
12203            if (needSep) {
12204                pw.println();
12205            }
12206            needSep = true;
12207            printedAnything = true;
12208            mStackSupervisor.dump(pw, "  ");
12209        }
12210
12211        if (!printedAnything) {
12212            pw.println("  (nothing)");
12213        }
12214    }
12215
12216    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12217            int opti, boolean dumpAll, String dumpPackage) {
12218        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12219
12220        boolean printedAnything = false;
12221
12222        if (mRecentTasks.size() > 0) {
12223            boolean printedHeader = false;
12224
12225            final int N = mRecentTasks.size();
12226            for (int i=0; i<N; i++) {
12227                TaskRecord tr = mRecentTasks.get(i);
12228                if (dumpPackage != null) {
12229                    if (tr.realActivity == null ||
12230                            !dumpPackage.equals(tr.realActivity)) {
12231                        continue;
12232                    }
12233                }
12234                if (!printedHeader) {
12235                    pw.println("  Recent tasks:");
12236                    printedHeader = true;
12237                    printedAnything = true;
12238                }
12239                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12240                        pw.println(tr);
12241                if (dumpAll) {
12242                    mRecentTasks.get(i).dump(pw, "    ");
12243                }
12244            }
12245        }
12246
12247        if (!printedAnything) {
12248            pw.println("  (nothing)");
12249        }
12250    }
12251
12252    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12253            int opti, boolean dumpAll, String dumpPackage) {
12254        boolean needSep = false;
12255        boolean printedAnything = false;
12256        int numPers = 0;
12257
12258        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12259
12260        if (dumpAll) {
12261            final int NP = mProcessNames.getMap().size();
12262            for (int ip=0; ip<NP; ip++) {
12263                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12264                final int NA = procs.size();
12265                for (int ia=0; ia<NA; ia++) {
12266                    ProcessRecord r = procs.valueAt(ia);
12267                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12268                        continue;
12269                    }
12270                    if (!needSep) {
12271                        pw.println("  All known processes:");
12272                        needSep = true;
12273                        printedAnything = true;
12274                    }
12275                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12276                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12277                        pw.print(" "); pw.println(r);
12278                    r.dump(pw, "    ");
12279                    if (r.persistent) {
12280                        numPers++;
12281                    }
12282                }
12283            }
12284        }
12285
12286        if (mIsolatedProcesses.size() > 0) {
12287            boolean printed = false;
12288            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12289                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12290                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12291                    continue;
12292                }
12293                if (!printed) {
12294                    if (needSep) {
12295                        pw.println();
12296                    }
12297                    pw.println("  Isolated process list (sorted by uid):");
12298                    printedAnything = true;
12299                    printed = true;
12300                    needSep = true;
12301                }
12302                pw.println(String.format("%sIsolated #%2d: %s",
12303                        "    ", i, r.toString()));
12304            }
12305        }
12306
12307        if (mLruProcesses.size() > 0) {
12308            if (needSep) {
12309                pw.println();
12310            }
12311            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12312                    pw.print(" total, non-act at ");
12313                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12314                    pw.print(", non-svc at ");
12315                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12316                    pw.println("):");
12317            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12318            needSep = true;
12319            printedAnything = true;
12320        }
12321
12322        if (dumpAll || dumpPackage != null) {
12323            synchronized (mPidsSelfLocked) {
12324                boolean printed = false;
12325                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12326                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12327                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12328                        continue;
12329                    }
12330                    if (!printed) {
12331                        if (needSep) pw.println();
12332                        needSep = true;
12333                        pw.println("  PID mappings:");
12334                        printed = true;
12335                        printedAnything = true;
12336                    }
12337                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12338                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12339                }
12340            }
12341        }
12342
12343        if (mForegroundProcesses.size() > 0) {
12344            synchronized (mPidsSelfLocked) {
12345                boolean printed = false;
12346                for (int i=0; i<mForegroundProcesses.size(); i++) {
12347                    ProcessRecord r = mPidsSelfLocked.get(
12348                            mForegroundProcesses.valueAt(i).pid);
12349                    if (dumpPackage != null && (r == null
12350                            || !r.pkgList.containsKey(dumpPackage))) {
12351                        continue;
12352                    }
12353                    if (!printed) {
12354                        if (needSep) pw.println();
12355                        needSep = true;
12356                        pw.println("  Foreground Processes:");
12357                        printed = true;
12358                        printedAnything = true;
12359                    }
12360                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12361                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12362                }
12363            }
12364        }
12365
12366        if (mPersistentStartingProcesses.size() > 0) {
12367            if (needSep) pw.println();
12368            needSep = true;
12369            printedAnything = true;
12370            pw.println("  Persisent processes that are starting:");
12371            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12372                    "Starting Norm", "Restarting PERS", dumpPackage);
12373        }
12374
12375        if (mRemovedProcesses.size() > 0) {
12376            if (needSep) pw.println();
12377            needSep = true;
12378            printedAnything = true;
12379            pw.println("  Processes that are being removed:");
12380            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12381                    "Removed Norm", "Removed PERS", dumpPackage);
12382        }
12383
12384        if (mProcessesOnHold.size() > 0) {
12385            if (needSep) pw.println();
12386            needSep = true;
12387            printedAnything = true;
12388            pw.println("  Processes that are on old until the system is ready:");
12389            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12390                    "OnHold Norm", "OnHold PERS", dumpPackage);
12391        }
12392
12393        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12394
12395        if (mProcessCrashTimes.getMap().size() > 0) {
12396            boolean printed = false;
12397            long now = SystemClock.uptimeMillis();
12398            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12399            final int NP = pmap.size();
12400            for (int ip=0; ip<NP; ip++) {
12401                String pname = pmap.keyAt(ip);
12402                SparseArray<Long> uids = pmap.valueAt(ip);
12403                final int N = uids.size();
12404                for (int i=0; i<N; i++) {
12405                    int puid = uids.keyAt(i);
12406                    ProcessRecord r = mProcessNames.get(pname, puid);
12407                    if (dumpPackage != null && (r == null
12408                            || !r.pkgList.containsKey(dumpPackage))) {
12409                        continue;
12410                    }
12411                    if (!printed) {
12412                        if (needSep) pw.println();
12413                        needSep = true;
12414                        pw.println("  Time since processes crashed:");
12415                        printed = true;
12416                        printedAnything = true;
12417                    }
12418                    pw.print("    Process "); pw.print(pname);
12419                            pw.print(" uid "); pw.print(puid);
12420                            pw.print(": last crashed ");
12421                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12422                            pw.println(" ago");
12423                }
12424            }
12425        }
12426
12427        if (mBadProcesses.getMap().size() > 0) {
12428            boolean printed = false;
12429            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12430            final int NP = pmap.size();
12431            for (int ip=0; ip<NP; ip++) {
12432                String pname = pmap.keyAt(ip);
12433                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12434                final int N = uids.size();
12435                for (int i=0; i<N; i++) {
12436                    int puid = uids.keyAt(i);
12437                    ProcessRecord r = mProcessNames.get(pname, puid);
12438                    if (dumpPackage != null && (r == null
12439                            || !r.pkgList.containsKey(dumpPackage))) {
12440                        continue;
12441                    }
12442                    if (!printed) {
12443                        if (needSep) pw.println();
12444                        needSep = true;
12445                        pw.println("  Bad processes:");
12446                        printedAnything = true;
12447                    }
12448                    BadProcessInfo info = uids.valueAt(i);
12449                    pw.print("    Bad process "); pw.print(pname);
12450                            pw.print(" uid "); pw.print(puid);
12451                            pw.print(": crashed at time "); pw.println(info.time);
12452                    if (info.shortMsg != null) {
12453                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12454                    }
12455                    if (info.longMsg != null) {
12456                        pw.print("      Long msg: "); pw.println(info.longMsg);
12457                    }
12458                    if (info.stack != null) {
12459                        pw.println("      Stack:");
12460                        int lastPos = 0;
12461                        for (int pos=0; pos<info.stack.length(); pos++) {
12462                            if (info.stack.charAt(pos) == '\n') {
12463                                pw.print("        ");
12464                                pw.write(info.stack, lastPos, pos-lastPos);
12465                                pw.println();
12466                                lastPos = pos+1;
12467                            }
12468                        }
12469                        if (lastPos < info.stack.length()) {
12470                            pw.print("        ");
12471                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12472                            pw.println();
12473                        }
12474                    }
12475                }
12476            }
12477        }
12478
12479        if (dumpPackage == null) {
12480            pw.println();
12481            needSep = false;
12482            pw.println("  mStartedUsers:");
12483            for (int i=0; i<mStartedUsers.size(); i++) {
12484                UserStartedState uss = mStartedUsers.valueAt(i);
12485                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12486                        pw.print(": "); uss.dump("", pw);
12487            }
12488            pw.print("  mStartedUserArray: [");
12489            for (int i=0; i<mStartedUserArray.length; i++) {
12490                if (i > 0) pw.print(", ");
12491                pw.print(mStartedUserArray[i]);
12492            }
12493            pw.println("]");
12494            pw.print("  mUserLru: [");
12495            for (int i=0; i<mUserLru.size(); i++) {
12496                if (i > 0) pw.print(", ");
12497                pw.print(mUserLru.get(i));
12498            }
12499            pw.println("]");
12500            if (dumpAll) {
12501                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12502            }
12503            synchronized (mUserProfileGroupIdsSelfLocked) {
12504                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12505                    pw.println("  mUserProfileGroupIds:");
12506                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12507                        pw.print("    User #");
12508                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12509                        pw.print(" -> profile #");
12510                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12511                    }
12512                }
12513            }
12514        }
12515        if (mHomeProcess != null && (dumpPackage == null
12516                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12517            if (needSep) {
12518                pw.println();
12519                needSep = false;
12520            }
12521            pw.println("  mHomeProcess: " + mHomeProcess);
12522        }
12523        if (mPreviousProcess != null && (dumpPackage == null
12524                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12525            if (needSep) {
12526                pw.println();
12527                needSep = false;
12528            }
12529            pw.println("  mPreviousProcess: " + mPreviousProcess);
12530        }
12531        if (dumpAll) {
12532            StringBuilder sb = new StringBuilder(128);
12533            sb.append("  mPreviousProcessVisibleTime: ");
12534            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12535            pw.println(sb);
12536        }
12537        if (mHeavyWeightProcess != null && (dumpPackage == null
12538                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12539            if (needSep) {
12540                pw.println();
12541                needSep = false;
12542            }
12543            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12544        }
12545        if (dumpPackage == null) {
12546            pw.println("  mConfiguration: " + mConfiguration);
12547        }
12548        if (dumpAll) {
12549            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12550            if (mCompatModePackages.getPackages().size() > 0) {
12551                boolean printed = false;
12552                for (Map.Entry<String, Integer> entry
12553                        : mCompatModePackages.getPackages().entrySet()) {
12554                    String pkg = entry.getKey();
12555                    int mode = entry.getValue();
12556                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12557                        continue;
12558                    }
12559                    if (!printed) {
12560                        pw.println("  mScreenCompatPackages:");
12561                        printed = true;
12562                    }
12563                    pw.print("    "); pw.print(pkg); pw.print(": ");
12564                            pw.print(mode); pw.println();
12565                }
12566            }
12567        }
12568        if (dumpPackage == null) {
12569            if (mSleeping || mWentToSleep || mLockScreenShown) {
12570                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12571                        + " mLockScreenShown " + mLockScreenShown);
12572            }
12573            if (mShuttingDown || mRunningVoice) {
12574                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12575            }
12576        }
12577        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12578                || mOrigWaitForDebugger) {
12579            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12580                    || dumpPackage.equals(mOrigDebugApp)) {
12581                if (needSep) {
12582                    pw.println();
12583                    needSep = false;
12584                }
12585                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12586                        + " mDebugTransient=" + mDebugTransient
12587                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12588            }
12589        }
12590        if (mOpenGlTraceApp != null) {
12591            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12592                if (needSep) {
12593                    pw.println();
12594                    needSep = false;
12595                }
12596                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12597            }
12598        }
12599        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12600                || mProfileFd != null) {
12601            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12602                if (needSep) {
12603                    pw.println();
12604                    needSep = false;
12605                }
12606                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12607                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12608                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12609                        + mAutoStopProfiler);
12610                pw.println("  mProfileType=" + mProfileType);
12611            }
12612        }
12613        if (dumpPackage == null) {
12614            if (mAlwaysFinishActivities || mController != null) {
12615                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12616                        + " mController=" + mController);
12617            }
12618            if (dumpAll) {
12619                pw.println("  Total persistent processes: " + numPers);
12620                pw.println("  mProcessesReady=" + mProcessesReady
12621                        + " mSystemReady=" + mSystemReady);
12622                pw.println("  mBooting=" + mBooting
12623                        + " mBooted=" + mBooted
12624                        + " mFactoryTest=" + mFactoryTest);
12625                pw.print("  mLastPowerCheckRealtime=");
12626                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12627                        pw.println("");
12628                pw.print("  mLastPowerCheckUptime=");
12629                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12630                        pw.println("");
12631                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12632                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12633                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12634                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12635                        + " (" + mLruProcesses.size() + " total)"
12636                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12637                        + " mNumServiceProcs=" + mNumServiceProcs
12638                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12639                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12640                        + " mLastMemoryLevel" + mLastMemoryLevel
12641                        + " mLastNumProcesses" + mLastNumProcesses);
12642                long now = SystemClock.uptimeMillis();
12643                pw.print("  mLastIdleTime=");
12644                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12645                        pw.print(" mLowRamSinceLastIdle=");
12646                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12647                        pw.println();
12648            }
12649        }
12650
12651        if (!printedAnything) {
12652            pw.println("  (nothing)");
12653        }
12654    }
12655
12656    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12657            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12658        if (mProcessesToGc.size() > 0) {
12659            boolean printed = false;
12660            long now = SystemClock.uptimeMillis();
12661            for (int i=0; i<mProcessesToGc.size(); i++) {
12662                ProcessRecord proc = mProcessesToGc.get(i);
12663                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12664                    continue;
12665                }
12666                if (!printed) {
12667                    if (needSep) pw.println();
12668                    needSep = true;
12669                    pw.println("  Processes that are waiting to GC:");
12670                    printed = true;
12671                }
12672                pw.print("    Process "); pw.println(proc);
12673                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12674                        pw.print(", last gced=");
12675                        pw.print(now-proc.lastRequestedGc);
12676                        pw.print(" ms ago, last lowMem=");
12677                        pw.print(now-proc.lastLowMemory);
12678                        pw.println(" ms ago");
12679
12680            }
12681        }
12682        return needSep;
12683    }
12684
12685    void printOomLevel(PrintWriter pw, String name, int adj) {
12686        pw.print("    ");
12687        if (adj >= 0) {
12688            pw.print(' ');
12689            if (adj < 10) pw.print(' ');
12690        } else {
12691            if (adj > -10) pw.print(' ');
12692        }
12693        pw.print(adj);
12694        pw.print(": ");
12695        pw.print(name);
12696        pw.print(" (");
12697        pw.print(mProcessList.getMemLevel(adj)/1024);
12698        pw.println(" kB)");
12699    }
12700
12701    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12702            int opti, boolean dumpAll) {
12703        boolean needSep = false;
12704
12705        if (mLruProcesses.size() > 0) {
12706            if (needSep) pw.println();
12707            needSep = true;
12708            pw.println("  OOM levels:");
12709            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12710            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12711            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12712            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12713            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12714            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12715            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12716            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12717            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12718            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12719            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12720            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12721            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12722
12723            if (needSep) pw.println();
12724            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12725                    pw.print(" total, non-act at ");
12726                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12727                    pw.print(", non-svc at ");
12728                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12729                    pw.println("):");
12730            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12731            needSep = true;
12732        }
12733
12734        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12735
12736        pw.println();
12737        pw.println("  mHomeProcess: " + mHomeProcess);
12738        pw.println("  mPreviousProcess: " + mPreviousProcess);
12739        if (mHeavyWeightProcess != null) {
12740            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12741        }
12742
12743        return true;
12744    }
12745
12746    /**
12747     * There are three ways to call this:
12748     *  - no provider specified: dump all the providers
12749     *  - a flattened component name that matched an existing provider was specified as the
12750     *    first arg: dump that one provider
12751     *  - the first arg isn't the flattened component name of an existing provider:
12752     *    dump all providers whose component contains the first arg as a substring
12753     */
12754    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12755            int opti, boolean dumpAll) {
12756        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12757    }
12758
12759    static class ItemMatcher {
12760        ArrayList<ComponentName> components;
12761        ArrayList<String> strings;
12762        ArrayList<Integer> objects;
12763        boolean all;
12764
12765        ItemMatcher() {
12766            all = true;
12767        }
12768
12769        void build(String name) {
12770            ComponentName componentName = ComponentName.unflattenFromString(name);
12771            if (componentName != null) {
12772                if (components == null) {
12773                    components = new ArrayList<ComponentName>();
12774                }
12775                components.add(componentName);
12776                all = false;
12777            } else {
12778                int objectId = 0;
12779                // Not a '/' separated full component name; maybe an object ID?
12780                try {
12781                    objectId = Integer.parseInt(name, 16);
12782                    if (objects == null) {
12783                        objects = new ArrayList<Integer>();
12784                    }
12785                    objects.add(objectId);
12786                    all = false;
12787                } catch (RuntimeException e) {
12788                    // Not an integer; just do string match.
12789                    if (strings == null) {
12790                        strings = new ArrayList<String>();
12791                    }
12792                    strings.add(name);
12793                    all = false;
12794                }
12795            }
12796        }
12797
12798        int build(String[] args, int opti) {
12799            for (; opti<args.length; opti++) {
12800                String name = args[opti];
12801                if ("--".equals(name)) {
12802                    return opti+1;
12803                }
12804                build(name);
12805            }
12806            return opti;
12807        }
12808
12809        boolean match(Object object, ComponentName comp) {
12810            if (all) {
12811                return true;
12812            }
12813            if (components != null) {
12814                for (int i=0; i<components.size(); i++) {
12815                    if (components.get(i).equals(comp)) {
12816                        return true;
12817                    }
12818                }
12819            }
12820            if (objects != null) {
12821                for (int i=0; i<objects.size(); i++) {
12822                    if (System.identityHashCode(object) == objects.get(i)) {
12823                        return true;
12824                    }
12825                }
12826            }
12827            if (strings != null) {
12828                String flat = comp.flattenToString();
12829                for (int i=0; i<strings.size(); i++) {
12830                    if (flat.contains(strings.get(i))) {
12831                        return true;
12832                    }
12833                }
12834            }
12835            return false;
12836        }
12837    }
12838
12839    /**
12840     * There are three things that cmd can be:
12841     *  - a flattened component name that matches an existing activity
12842     *  - the cmd arg isn't the flattened component name of an existing activity:
12843     *    dump all activity whose component contains the cmd as a substring
12844     *  - A hex number of the ActivityRecord object instance.
12845     */
12846    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12847            int opti, boolean dumpAll) {
12848        ArrayList<ActivityRecord> activities;
12849
12850        synchronized (this) {
12851            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12852        }
12853
12854        if (activities.size() <= 0) {
12855            return false;
12856        }
12857
12858        String[] newArgs = new String[args.length - opti];
12859        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12860
12861        TaskRecord lastTask = null;
12862        boolean needSep = false;
12863        for (int i=activities.size()-1; i>=0; i--) {
12864            ActivityRecord r = activities.get(i);
12865            if (needSep) {
12866                pw.println();
12867            }
12868            needSep = true;
12869            synchronized (this) {
12870                if (lastTask != r.task) {
12871                    lastTask = r.task;
12872                    pw.print("TASK "); pw.print(lastTask.affinity);
12873                            pw.print(" id="); pw.println(lastTask.taskId);
12874                    if (dumpAll) {
12875                        lastTask.dump(pw, "  ");
12876                    }
12877                }
12878            }
12879            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12880        }
12881        return true;
12882    }
12883
12884    /**
12885     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12886     * there is a thread associated with the activity.
12887     */
12888    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12889            final ActivityRecord r, String[] args, boolean dumpAll) {
12890        String innerPrefix = prefix + "  ";
12891        synchronized (this) {
12892            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12893                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12894                    pw.print(" pid=");
12895                    if (r.app != null) pw.println(r.app.pid);
12896                    else pw.println("(not running)");
12897            if (dumpAll) {
12898                r.dump(pw, innerPrefix);
12899            }
12900        }
12901        if (r.app != null && r.app.thread != null) {
12902            // flush anything that is already in the PrintWriter since the thread is going
12903            // to write to the file descriptor directly
12904            pw.flush();
12905            try {
12906                TransferPipe tp = new TransferPipe();
12907                try {
12908                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12909                            r.appToken, innerPrefix, args);
12910                    tp.go(fd);
12911                } finally {
12912                    tp.kill();
12913                }
12914            } catch (IOException e) {
12915                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12916            } catch (RemoteException e) {
12917                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12918            }
12919        }
12920    }
12921
12922    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12923            int opti, boolean dumpAll, String dumpPackage) {
12924        boolean needSep = false;
12925        boolean onlyHistory = false;
12926        boolean printedAnything = false;
12927
12928        if ("history".equals(dumpPackage)) {
12929            if (opti < args.length && "-s".equals(args[opti])) {
12930                dumpAll = false;
12931            }
12932            onlyHistory = true;
12933            dumpPackage = null;
12934        }
12935
12936        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12937        if (!onlyHistory && dumpAll) {
12938            if (mRegisteredReceivers.size() > 0) {
12939                boolean printed = false;
12940                Iterator it = mRegisteredReceivers.values().iterator();
12941                while (it.hasNext()) {
12942                    ReceiverList r = (ReceiverList)it.next();
12943                    if (dumpPackage != null && (r.app == null ||
12944                            !dumpPackage.equals(r.app.info.packageName))) {
12945                        continue;
12946                    }
12947                    if (!printed) {
12948                        pw.println("  Registered Receivers:");
12949                        needSep = true;
12950                        printed = true;
12951                        printedAnything = true;
12952                    }
12953                    pw.print("  * "); pw.println(r);
12954                    r.dump(pw, "    ");
12955                }
12956            }
12957
12958            if (mReceiverResolver.dump(pw, needSep ?
12959                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12960                    "    ", dumpPackage, false)) {
12961                needSep = true;
12962                printedAnything = true;
12963            }
12964        }
12965
12966        for (BroadcastQueue q : mBroadcastQueues) {
12967            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12968            printedAnything |= needSep;
12969        }
12970
12971        needSep = true;
12972
12973        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12974            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12975                if (needSep) {
12976                    pw.println();
12977                }
12978                needSep = true;
12979                printedAnything = true;
12980                pw.print("  Sticky broadcasts for user ");
12981                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12982                StringBuilder sb = new StringBuilder(128);
12983                for (Map.Entry<String, ArrayList<Intent>> ent
12984                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12985                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12986                    if (dumpAll) {
12987                        pw.println(":");
12988                        ArrayList<Intent> intents = ent.getValue();
12989                        final int N = intents.size();
12990                        for (int i=0; i<N; i++) {
12991                            sb.setLength(0);
12992                            sb.append("    Intent: ");
12993                            intents.get(i).toShortString(sb, false, true, false, false);
12994                            pw.println(sb.toString());
12995                            Bundle bundle = intents.get(i).getExtras();
12996                            if (bundle != null) {
12997                                pw.print("      ");
12998                                pw.println(bundle.toString());
12999                            }
13000                        }
13001                    } else {
13002                        pw.println("");
13003                    }
13004                }
13005            }
13006        }
13007
13008        if (!onlyHistory && dumpAll) {
13009            pw.println();
13010            for (BroadcastQueue queue : mBroadcastQueues) {
13011                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13012                        + queue.mBroadcastsScheduled);
13013            }
13014            pw.println("  mHandler:");
13015            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13016            needSep = true;
13017            printedAnything = true;
13018        }
13019
13020        if (!printedAnything) {
13021            pw.println("  (nothing)");
13022        }
13023    }
13024
13025    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13026            int opti, boolean dumpAll, String dumpPackage) {
13027        boolean needSep;
13028        boolean printedAnything = false;
13029
13030        ItemMatcher matcher = new ItemMatcher();
13031        matcher.build(args, opti);
13032
13033        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13034
13035        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13036        printedAnything |= needSep;
13037
13038        if (mLaunchingProviders.size() > 0) {
13039            boolean printed = false;
13040            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13041                ContentProviderRecord r = mLaunchingProviders.get(i);
13042                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13043                    continue;
13044                }
13045                if (!printed) {
13046                    if (needSep) pw.println();
13047                    needSep = true;
13048                    pw.println("  Launching content providers:");
13049                    printed = true;
13050                    printedAnything = true;
13051                }
13052                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13053                        pw.println(r);
13054            }
13055        }
13056
13057        if (mGrantedUriPermissions.size() > 0) {
13058            boolean printed = false;
13059            int dumpUid = -2;
13060            if (dumpPackage != null) {
13061                try {
13062                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13063                } catch (NameNotFoundException e) {
13064                    dumpUid = -1;
13065                }
13066            }
13067            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13068                int uid = mGrantedUriPermissions.keyAt(i);
13069                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13070                    continue;
13071                }
13072                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13073                if (!printed) {
13074                    if (needSep) pw.println();
13075                    needSep = true;
13076                    pw.println("  Granted Uri Permissions:");
13077                    printed = true;
13078                    printedAnything = true;
13079                }
13080                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13081                for (UriPermission perm : perms.values()) {
13082                    pw.print("    "); pw.println(perm);
13083                    if (dumpAll) {
13084                        perm.dump(pw, "      ");
13085                    }
13086                }
13087            }
13088        }
13089
13090        if (!printedAnything) {
13091            pw.println("  (nothing)");
13092        }
13093    }
13094
13095    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13096            int opti, boolean dumpAll, String dumpPackage) {
13097        boolean printed = false;
13098
13099        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13100
13101        if (mIntentSenderRecords.size() > 0) {
13102            Iterator<WeakReference<PendingIntentRecord>> it
13103                    = mIntentSenderRecords.values().iterator();
13104            while (it.hasNext()) {
13105                WeakReference<PendingIntentRecord> ref = it.next();
13106                PendingIntentRecord rec = ref != null ? ref.get(): null;
13107                if (dumpPackage != null && (rec == null
13108                        || !dumpPackage.equals(rec.key.packageName))) {
13109                    continue;
13110                }
13111                printed = true;
13112                if (rec != null) {
13113                    pw.print("  * "); pw.println(rec);
13114                    if (dumpAll) {
13115                        rec.dump(pw, "    ");
13116                    }
13117                } else {
13118                    pw.print("  * "); pw.println(ref);
13119                }
13120            }
13121        }
13122
13123        if (!printed) {
13124            pw.println("  (nothing)");
13125        }
13126    }
13127
13128    private static final int dumpProcessList(PrintWriter pw,
13129            ActivityManagerService service, List list,
13130            String prefix, String normalLabel, String persistentLabel,
13131            String dumpPackage) {
13132        int numPers = 0;
13133        final int N = list.size()-1;
13134        for (int i=N; i>=0; i--) {
13135            ProcessRecord r = (ProcessRecord)list.get(i);
13136            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13137                continue;
13138            }
13139            pw.println(String.format("%s%s #%2d: %s",
13140                    prefix, (r.persistent ? persistentLabel : normalLabel),
13141                    i, r.toString()));
13142            if (r.persistent) {
13143                numPers++;
13144            }
13145        }
13146        return numPers;
13147    }
13148
13149    private static final boolean dumpProcessOomList(PrintWriter pw,
13150            ActivityManagerService service, List<ProcessRecord> origList,
13151            String prefix, String normalLabel, String persistentLabel,
13152            boolean inclDetails, String dumpPackage) {
13153
13154        ArrayList<Pair<ProcessRecord, Integer>> list
13155                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13156        for (int i=0; i<origList.size(); i++) {
13157            ProcessRecord r = origList.get(i);
13158            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13159                continue;
13160            }
13161            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13162        }
13163
13164        if (list.size() <= 0) {
13165            return false;
13166        }
13167
13168        Comparator<Pair<ProcessRecord, Integer>> comparator
13169                = new Comparator<Pair<ProcessRecord, Integer>>() {
13170            @Override
13171            public int compare(Pair<ProcessRecord, Integer> object1,
13172                    Pair<ProcessRecord, Integer> object2) {
13173                if (object1.first.setAdj != object2.first.setAdj) {
13174                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13175                }
13176                if (object1.second.intValue() != object2.second.intValue()) {
13177                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13178                }
13179                return 0;
13180            }
13181        };
13182
13183        Collections.sort(list, comparator);
13184
13185        final long curRealtime = SystemClock.elapsedRealtime();
13186        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13187        final long curUptime = SystemClock.uptimeMillis();
13188        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13189
13190        for (int i=list.size()-1; i>=0; i--) {
13191            ProcessRecord r = list.get(i).first;
13192            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13193            char schedGroup;
13194            switch (r.setSchedGroup) {
13195                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13196                    schedGroup = 'B';
13197                    break;
13198                case Process.THREAD_GROUP_DEFAULT:
13199                    schedGroup = 'F';
13200                    break;
13201                default:
13202                    schedGroup = '?';
13203                    break;
13204            }
13205            char foreground;
13206            if (r.foregroundActivities) {
13207                foreground = 'A';
13208            } else if (r.foregroundServices) {
13209                foreground = 'S';
13210            } else {
13211                foreground = ' ';
13212            }
13213            String procState = ProcessList.makeProcStateString(r.curProcState);
13214            pw.print(prefix);
13215            pw.print(r.persistent ? persistentLabel : normalLabel);
13216            pw.print(" #");
13217            int num = (origList.size()-1)-list.get(i).second;
13218            if (num < 10) pw.print(' ');
13219            pw.print(num);
13220            pw.print(": ");
13221            pw.print(oomAdj);
13222            pw.print(' ');
13223            pw.print(schedGroup);
13224            pw.print('/');
13225            pw.print(foreground);
13226            pw.print('/');
13227            pw.print(procState);
13228            pw.print(" trm:");
13229            if (r.trimMemoryLevel < 10) pw.print(' ');
13230            pw.print(r.trimMemoryLevel);
13231            pw.print(' ');
13232            pw.print(r.toShortString());
13233            pw.print(" (");
13234            pw.print(r.adjType);
13235            pw.println(')');
13236            if (r.adjSource != null || r.adjTarget != null) {
13237                pw.print(prefix);
13238                pw.print("    ");
13239                if (r.adjTarget instanceof ComponentName) {
13240                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13241                } else if (r.adjTarget != null) {
13242                    pw.print(r.adjTarget.toString());
13243                } else {
13244                    pw.print("{null}");
13245                }
13246                pw.print("<=");
13247                if (r.adjSource instanceof ProcessRecord) {
13248                    pw.print("Proc{");
13249                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13250                    pw.println("}");
13251                } else if (r.adjSource != null) {
13252                    pw.println(r.adjSource.toString());
13253                } else {
13254                    pw.println("{null}");
13255                }
13256            }
13257            if (inclDetails) {
13258                pw.print(prefix);
13259                pw.print("    ");
13260                pw.print("oom: max="); pw.print(r.maxAdj);
13261                pw.print(" curRaw="); pw.print(r.curRawAdj);
13262                pw.print(" setRaw="); pw.print(r.setRawAdj);
13263                pw.print(" cur="); pw.print(r.curAdj);
13264                pw.print(" set="); pw.println(r.setAdj);
13265                pw.print(prefix);
13266                pw.print("    ");
13267                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13268                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13269                pw.print(" lastPss="); pw.print(r.lastPss);
13270                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13271                pw.print(prefix);
13272                pw.print("    ");
13273                pw.print("cached="); pw.print(r.cached);
13274                pw.print(" empty="); pw.print(r.empty);
13275                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13276
13277                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13278                    if (r.lastWakeTime != 0) {
13279                        long wtime;
13280                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13281                        synchronized (stats) {
13282                            wtime = stats.getProcessWakeTime(r.info.uid,
13283                                    r.pid, curRealtime);
13284                        }
13285                        long timeUsed = wtime - r.lastWakeTime;
13286                        pw.print(prefix);
13287                        pw.print("    ");
13288                        pw.print("keep awake over ");
13289                        TimeUtils.formatDuration(realtimeSince, pw);
13290                        pw.print(" used ");
13291                        TimeUtils.formatDuration(timeUsed, pw);
13292                        pw.print(" (");
13293                        pw.print((timeUsed*100)/realtimeSince);
13294                        pw.println("%)");
13295                    }
13296                    if (r.lastCpuTime != 0) {
13297                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13298                        pw.print(prefix);
13299                        pw.print("    ");
13300                        pw.print("run cpu over ");
13301                        TimeUtils.formatDuration(uptimeSince, pw);
13302                        pw.print(" used ");
13303                        TimeUtils.formatDuration(timeUsed, pw);
13304                        pw.print(" (");
13305                        pw.print((timeUsed*100)/uptimeSince);
13306                        pw.println("%)");
13307                    }
13308                }
13309            }
13310        }
13311        return true;
13312    }
13313
13314    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13315        ArrayList<ProcessRecord> procs;
13316        synchronized (this) {
13317            if (args != null && args.length > start
13318                    && args[start].charAt(0) != '-') {
13319                procs = new ArrayList<ProcessRecord>();
13320                int pid = -1;
13321                try {
13322                    pid = Integer.parseInt(args[start]);
13323                } catch (NumberFormatException e) {
13324                }
13325                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13326                    ProcessRecord proc = mLruProcesses.get(i);
13327                    if (proc.pid == pid) {
13328                        procs.add(proc);
13329                    } else if (proc.processName.equals(args[start])) {
13330                        procs.add(proc);
13331                    }
13332                }
13333                if (procs.size() <= 0) {
13334                    return null;
13335                }
13336            } else {
13337                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13338            }
13339        }
13340        return procs;
13341    }
13342
13343    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13344            PrintWriter pw, String[] args) {
13345        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13346        if (procs == null) {
13347            pw.println("No process found for: " + args[0]);
13348            return;
13349        }
13350
13351        long uptime = SystemClock.uptimeMillis();
13352        long realtime = SystemClock.elapsedRealtime();
13353        pw.println("Applications Graphics Acceleration Info:");
13354        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13355
13356        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13357            ProcessRecord r = procs.get(i);
13358            if (r.thread != null) {
13359                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13360                pw.flush();
13361                try {
13362                    TransferPipe tp = new TransferPipe();
13363                    try {
13364                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13365                        tp.go(fd);
13366                    } finally {
13367                        tp.kill();
13368                    }
13369                } catch (IOException e) {
13370                    pw.println("Failure while dumping the app: " + r);
13371                    pw.flush();
13372                } catch (RemoteException e) {
13373                    pw.println("Got a RemoteException while dumping the app " + r);
13374                    pw.flush();
13375                }
13376            }
13377        }
13378    }
13379
13380    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13381        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13382        if (procs == null) {
13383            pw.println("No process found for: " + args[0]);
13384            return;
13385        }
13386
13387        pw.println("Applications Database Info:");
13388
13389        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13390            ProcessRecord r = procs.get(i);
13391            if (r.thread != null) {
13392                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13393                pw.flush();
13394                try {
13395                    TransferPipe tp = new TransferPipe();
13396                    try {
13397                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13398                        tp.go(fd);
13399                    } finally {
13400                        tp.kill();
13401                    }
13402                } catch (IOException e) {
13403                    pw.println("Failure while dumping the app: " + r);
13404                    pw.flush();
13405                } catch (RemoteException e) {
13406                    pw.println("Got a RemoteException while dumping the app " + r);
13407                    pw.flush();
13408                }
13409            }
13410        }
13411    }
13412
13413    final static class MemItem {
13414        final boolean isProc;
13415        final String label;
13416        final String shortLabel;
13417        final long pss;
13418        final int id;
13419        final boolean hasActivities;
13420        ArrayList<MemItem> subitems;
13421
13422        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13423                boolean _hasActivities) {
13424            isProc = true;
13425            label = _label;
13426            shortLabel = _shortLabel;
13427            pss = _pss;
13428            id = _id;
13429            hasActivities = _hasActivities;
13430        }
13431
13432        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13433            isProc = false;
13434            label = _label;
13435            shortLabel = _shortLabel;
13436            pss = _pss;
13437            id = _id;
13438            hasActivities = false;
13439        }
13440    }
13441
13442    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13443            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13444        if (sort && !isCompact) {
13445            Collections.sort(items, new Comparator<MemItem>() {
13446                @Override
13447                public int compare(MemItem lhs, MemItem rhs) {
13448                    if (lhs.pss < rhs.pss) {
13449                        return 1;
13450                    } else if (lhs.pss > rhs.pss) {
13451                        return -1;
13452                    }
13453                    return 0;
13454                }
13455            });
13456        }
13457
13458        for (int i=0; i<items.size(); i++) {
13459            MemItem mi = items.get(i);
13460            if (!isCompact) {
13461                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13462            } else if (mi.isProc) {
13463                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13464                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13465                pw.println(mi.hasActivities ? ",a" : ",e");
13466            } else {
13467                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13468                pw.println(mi.pss);
13469            }
13470            if (mi.subitems != null) {
13471                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13472                        true, isCompact);
13473            }
13474        }
13475    }
13476
13477    // These are in KB.
13478    static final long[] DUMP_MEM_BUCKETS = new long[] {
13479        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13480        120*1024, 160*1024, 200*1024,
13481        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13482        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13483    };
13484
13485    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13486            boolean stackLike) {
13487        int start = label.lastIndexOf('.');
13488        if (start >= 0) start++;
13489        else start = 0;
13490        int end = label.length();
13491        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13492            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13493                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13494                out.append(bucket);
13495                out.append(stackLike ? "MB." : "MB ");
13496                out.append(label, start, end);
13497                return;
13498            }
13499        }
13500        out.append(memKB/1024);
13501        out.append(stackLike ? "MB." : "MB ");
13502        out.append(label, start, end);
13503    }
13504
13505    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13506            ProcessList.NATIVE_ADJ,
13507            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13508            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13509            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13510            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13511            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13512    };
13513    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13514            "Native",
13515            "System", "Persistent", "Foreground",
13516            "Visible", "Perceptible",
13517            "Heavy Weight", "Backup",
13518            "A Services", "Home",
13519            "Previous", "B Services", "Cached"
13520    };
13521    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13522            "native",
13523            "sys", "pers", "fore",
13524            "vis", "percept",
13525            "heavy", "backup",
13526            "servicea", "home",
13527            "prev", "serviceb", "cached"
13528    };
13529
13530    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13531            long realtime, boolean isCheckinRequest, boolean isCompact) {
13532        if (isCheckinRequest || isCompact) {
13533            // short checkin version
13534            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13535        } else {
13536            pw.println("Applications Memory Usage (kB):");
13537            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13538        }
13539    }
13540
13541    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13542            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13543        boolean dumpDetails = false;
13544        boolean dumpFullDetails = false;
13545        boolean dumpDalvik = false;
13546        boolean oomOnly = false;
13547        boolean isCompact = false;
13548        boolean localOnly = false;
13549
13550        int opti = 0;
13551        while (opti < args.length) {
13552            String opt = args[opti];
13553            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13554                break;
13555            }
13556            opti++;
13557            if ("-a".equals(opt)) {
13558                dumpDetails = true;
13559                dumpFullDetails = true;
13560                dumpDalvik = true;
13561            } else if ("-d".equals(opt)) {
13562                dumpDalvik = true;
13563            } else if ("-c".equals(opt)) {
13564                isCompact = true;
13565            } else if ("--oom".equals(opt)) {
13566                oomOnly = true;
13567            } else if ("--local".equals(opt)) {
13568                localOnly = true;
13569            } else if ("-h".equals(opt)) {
13570                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13571                pw.println("  -a: include all available information for each process.");
13572                pw.println("  -d: include dalvik details when dumping process details.");
13573                pw.println("  -c: dump in a compact machine-parseable representation.");
13574                pw.println("  --oom: only show processes organized by oom adj.");
13575                pw.println("  --local: only collect details locally, don't call process.");
13576                pw.println("If [process] is specified it can be the name or ");
13577                pw.println("pid of a specific process to dump.");
13578                return;
13579            } else {
13580                pw.println("Unknown argument: " + opt + "; use -h for help");
13581            }
13582        }
13583
13584        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13585        long uptime = SystemClock.uptimeMillis();
13586        long realtime = SystemClock.elapsedRealtime();
13587        final long[] tmpLong = new long[1];
13588
13589        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13590        if (procs == null) {
13591            // No Java processes.  Maybe they want to print a native process.
13592            if (args != null && args.length > opti
13593                    && args[opti].charAt(0) != '-') {
13594                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13595                        = new ArrayList<ProcessCpuTracker.Stats>();
13596                updateCpuStatsNow();
13597                int findPid = -1;
13598                try {
13599                    findPid = Integer.parseInt(args[opti]);
13600                } catch (NumberFormatException e) {
13601                }
13602                synchronized (mProcessCpuThread) {
13603                    final int N = mProcessCpuTracker.countStats();
13604                    for (int i=0; i<N; i++) {
13605                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13606                        if (st.pid == findPid || (st.baseName != null
13607                                && st.baseName.equals(args[opti]))) {
13608                            nativeProcs.add(st);
13609                        }
13610                    }
13611                }
13612                if (nativeProcs.size() > 0) {
13613                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13614                            isCompact);
13615                    Debug.MemoryInfo mi = null;
13616                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13617                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13618                        final int pid = r.pid;
13619                        if (!isCheckinRequest && dumpDetails) {
13620                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13621                        }
13622                        if (mi == null) {
13623                            mi = new Debug.MemoryInfo();
13624                        }
13625                        if (dumpDetails || (!brief && !oomOnly)) {
13626                            Debug.getMemoryInfo(pid, mi);
13627                        } else {
13628                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13629                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13630                        }
13631                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13632                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13633                        if (isCheckinRequest) {
13634                            pw.println();
13635                        }
13636                    }
13637                    return;
13638                }
13639            }
13640            pw.println("No process found for: " + args[opti]);
13641            return;
13642        }
13643
13644        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13645            dumpDetails = true;
13646        }
13647
13648        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13649
13650        String[] innerArgs = new String[args.length-opti];
13651        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13652
13653        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13654        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13655        long nativePss=0, dalvikPss=0, otherPss=0;
13656        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13657
13658        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13659        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13660                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13661
13662        long totalPss = 0;
13663        long cachedPss = 0;
13664
13665        Debug.MemoryInfo mi = null;
13666        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13667            final ProcessRecord r = procs.get(i);
13668            final IApplicationThread thread;
13669            final int pid;
13670            final int oomAdj;
13671            final boolean hasActivities;
13672            synchronized (this) {
13673                thread = r.thread;
13674                pid = r.pid;
13675                oomAdj = r.getSetAdjWithServices();
13676                hasActivities = r.activities.size() > 0;
13677            }
13678            if (thread != null) {
13679                if (!isCheckinRequest && dumpDetails) {
13680                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13681                }
13682                if (mi == null) {
13683                    mi = new Debug.MemoryInfo();
13684                }
13685                if (dumpDetails || (!brief && !oomOnly)) {
13686                    Debug.getMemoryInfo(pid, mi);
13687                } else {
13688                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13689                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13690                }
13691                if (dumpDetails) {
13692                    if (localOnly) {
13693                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13694                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13695                        if (isCheckinRequest) {
13696                            pw.println();
13697                        }
13698                    } else {
13699                        try {
13700                            pw.flush();
13701                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13702                                    dumpDalvik, innerArgs);
13703                        } catch (RemoteException e) {
13704                            if (!isCheckinRequest) {
13705                                pw.println("Got RemoteException!");
13706                                pw.flush();
13707                            }
13708                        }
13709                    }
13710                }
13711
13712                final long myTotalPss = mi.getTotalPss();
13713                final long myTotalUss = mi.getTotalUss();
13714
13715                synchronized (this) {
13716                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13717                        // Record this for posterity if the process has been stable.
13718                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13719                    }
13720                }
13721
13722                if (!isCheckinRequest && mi != null) {
13723                    totalPss += myTotalPss;
13724                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13725                            (hasActivities ? " / activities)" : ")"),
13726                            r.processName, myTotalPss, pid, hasActivities);
13727                    procMems.add(pssItem);
13728                    procMemsMap.put(pid, pssItem);
13729
13730                    nativePss += mi.nativePss;
13731                    dalvikPss += mi.dalvikPss;
13732                    otherPss += mi.otherPss;
13733                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13734                        long mem = mi.getOtherPss(j);
13735                        miscPss[j] += mem;
13736                        otherPss -= mem;
13737                    }
13738
13739                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13740                        cachedPss += myTotalPss;
13741                    }
13742
13743                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13744                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13745                                || oomIndex == (oomPss.length-1)) {
13746                            oomPss[oomIndex] += myTotalPss;
13747                            if (oomProcs[oomIndex] == null) {
13748                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13749                            }
13750                            oomProcs[oomIndex].add(pssItem);
13751                            break;
13752                        }
13753                    }
13754                }
13755            }
13756        }
13757
13758        long nativeProcTotalPss = 0;
13759
13760        if (!isCheckinRequest && procs.size() > 1) {
13761            // If we are showing aggregations, also look for native processes to
13762            // include so that our aggregations are more accurate.
13763            updateCpuStatsNow();
13764            synchronized (mProcessCpuThread) {
13765                final int N = mProcessCpuTracker.countStats();
13766                for (int i=0; i<N; i++) {
13767                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13768                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13769                        if (mi == null) {
13770                            mi = new Debug.MemoryInfo();
13771                        }
13772                        if (!brief && !oomOnly) {
13773                            Debug.getMemoryInfo(st.pid, mi);
13774                        } else {
13775                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13776                            mi.nativePrivateDirty = (int)tmpLong[0];
13777                        }
13778
13779                        final long myTotalPss = mi.getTotalPss();
13780                        totalPss += myTotalPss;
13781                        nativeProcTotalPss += myTotalPss;
13782
13783                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13784                                st.name, myTotalPss, st.pid, false);
13785                        procMems.add(pssItem);
13786
13787                        nativePss += mi.nativePss;
13788                        dalvikPss += mi.dalvikPss;
13789                        otherPss += mi.otherPss;
13790                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13791                            long mem = mi.getOtherPss(j);
13792                            miscPss[j] += mem;
13793                            otherPss -= mem;
13794                        }
13795                        oomPss[0] += myTotalPss;
13796                        if (oomProcs[0] == null) {
13797                            oomProcs[0] = new ArrayList<MemItem>();
13798                        }
13799                        oomProcs[0].add(pssItem);
13800                    }
13801                }
13802            }
13803
13804            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13805
13806            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13807            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13808            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13809            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13810                String label = Debug.MemoryInfo.getOtherLabel(j);
13811                catMems.add(new MemItem(label, label, miscPss[j], j));
13812            }
13813
13814            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13815            for (int j=0; j<oomPss.length; j++) {
13816                if (oomPss[j] != 0) {
13817                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13818                            : DUMP_MEM_OOM_LABEL[j];
13819                    MemItem item = new MemItem(label, label, oomPss[j],
13820                            DUMP_MEM_OOM_ADJ[j]);
13821                    item.subitems = oomProcs[j];
13822                    oomMems.add(item);
13823                }
13824            }
13825
13826            if (!brief && !oomOnly && !isCompact) {
13827                pw.println();
13828                pw.println("Total PSS by process:");
13829                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13830                pw.println();
13831            }
13832            if (!isCompact) {
13833                pw.println("Total PSS by OOM adjustment:");
13834            }
13835            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13836            if (!brief && !oomOnly) {
13837                PrintWriter out = categoryPw != null ? categoryPw : pw;
13838                if (!isCompact) {
13839                    out.println();
13840                    out.println("Total PSS by category:");
13841                }
13842                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13843            }
13844            if (!isCompact) {
13845                pw.println();
13846            }
13847            MemInfoReader memInfo = new MemInfoReader();
13848            memInfo.readMemInfo();
13849            if (nativeProcTotalPss > 0) {
13850                synchronized (this) {
13851                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13852                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13853                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13854                            nativeProcTotalPss);
13855                }
13856            }
13857            if (!brief) {
13858                if (!isCompact) {
13859                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13860                    pw.print(" kB (status ");
13861                    switch (mLastMemoryLevel) {
13862                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13863                            pw.println("normal)");
13864                            break;
13865                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13866                            pw.println("moderate)");
13867                            break;
13868                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13869                            pw.println("low)");
13870                            break;
13871                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13872                            pw.println("critical)");
13873                            break;
13874                        default:
13875                            pw.print(mLastMemoryLevel);
13876                            pw.println(")");
13877                            break;
13878                    }
13879                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13880                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13881                            pw.print(cachedPss); pw.print(" cached pss + ");
13882                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13883                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13884                } else {
13885                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13886                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13887                            + memInfo.getFreeSizeKb()); pw.print(",");
13888                    pw.println(totalPss - cachedPss);
13889                }
13890            }
13891            if (!isCompact) {
13892                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13893                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13894                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13895                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13896                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13897                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13898                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13899                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13900                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13901                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13902                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13903            }
13904            if (!brief) {
13905                if (memInfo.getZramTotalSizeKb() != 0) {
13906                    if (!isCompact) {
13907                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13908                                pw.print(" kB physical used for ");
13909                                pw.print(memInfo.getSwapTotalSizeKb()
13910                                        - memInfo.getSwapFreeSizeKb());
13911                                pw.print(" kB in swap (");
13912                                pw.print(memInfo.getSwapTotalSizeKb());
13913                                pw.println(" kB total swap)");
13914                    } else {
13915                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13916                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13917                                pw.println(memInfo.getSwapFreeSizeKb());
13918                    }
13919                }
13920                final int[] SINGLE_LONG_FORMAT = new int[] {
13921                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13922                };
13923                long[] longOut = new long[1];
13924                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13925                        SINGLE_LONG_FORMAT, null, longOut, null);
13926                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13927                longOut[0] = 0;
13928                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13929                        SINGLE_LONG_FORMAT, null, longOut, null);
13930                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13931                longOut[0] = 0;
13932                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13933                        SINGLE_LONG_FORMAT, null, longOut, null);
13934                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13935                longOut[0] = 0;
13936                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13937                        SINGLE_LONG_FORMAT, null, longOut, null);
13938                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13939                if (!isCompact) {
13940                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13941                        pw.print("      KSM: "); pw.print(sharing);
13942                                pw.print(" kB saved from shared ");
13943                                pw.print(shared); pw.println(" kB");
13944                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13945                                pw.print(voltile); pw.println(" kB volatile");
13946                    }
13947                    pw.print("   Tuning: ");
13948                    pw.print(ActivityManager.staticGetMemoryClass());
13949                    pw.print(" (large ");
13950                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13951                    pw.print("), oom ");
13952                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13953                    pw.print(" kB");
13954                    pw.print(", restore limit ");
13955                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13956                    pw.print(" kB");
13957                    if (ActivityManager.isLowRamDeviceStatic()) {
13958                        pw.print(" (low-ram)");
13959                    }
13960                    if (ActivityManager.isHighEndGfx()) {
13961                        pw.print(" (high-end-gfx)");
13962                    }
13963                    pw.println();
13964                } else {
13965                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13966                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13967                    pw.println(voltile);
13968                    pw.print("tuning,");
13969                    pw.print(ActivityManager.staticGetMemoryClass());
13970                    pw.print(',');
13971                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13972                    pw.print(',');
13973                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13974                    if (ActivityManager.isLowRamDeviceStatic()) {
13975                        pw.print(",low-ram");
13976                    }
13977                    if (ActivityManager.isHighEndGfx()) {
13978                        pw.print(",high-end-gfx");
13979                    }
13980                    pw.println();
13981                }
13982            }
13983        }
13984    }
13985
13986    /**
13987     * Searches array of arguments for the specified string
13988     * @param args array of argument strings
13989     * @param value value to search for
13990     * @return true if the value is contained in the array
13991     */
13992    private static boolean scanArgs(String[] args, String value) {
13993        if (args != null) {
13994            for (String arg : args) {
13995                if (value.equals(arg)) {
13996                    return true;
13997                }
13998            }
13999        }
14000        return false;
14001    }
14002
14003    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14004            ContentProviderRecord cpr, boolean always) {
14005        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14006
14007        if (!inLaunching || always) {
14008            synchronized (cpr) {
14009                cpr.launchingApp = null;
14010                cpr.notifyAll();
14011            }
14012            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14013            String names[] = cpr.info.authority.split(";");
14014            for (int j = 0; j < names.length; j++) {
14015                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14016            }
14017        }
14018
14019        for (int i=0; i<cpr.connections.size(); i++) {
14020            ContentProviderConnection conn = cpr.connections.get(i);
14021            if (conn.waiting) {
14022                // If this connection is waiting for the provider, then we don't
14023                // need to mess with its process unless we are always removing
14024                // or for some reason the provider is not currently launching.
14025                if (inLaunching && !always) {
14026                    continue;
14027                }
14028            }
14029            ProcessRecord capp = conn.client;
14030            conn.dead = true;
14031            if (conn.stableCount > 0) {
14032                if (!capp.persistent && capp.thread != null
14033                        && capp.pid != 0
14034                        && capp.pid != MY_PID) {
14035                    capp.kill("depends on provider "
14036                            + cpr.name.flattenToShortString()
14037                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14038                }
14039            } else if (capp.thread != null && conn.provider.provider != null) {
14040                try {
14041                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14042                } catch (RemoteException e) {
14043                }
14044                // In the protocol here, we don't expect the client to correctly
14045                // clean up this connection, we'll just remove it.
14046                cpr.connections.remove(i);
14047                conn.client.conProviders.remove(conn);
14048            }
14049        }
14050
14051        if (inLaunching && always) {
14052            mLaunchingProviders.remove(cpr);
14053        }
14054        return inLaunching;
14055    }
14056
14057    /**
14058     * Main code for cleaning up a process when it has gone away.  This is
14059     * called both as a result of the process dying, or directly when stopping
14060     * a process when running in single process mode.
14061     */
14062    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14063            boolean restarting, boolean allowRestart, int index) {
14064        if (index >= 0) {
14065            removeLruProcessLocked(app);
14066            ProcessList.remove(app.pid);
14067        }
14068
14069        mProcessesToGc.remove(app);
14070        mPendingPssProcesses.remove(app);
14071
14072        // Dismiss any open dialogs.
14073        if (app.crashDialog != null && !app.forceCrashReport) {
14074            app.crashDialog.dismiss();
14075            app.crashDialog = null;
14076        }
14077        if (app.anrDialog != null) {
14078            app.anrDialog.dismiss();
14079            app.anrDialog = null;
14080        }
14081        if (app.waitDialog != null) {
14082            app.waitDialog.dismiss();
14083            app.waitDialog = null;
14084        }
14085
14086        app.crashing = false;
14087        app.notResponding = false;
14088
14089        app.resetPackageList(mProcessStats);
14090        app.unlinkDeathRecipient();
14091        app.makeInactive(mProcessStats);
14092        app.waitingToKill = null;
14093        app.forcingToForeground = null;
14094        updateProcessForegroundLocked(app, false, false);
14095        app.foregroundActivities = false;
14096        app.hasShownUi = false;
14097        app.treatLikeActivity = false;
14098        app.hasAboveClient = false;
14099        app.hasClientActivities = false;
14100
14101        mServices.killServicesLocked(app, allowRestart);
14102
14103        boolean restart = false;
14104
14105        // Remove published content providers.
14106        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14107            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14108            final boolean always = app.bad || !allowRestart;
14109            if (removeDyingProviderLocked(app, cpr, always) || always) {
14110                // We left the provider in the launching list, need to
14111                // restart it.
14112                restart = true;
14113            }
14114
14115            cpr.provider = null;
14116            cpr.proc = null;
14117        }
14118        app.pubProviders.clear();
14119
14120        // Take care of any launching providers waiting for this process.
14121        if (checkAppInLaunchingProvidersLocked(app, false)) {
14122            restart = true;
14123        }
14124
14125        // Unregister from connected content providers.
14126        if (!app.conProviders.isEmpty()) {
14127            for (int i=0; i<app.conProviders.size(); i++) {
14128                ContentProviderConnection conn = app.conProviders.get(i);
14129                conn.provider.connections.remove(conn);
14130            }
14131            app.conProviders.clear();
14132        }
14133
14134        // At this point there may be remaining entries in mLaunchingProviders
14135        // where we were the only one waiting, so they are no longer of use.
14136        // Look for these and clean up if found.
14137        // XXX Commented out for now.  Trying to figure out a way to reproduce
14138        // the actual situation to identify what is actually going on.
14139        if (false) {
14140            for (int i=0; i<mLaunchingProviders.size(); i++) {
14141                ContentProviderRecord cpr = (ContentProviderRecord)
14142                        mLaunchingProviders.get(i);
14143                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14144                    synchronized (cpr) {
14145                        cpr.launchingApp = null;
14146                        cpr.notifyAll();
14147                    }
14148                }
14149            }
14150        }
14151
14152        skipCurrentReceiverLocked(app);
14153
14154        // Unregister any receivers.
14155        for (int i=app.receivers.size()-1; i>=0; i--) {
14156            removeReceiverLocked(app.receivers.valueAt(i));
14157        }
14158        app.receivers.clear();
14159
14160        // If the app is undergoing backup, tell the backup manager about it
14161        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14162            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14163                    + mBackupTarget.appInfo + " died during backup");
14164            try {
14165                IBackupManager bm = IBackupManager.Stub.asInterface(
14166                        ServiceManager.getService(Context.BACKUP_SERVICE));
14167                bm.agentDisconnected(app.info.packageName);
14168            } catch (RemoteException e) {
14169                // can't happen; backup manager is local
14170            }
14171        }
14172
14173        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14174            ProcessChangeItem item = mPendingProcessChanges.get(i);
14175            if (item.pid == app.pid) {
14176                mPendingProcessChanges.remove(i);
14177                mAvailProcessChanges.add(item);
14178            }
14179        }
14180        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14181
14182        // If the caller is restarting this app, then leave it in its
14183        // current lists and let the caller take care of it.
14184        if (restarting) {
14185            return;
14186        }
14187
14188        if (!app.persistent || app.isolated) {
14189            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14190                    "Removing non-persistent process during cleanup: " + app);
14191            mProcessNames.remove(app.processName, app.uid);
14192            mIsolatedProcesses.remove(app.uid);
14193            if (mHeavyWeightProcess == app) {
14194                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14195                        mHeavyWeightProcess.userId, 0));
14196                mHeavyWeightProcess = null;
14197            }
14198        } else if (!app.removed) {
14199            // This app is persistent, so we need to keep its record around.
14200            // If it is not already on the pending app list, add it there
14201            // and start a new process for it.
14202            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14203                mPersistentStartingProcesses.add(app);
14204                restart = true;
14205            }
14206        }
14207        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14208                "Clean-up removing on hold: " + app);
14209        mProcessesOnHold.remove(app);
14210
14211        if (app == mHomeProcess) {
14212            mHomeProcess = null;
14213        }
14214        if (app == mPreviousProcess) {
14215            mPreviousProcess = null;
14216        }
14217
14218        if (restart && !app.isolated) {
14219            // We have components that still need to be running in the
14220            // process, so re-launch it.
14221            mProcessNames.put(app.processName, app.uid, app);
14222            startProcessLocked(app, "restart", app.processName);
14223        } else if (app.pid > 0 && app.pid != MY_PID) {
14224            // Goodbye!
14225            boolean removed;
14226            synchronized (mPidsSelfLocked) {
14227                mPidsSelfLocked.remove(app.pid);
14228                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14229            }
14230            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14231            if (app.isolated) {
14232                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14233            }
14234            app.setPid(0);
14235        }
14236    }
14237
14238    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14239        // Look through the content providers we are waiting to have launched,
14240        // and if any run in this process then either schedule a restart of
14241        // the process or kill the client waiting for it if this process has
14242        // gone bad.
14243        int NL = mLaunchingProviders.size();
14244        boolean restart = false;
14245        for (int i=0; i<NL; i++) {
14246            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14247            if (cpr.launchingApp == app) {
14248                if (!alwaysBad && !app.bad) {
14249                    restart = true;
14250                } else {
14251                    removeDyingProviderLocked(app, cpr, true);
14252                    // cpr should have been removed from mLaunchingProviders
14253                    NL = mLaunchingProviders.size();
14254                    i--;
14255                }
14256            }
14257        }
14258        return restart;
14259    }
14260
14261    // =========================================================
14262    // SERVICES
14263    // =========================================================
14264
14265    @Override
14266    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14267            int flags) {
14268        enforceNotIsolatedCaller("getServices");
14269        synchronized (this) {
14270            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14271        }
14272    }
14273
14274    @Override
14275    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14276        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14277        synchronized (this) {
14278            return mServices.getRunningServiceControlPanelLocked(name);
14279        }
14280    }
14281
14282    @Override
14283    public ComponentName startService(IApplicationThread caller, Intent service,
14284            String resolvedType, int userId) {
14285        enforceNotIsolatedCaller("startService");
14286        // Refuse possible leaked file descriptors
14287        if (service != null && service.hasFileDescriptors() == true) {
14288            throw new IllegalArgumentException("File descriptors passed in Intent");
14289        }
14290
14291        if (DEBUG_SERVICE)
14292            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14293        synchronized(this) {
14294            final int callingPid = Binder.getCallingPid();
14295            final int callingUid = Binder.getCallingUid();
14296            final long origId = Binder.clearCallingIdentity();
14297            ComponentName res = mServices.startServiceLocked(caller, service,
14298                    resolvedType, callingPid, callingUid, userId);
14299            Binder.restoreCallingIdentity(origId);
14300            return res;
14301        }
14302    }
14303
14304    ComponentName startServiceInPackage(int uid,
14305            Intent service, String resolvedType, int userId) {
14306        synchronized(this) {
14307            if (DEBUG_SERVICE)
14308                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14309            final long origId = Binder.clearCallingIdentity();
14310            ComponentName res = mServices.startServiceLocked(null, service,
14311                    resolvedType, -1, uid, userId);
14312            Binder.restoreCallingIdentity(origId);
14313            return res;
14314        }
14315    }
14316
14317    @Override
14318    public int stopService(IApplicationThread caller, Intent service,
14319            String resolvedType, int userId) {
14320        enforceNotIsolatedCaller("stopService");
14321        // Refuse possible leaked file descriptors
14322        if (service != null && service.hasFileDescriptors() == true) {
14323            throw new IllegalArgumentException("File descriptors passed in Intent");
14324        }
14325
14326        synchronized(this) {
14327            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14328        }
14329    }
14330
14331    @Override
14332    public IBinder peekService(Intent service, String resolvedType) {
14333        enforceNotIsolatedCaller("peekService");
14334        // Refuse possible leaked file descriptors
14335        if (service != null && service.hasFileDescriptors() == true) {
14336            throw new IllegalArgumentException("File descriptors passed in Intent");
14337        }
14338        synchronized(this) {
14339            return mServices.peekServiceLocked(service, resolvedType);
14340        }
14341    }
14342
14343    @Override
14344    public boolean stopServiceToken(ComponentName className, IBinder token,
14345            int startId) {
14346        synchronized(this) {
14347            return mServices.stopServiceTokenLocked(className, token, startId);
14348        }
14349    }
14350
14351    @Override
14352    public void setServiceForeground(ComponentName className, IBinder token,
14353            int id, Notification notification, boolean removeNotification) {
14354        synchronized(this) {
14355            mServices.setServiceForegroundLocked(className, token, id, notification,
14356                    removeNotification);
14357        }
14358    }
14359
14360    @Override
14361    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14362            boolean requireFull, String name, String callerPackage) {
14363        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14364                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14365    }
14366
14367    int unsafeConvertIncomingUser(int userId) {
14368        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14369                ? mCurrentUserId : userId;
14370    }
14371
14372    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14373            int allowMode, String name, String callerPackage) {
14374        final int callingUserId = UserHandle.getUserId(callingUid);
14375        if (callingUserId == userId) {
14376            return userId;
14377        }
14378
14379        // Note that we may be accessing mCurrentUserId outside of a lock...
14380        // shouldn't be a big deal, if this is being called outside
14381        // of a locked context there is intrinsically a race with
14382        // the value the caller will receive and someone else changing it.
14383        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14384        // we will switch to the calling user if access to the current user fails.
14385        int targetUserId = unsafeConvertIncomingUser(userId);
14386
14387        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14388            final boolean allow;
14389            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14390                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14391                // If the caller has this permission, they always pass go.  And collect $200.
14392                allow = true;
14393            } else if (allowMode == ALLOW_FULL_ONLY) {
14394                // We require full access, sucks to be you.
14395                allow = false;
14396            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14397                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14398                // If the caller does not have either permission, they are always doomed.
14399                allow = false;
14400            } else if (allowMode == ALLOW_NON_FULL) {
14401                // We are blanket allowing non-full access, you lucky caller!
14402                allow = true;
14403            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14404                // We may or may not allow this depending on whether the two users are
14405                // in the same profile.
14406                synchronized (mUserProfileGroupIdsSelfLocked) {
14407                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14408                            UserInfo.NO_PROFILE_GROUP_ID);
14409                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14410                            UserInfo.NO_PROFILE_GROUP_ID);
14411                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14412                            && callingProfile == targetProfile;
14413                }
14414            } else {
14415                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14416            }
14417            if (!allow) {
14418                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14419                    // In this case, they would like to just execute as their
14420                    // owner user instead of failing.
14421                    targetUserId = callingUserId;
14422                } else {
14423                    StringBuilder builder = new StringBuilder(128);
14424                    builder.append("Permission Denial: ");
14425                    builder.append(name);
14426                    if (callerPackage != null) {
14427                        builder.append(" from ");
14428                        builder.append(callerPackage);
14429                    }
14430                    builder.append(" asks to run as user ");
14431                    builder.append(userId);
14432                    builder.append(" but is calling from user ");
14433                    builder.append(UserHandle.getUserId(callingUid));
14434                    builder.append("; this requires ");
14435                    builder.append(INTERACT_ACROSS_USERS_FULL);
14436                    if (allowMode != ALLOW_FULL_ONLY) {
14437                        builder.append(" or ");
14438                        builder.append(INTERACT_ACROSS_USERS);
14439                    }
14440                    String msg = builder.toString();
14441                    Slog.w(TAG, msg);
14442                    throw new SecurityException(msg);
14443                }
14444            }
14445        }
14446        if (!allowAll && targetUserId < 0) {
14447            throw new IllegalArgumentException(
14448                    "Call does not support special user #" + targetUserId);
14449        }
14450        return targetUserId;
14451    }
14452
14453    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14454            String className, int flags) {
14455        boolean result = false;
14456        // For apps that don't have pre-defined UIDs, check for permission
14457        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14458            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14459                if (ActivityManager.checkUidPermission(
14460                        INTERACT_ACROSS_USERS,
14461                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14462                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14463                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14464                            + " requests FLAG_SINGLE_USER, but app does not hold "
14465                            + INTERACT_ACROSS_USERS;
14466                    Slog.w(TAG, msg);
14467                    throw new SecurityException(msg);
14468                }
14469                // Permission passed
14470                result = true;
14471            }
14472        } else if ("system".equals(componentProcessName)) {
14473            result = true;
14474        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14475                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14476            // Phone app is allowed to export singleuser providers.
14477            result = true;
14478        } else {
14479            // App with pre-defined UID, check if it's a persistent app
14480            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14481        }
14482        if (DEBUG_MU) {
14483            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14484                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14485        }
14486        return result;
14487    }
14488
14489    /**
14490     * Checks to see if the caller is in the same app as the singleton
14491     * component, or the component is in a special app. It allows special apps
14492     * to export singleton components but prevents exporting singleton
14493     * components for regular apps.
14494     */
14495    boolean isValidSingletonCall(int callingUid, int componentUid) {
14496        int componentAppId = UserHandle.getAppId(componentUid);
14497        return UserHandle.isSameApp(callingUid, componentUid)
14498                || componentAppId == Process.SYSTEM_UID
14499                || componentAppId == Process.PHONE_UID
14500                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14501                        == PackageManager.PERMISSION_GRANTED;
14502    }
14503
14504    public int bindService(IApplicationThread caller, IBinder token,
14505            Intent service, String resolvedType,
14506            IServiceConnection connection, int flags, int userId) {
14507        enforceNotIsolatedCaller("bindService");
14508        // Refuse possible leaked file descriptors
14509        if (service != null && service.hasFileDescriptors() == true) {
14510            throw new IllegalArgumentException("File descriptors passed in Intent");
14511        }
14512
14513        synchronized(this) {
14514            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14515                    connection, flags, userId);
14516        }
14517    }
14518
14519    public boolean unbindService(IServiceConnection connection) {
14520        synchronized (this) {
14521            return mServices.unbindServiceLocked(connection);
14522        }
14523    }
14524
14525    public void publishService(IBinder token, Intent intent, IBinder service) {
14526        // Refuse possible leaked file descriptors
14527        if (intent != null && intent.hasFileDescriptors() == true) {
14528            throw new IllegalArgumentException("File descriptors passed in Intent");
14529        }
14530
14531        synchronized(this) {
14532            if (!(token instanceof ServiceRecord)) {
14533                throw new IllegalArgumentException("Invalid service token");
14534            }
14535            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14536        }
14537    }
14538
14539    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14540        // Refuse possible leaked file descriptors
14541        if (intent != null && intent.hasFileDescriptors() == true) {
14542            throw new IllegalArgumentException("File descriptors passed in Intent");
14543        }
14544
14545        synchronized(this) {
14546            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14547        }
14548    }
14549
14550    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14551        synchronized(this) {
14552            if (!(token instanceof ServiceRecord)) {
14553                throw new IllegalArgumentException("Invalid service token");
14554            }
14555            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14556        }
14557    }
14558
14559    // =========================================================
14560    // BACKUP AND RESTORE
14561    // =========================================================
14562
14563    // Cause the target app to be launched if necessary and its backup agent
14564    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14565    // activity manager to announce its creation.
14566    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14567        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14568        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14569
14570        synchronized(this) {
14571            // !!! TODO: currently no check here that we're already bound
14572            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14573            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14574            synchronized (stats) {
14575                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14576            }
14577
14578            // Backup agent is now in use, its package can't be stopped.
14579            try {
14580                AppGlobals.getPackageManager().setPackageStoppedState(
14581                        app.packageName, false, UserHandle.getUserId(app.uid));
14582            } catch (RemoteException e) {
14583            } catch (IllegalArgumentException e) {
14584                Slog.w(TAG, "Failed trying to unstop package "
14585                        + app.packageName + ": " + e);
14586            }
14587
14588            BackupRecord r = new BackupRecord(ss, app, backupMode);
14589            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14590                    ? new ComponentName(app.packageName, app.backupAgentName)
14591                    : new ComponentName("android", "FullBackupAgent");
14592            // startProcessLocked() returns existing proc's record if it's already running
14593            ProcessRecord proc = startProcessLocked(app.processName, app,
14594                    false, 0, "backup", hostingName, false, false, false);
14595            if (proc == null) {
14596                Slog.e(TAG, "Unable to start backup agent process " + r);
14597                return false;
14598            }
14599
14600            r.app = proc;
14601            mBackupTarget = r;
14602            mBackupAppName = app.packageName;
14603
14604            // Try not to kill the process during backup
14605            updateOomAdjLocked(proc);
14606
14607            // If the process is already attached, schedule the creation of the backup agent now.
14608            // If it is not yet live, this will be done when it attaches to the framework.
14609            if (proc.thread != null) {
14610                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14611                try {
14612                    proc.thread.scheduleCreateBackupAgent(app,
14613                            compatibilityInfoForPackageLocked(app), backupMode);
14614                } catch (RemoteException e) {
14615                    // Will time out on the backup manager side
14616                }
14617            } else {
14618                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14619            }
14620            // Invariants: at this point, the target app process exists and the application
14621            // is either already running or in the process of coming up.  mBackupTarget and
14622            // mBackupAppName describe the app, so that when it binds back to the AM we
14623            // know that it's scheduled for a backup-agent operation.
14624        }
14625
14626        return true;
14627    }
14628
14629    @Override
14630    public void clearPendingBackup() {
14631        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14632        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14633
14634        synchronized (this) {
14635            mBackupTarget = null;
14636            mBackupAppName = null;
14637        }
14638    }
14639
14640    // A backup agent has just come up
14641    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14642        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14643                + " = " + agent);
14644
14645        synchronized(this) {
14646            if (!agentPackageName.equals(mBackupAppName)) {
14647                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14648                return;
14649            }
14650        }
14651
14652        long oldIdent = Binder.clearCallingIdentity();
14653        try {
14654            IBackupManager bm = IBackupManager.Stub.asInterface(
14655                    ServiceManager.getService(Context.BACKUP_SERVICE));
14656            bm.agentConnected(agentPackageName, agent);
14657        } catch (RemoteException e) {
14658            // can't happen; the backup manager service is local
14659        } catch (Exception e) {
14660            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14661            e.printStackTrace();
14662        } finally {
14663            Binder.restoreCallingIdentity(oldIdent);
14664        }
14665    }
14666
14667    // done with this agent
14668    public void unbindBackupAgent(ApplicationInfo appInfo) {
14669        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14670        if (appInfo == null) {
14671            Slog.w(TAG, "unbind backup agent for null app");
14672            return;
14673        }
14674
14675        synchronized(this) {
14676            try {
14677                if (mBackupAppName == null) {
14678                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14679                    return;
14680                }
14681
14682                if (!mBackupAppName.equals(appInfo.packageName)) {
14683                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14684                    return;
14685                }
14686
14687                // Not backing this app up any more; reset its OOM adjustment
14688                final ProcessRecord proc = mBackupTarget.app;
14689                updateOomAdjLocked(proc);
14690
14691                // If the app crashed during backup, 'thread' will be null here
14692                if (proc.thread != null) {
14693                    try {
14694                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14695                                compatibilityInfoForPackageLocked(appInfo));
14696                    } catch (Exception e) {
14697                        Slog.e(TAG, "Exception when unbinding backup agent:");
14698                        e.printStackTrace();
14699                    }
14700                }
14701            } finally {
14702                mBackupTarget = null;
14703                mBackupAppName = null;
14704            }
14705        }
14706    }
14707    // =========================================================
14708    // BROADCASTS
14709    // =========================================================
14710
14711    private final List getStickiesLocked(String action, IntentFilter filter,
14712            List cur, int userId) {
14713        final ContentResolver resolver = mContext.getContentResolver();
14714        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14715        if (stickies == null) {
14716            return cur;
14717        }
14718        final ArrayList<Intent> list = stickies.get(action);
14719        if (list == null) {
14720            return cur;
14721        }
14722        int N = list.size();
14723        for (int i=0; i<N; i++) {
14724            Intent intent = list.get(i);
14725            if (filter.match(resolver, intent, true, TAG) >= 0) {
14726                if (cur == null) {
14727                    cur = new ArrayList<Intent>();
14728                }
14729                cur.add(intent);
14730            }
14731        }
14732        return cur;
14733    }
14734
14735    boolean isPendingBroadcastProcessLocked(int pid) {
14736        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14737                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14738    }
14739
14740    void skipPendingBroadcastLocked(int pid) {
14741            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14742            for (BroadcastQueue queue : mBroadcastQueues) {
14743                queue.skipPendingBroadcastLocked(pid);
14744            }
14745    }
14746
14747    // The app just attached; send any pending broadcasts that it should receive
14748    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14749        boolean didSomething = false;
14750        for (BroadcastQueue queue : mBroadcastQueues) {
14751            didSomething |= queue.sendPendingBroadcastsLocked(app);
14752        }
14753        return didSomething;
14754    }
14755
14756    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14757            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14758        enforceNotIsolatedCaller("registerReceiver");
14759        int callingUid;
14760        int callingPid;
14761        synchronized(this) {
14762            ProcessRecord callerApp = null;
14763            if (caller != null) {
14764                callerApp = getRecordForAppLocked(caller);
14765                if (callerApp == null) {
14766                    throw new SecurityException(
14767                            "Unable to find app for caller " + caller
14768                            + " (pid=" + Binder.getCallingPid()
14769                            + ") when registering receiver " + receiver);
14770                }
14771                if (callerApp.info.uid != Process.SYSTEM_UID &&
14772                        !callerApp.pkgList.containsKey(callerPackage) &&
14773                        !"android".equals(callerPackage)) {
14774                    throw new SecurityException("Given caller package " + callerPackage
14775                            + " is not running in process " + callerApp);
14776                }
14777                callingUid = callerApp.info.uid;
14778                callingPid = callerApp.pid;
14779            } else {
14780                callerPackage = null;
14781                callingUid = Binder.getCallingUid();
14782                callingPid = Binder.getCallingPid();
14783            }
14784
14785            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14786                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14787
14788            List allSticky = null;
14789
14790            // Look for any matching sticky broadcasts...
14791            Iterator actions = filter.actionsIterator();
14792            if (actions != null) {
14793                while (actions.hasNext()) {
14794                    String action = (String)actions.next();
14795                    allSticky = getStickiesLocked(action, filter, allSticky,
14796                            UserHandle.USER_ALL);
14797                    allSticky = getStickiesLocked(action, filter, allSticky,
14798                            UserHandle.getUserId(callingUid));
14799                }
14800            } else {
14801                allSticky = getStickiesLocked(null, filter, allSticky,
14802                        UserHandle.USER_ALL);
14803                allSticky = getStickiesLocked(null, filter, allSticky,
14804                        UserHandle.getUserId(callingUid));
14805            }
14806
14807            // The first sticky in the list is returned directly back to
14808            // the client.
14809            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14810
14811            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14812                    + ": " + sticky);
14813
14814            if (receiver == null) {
14815                return sticky;
14816            }
14817
14818            ReceiverList rl
14819                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14820            if (rl == null) {
14821                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14822                        userId, receiver);
14823                if (rl.app != null) {
14824                    rl.app.receivers.add(rl);
14825                } else {
14826                    try {
14827                        receiver.asBinder().linkToDeath(rl, 0);
14828                    } catch (RemoteException e) {
14829                        return sticky;
14830                    }
14831                    rl.linkedToDeath = true;
14832                }
14833                mRegisteredReceivers.put(receiver.asBinder(), rl);
14834            } else if (rl.uid != callingUid) {
14835                throw new IllegalArgumentException(
14836                        "Receiver requested to register for uid " + callingUid
14837                        + " was previously registered for uid " + rl.uid);
14838            } else if (rl.pid != callingPid) {
14839                throw new IllegalArgumentException(
14840                        "Receiver requested to register for pid " + callingPid
14841                        + " was previously registered for pid " + rl.pid);
14842            } else if (rl.userId != userId) {
14843                throw new IllegalArgumentException(
14844                        "Receiver requested to register for user " + userId
14845                        + " was previously registered for user " + rl.userId);
14846            }
14847            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14848                    permission, callingUid, userId);
14849            rl.add(bf);
14850            if (!bf.debugCheck()) {
14851                Slog.w(TAG, "==> For Dynamic broadast");
14852            }
14853            mReceiverResolver.addFilter(bf);
14854
14855            // Enqueue broadcasts for all existing stickies that match
14856            // this filter.
14857            if (allSticky != null) {
14858                ArrayList receivers = new ArrayList();
14859                receivers.add(bf);
14860
14861                int N = allSticky.size();
14862                for (int i=0; i<N; i++) {
14863                    Intent intent = (Intent)allSticky.get(i);
14864                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14865                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14866                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14867                            null, null, false, true, true, -1);
14868                    queue.enqueueParallelBroadcastLocked(r);
14869                    queue.scheduleBroadcastsLocked();
14870                }
14871            }
14872
14873            return sticky;
14874        }
14875    }
14876
14877    public void unregisterReceiver(IIntentReceiver receiver) {
14878        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14879
14880        final long origId = Binder.clearCallingIdentity();
14881        try {
14882            boolean doTrim = false;
14883
14884            synchronized(this) {
14885                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14886                if (rl != null) {
14887                    if (rl.curBroadcast != null) {
14888                        BroadcastRecord r = rl.curBroadcast;
14889                        final boolean doNext = finishReceiverLocked(
14890                                receiver.asBinder(), r.resultCode, r.resultData,
14891                                r.resultExtras, r.resultAbort);
14892                        if (doNext) {
14893                            doTrim = true;
14894                            r.queue.processNextBroadcast(false);
14895                        }
14896                    }
14897
14898                    if (rl.app != null) {
14899                        rl.app.receivers.remove(rl);
14900                    }
14901                    removeReceiverLocked(rl);
14902                    if (rl.linkedToDeath) {
14903                        rl.linkedToDeath = false;
14904                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14905                    }
14906                }
14907            }
14908
14909            // If we actually concluded any broadcasts, we might now be able
14910            // to trim the recipients' apps from our working set
14911            if (doTrim) {
14912                trimApplications();
14913                return;
14914            }
14915
14916        } finally {
14917            Binder.restoreCallingIdentity(origId);
14918        }
14919    }
14920
14921    void removeReceiverLocked(ReceiverList rl) {
14922        mRegisteredReceivers.remove(rl.receiver.asBinder());
14923        int N = rl.size();
14924        for (int i=0; i<N; i++) {
14925            mReceiverResolver.removeFilter(rl.get(i));
14926        }
14927    }
14928
14929    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14930        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14931            ProcessRecord r = mLruProcesses.get(i);
14932            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14933                try {
14934                    r.thread.dispatchPackageBroadcast(cmd, packages);
14935                } catch (RemoteException ex) {
14936                }
14937            }
14938        }
14939    }
14940
14941    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14942            int[] users) {
14943        List<ResolveInfo> receivers = null;
14944        try {
14945            HashSet<ComponentName> singleUserReceivers = null;
14946            boolean scannedFirstReceivers = false;
14947            for (int user : users) {
14948                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14949                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14950                if (user != 0 && newReceivers != null) {
14951                    // If this is not the primary user, we need to check for
14952                    // any receivers that should be filtered out.
14953                    for (int i=0; i<newReceivers.size(); i++) {
14954                        ResolveInfo ri = newReceivers.get(i);
14955                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14956                            newReceivers.remove(i);
14957                            i--;
14958                        }
14959                    }
14960                }
14961                if (newReceivers != null && newReceivers.size() == 0) {
14962                    newReceivers = null;
14963                }
14964                if (receivers == null) {
14965                    receivers = newReceivers;
14966                } else if (newReceivers != null) {
14967                    // We need to concatenate the additional receivers
14968                    // found with what we have do far.  This would be easy,
14969                    // but we also need to de-dup any receivers that are
14970                    // singleUser.
14971                    if (!scannedFirstReceivers) {
14972                        // Collect any single user receivers we had already retrieved.
14973                        scannedFirstReceivers = true;
14974                        for (int i=0; i<receivers.size(); i++) {
14975                            ResolveInfo ri = receivers.get(i);
14976                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14977                                ComponentName cn = new ComponentName(
14978                                        ri.activityInfo.packageName, ri.activityInfo.name);
14979                                if (singleUserReceivers == null) {
14980                                    singleUserReceivers = new HashSet<ComponentName>();
14981                                }
14982                                singleUserReceivers.add(cn);
14983                            }
14984                        }
14985                    }
14986                    // Add the new results to the existing results, tracking
14987                    // and de-dupping single user receivers.
14988                    for (int i=0; i<newReceivers.size(); i++) {
14989                        ResolveInfo ri = newReceivers.get(i);
14990                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14991                            ComponentName cn = new ComponentName(
14992                                    ri.activityInfo.packageName, ri.activityInfo.name);
14993                            if (singleUserReceivers == null) {
14994                                singleUserReceivers = new HashSet<ComponentName>();
14995                            }
14996                            if (!singleUserReceivers.contains(cn)) {
14997                                singleUserReceivers.add(cn);
14998                                receivers.add(ri);
14999                            }
15000                        } else {
15001                            receivers.add(ri);
15002                        }
15003                    }
15004                }
15005            }
15006        } catch (RemoteException ex) {
15007            // pm is in same process, this will never happen.
15008        }
15009        return receivers;
15010    }
15011
15012    private final int broadcastIntentLocked(ProcessRecord callerApp,
15013            String callerPackage, Intent intent, String resolvedType,
15014            IIntentReceiver resultTo, int resultCode, String resultData,
15015            Bundle map, String requiredPermission, int appOp,
15016            boolean ordered, boolean sticky, int callingPid, int callingUid,
15017            int userId) {
15018        intent = new Intent(intent);
15019
15020        // By default broadcasts do not go to stopped apps.
15021        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15022
15023        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15024            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15025            + " ordered=" + ordered + " userid=" + userId);
15026        if ((resultTo != null) && !ordered) {
15027            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15028        }
15029
15030        userId = handleIncomingUser(callingPid, callingUid, userId,
15031                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15032
15033        // Make sure that the user who is receiving this broadcast is started.
15034        // If not, we will just skip it.
15035
15036
15037        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15038            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15039                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15040                Slog.w(TAG, "Skipping broadcast of " + intent
15041                        + ": user " + userId + " is stopped");
15042                return ActivityManager.BROADCAST_SUCCESS;
15043            }
15044        }
15045
15046        /*
15047         * Prevent non-system code (defined here to be non-persistent
15048         * processes) from sending protected broadcasts.
15049         */
15050        int callingAppId = UserHandle.getAppId(callingUid);
15051        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15052            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15053            || callingAppId == Process.NFC_UID || callingUid == 0) {
15054            // Always okay.
15055        } else if (callerApp == null || !callerApp.persistent) {
15056            try {
15057                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15058                        intent.getAction())) {
15059                    String msg = "Permission Denial: not allowed to send broadcast "
15060                            + intent.getAction() + " from pid="
15061                            + callingPid + ", uid=" + callingUid;
15062                    Slog.w(TAG, msg);
15063                    throw new SecurityException(msg);
15064                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15065                    // Special case for compatibility: we don't want apps to send this,
15066                    // but historically it has not been protected and apps may be using it
15067                    // to poke their own app widget.  So, instead of making it protected,
15068                    // just limit it to the caller.
15069                    if (callerApp == null) {
15070                        String msg = "Permission Denial: not allowed to send broadcast "
15071                                + intent.getAction() + " from unknown caller.";
15072                        Slog.w(TAG, msg);
15073                        throw new SecurityException(msg);
15074                    } else if (intent.getComponent() != null) {
15075                        // They are good enough to send to an explicit component...  verify
15076                        // it is being sent to the calling app.
15077                        if (!intent.getComponent().getPackageName().equals(
15078                                callerApp.info.packageName)) {
15079                            String msg = "Permission Denial: not allowed to send broadcast "
15080                                    + intent.getAction() + " to "
15081                                    + intent.getComponent().getPackageName() + " from "
15082                                    + callerApp.info.packageName;
15083                            Slog.w(TAG, msg);
15084                            throw new SecurityException(msg);
15085                        }
15086                    } else {
15087                        // Limit broadcast to their own package.
15088                        intent.setPackage(callerApp.info.packageName);
15089                    }
15090                }
15091            } catch (RemoteException e) {
15092                Slog.w(TAG, "Remote exception", e);
15093                return ActivityManager.BROADCAST_SUCCESS;
15094            }
15095        }
15096
15097        // Handle special intents: if this broadcast is from the package
15098        // manager about a package being removed, we need to remove all of
15099        // its activities from the history stack.
15100        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15101                intent.getAction());
15102        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15103                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15104                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15105                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15106                || uidRemoved) {
15107            if (checkComponentPermission(
15108                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15109                    callingPid, callingUid, -1, true)
15110                    == PackageManager.PERMISSION_GRANTED) {
15111                if (uidRemoved) {
15112                    final Bundle intentExtras = intent.getExtras();
15113                    final int uid = intentExtras != null
15114                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15115                    if (uid >= 0) {
15116                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15117                        synchronized (bs) {
15118                            bs.removeUidStatsLocked(uid);
15119                        }
15120                        mAppOpsService.uidRemoved(uid);
15121                    }
15122                } else {
15123                    // If resources are unavailable just force stop all
15124                    // those packages and flush the attribute cache as well.
15125                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15126                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15127                        if (list != null && (list.length > 0)) {
15128                            for (String pkg : list) {
15129                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15130                                        "storage unmount");
15131                            }
15132                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15133                            sendPackageBroadcastLocked(
15134                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15135                        }
15136                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15137                            intent.getAction())) {
15138                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15139                    } else {
15140                        Uri data = intent.getData();
15141                        String ssp;
15142                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15143                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15144                                    intent.getAction());
15145                            boolean fullUninstall = removed &&
15146                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15147                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15148                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15149                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15150                                        false, fullUninstall, userId,
15151                                        removed ? "pkg removed" : "pkg changed");
15152                            }
15153                            if (removed) {
15154                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15155                                        new String[] {ssp}, userId);
15156                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15157                                    mAppOpsService.packageRemoved(
15158                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15159
15160                                    // Remove all permissions granted from/to this package
15161                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15162                                }
15163                            }
15164                        }
15165                    }
15166                }
15167            } else {
15168                String msg = "Permission Denial: " + intent.getAction()
15169                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15170                        + ", uid=" + callingUid + ")"
15171                        + " requires "
15172                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15173                Slog.w(TAG, msg);
15174                throw new SecurityException(msg);
15175            }
15176
15177        // Special case for adding a package: by default turn on compatibility
15178        // mode.
15179        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15180            Uri data = intent.getData();
15181            String ssp;
15182            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15183                mCompatModePackages.handlePackageAddedLocked(ssp,
15184                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15185            }
15186        }
15187
15188        /*
15189         * If this is the time zone changed action, queue up a message that will reset the timezone
15190         * of all currently running processes. This message will get queued up before the broadcast
15191         * happens.
15192         */
15193        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15194            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15195        }
15196
15197        /*
15198         * If the user set the time, let all running processes know.
15199         */
15200        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15201            final int is24Hour = intent.getBooleanExtra(
15202                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15203            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15204        }
15205
15206        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15207            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15208        }
15209
15210        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15211            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15212            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15213        }
15214
15215        // Add to the sticky list if requested.
15216        if (sticky) {
15217            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15218                    callingPid, callingUid)
15219                    != PackageManager.PERMISSION_GRANTED) {
15220                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15221                        + callingPid + ", uid=" + callingUid
15222                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15223                Slog.w(TAG, msg);
15224                throw new SecurityException(msg);
15225            }
15226            if (requiredPermission != null) {
15227                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15228                        + " and enforce permission " + requiredPermission);
15229                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15230            }
15231            if (intent.getComponent() != null) {
15232                throw new SecurityException(
15233                        "Sticky broadcasts can't target a specific component");
15234            }
15235            // We use userId directly here, since the "all" target is maintained
15236            // as a separate set of sticky broadcasts.
15237            if (userId != UserHandle.USER_ALL) {
15238                // But first, if this is not a broadcast to all users, then
15239                // make sure it doesn't conflict with an existing broadcast to
15240                // all users.
15241                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15242                        UserHandle.USER_ALL);
15243                if (stickies != null) {
15244                    ArrayList<Intent> list = stickies.get(intent.getAction());
15245                    if (list != null) {
15246                        int N = list.size();
15247                        int i;
15248                        for (i=0; i<N; i++) {
15249                            if (intent.filterEquals(list.get(i))) {
15250                                throw new IllegalArgumentException(
15251                                        "Sticky broadcast " + intent + " for user "
15252                                        + userId + " conflicts with existing global broadcast");
15253                            }
15254                        }
15255                    }
15256                }
15257            }
15258            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15259            if (stickies == null) {
15260                stickies = new ArrayMap<String, ArrayList<Intent>>();
15261                mStickyBroadcasts.put(userId, stickies);
15262            }
15263            ArrayList<Intent> list = stickies.get(intent.getAction());
15264            if (list == null) {
15265                list = new ArrayList<Intent>();
15266                stickies.put(intent.getAction(), list);
15267            }
15268            int N = list.size();
15269            int i;
15270            for (i=0; i<N; i++) {
15271                if (intent.filterEquals(list.get(i))) {
15272                    // This sticky already exists, replace it.
15273                    list.set(i, new Intent(intent));
15274                    break;
15275                }
15276            }
15277            if (i >= N) {
15278                list.add(new Intent(intent));
15279            }
15280        }
15281
15282        int[] users;
15283        if (userId == UserHandle.USER_ALL) {
15284            // Caller wants broadcast to go to all started users.
15285            users = mStartedUserArray;
15286        } else {
15287            // Caller wants broadcast to go to one specific user.
15288            users = new int[] {userId};
15289        }
15290
15291        // Figure out who all will receive this broadcast.
15292        List receivers = null;
15293        List<BroadcastFilter> registeredReceivers = null;
15294        // Need to resolve the intent to interested receivers...
15295        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15296                 == 0) {
15297            receivers = collectReceiverComponents(intent, resolvedType, users);
15298        }
15299        if (intent.getComponent() == null) {
15300            registeredReceivers = mReceiverResolver.queryIntent(intent,
15301                    resolvedType, false, userId);
15302        }
15303
15304        final boolean replacePending =
15305                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15306
15307        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15308                + " replacePending=" + replacePending);
15309
15310        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15311        if (!ordered && NR > 0) {
15312            // If we are not serializing this broadcast, then send the
15313            // registered receivers separately so they don't wait for the
15314            // components to be launched.
15315            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15316            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15317                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15318                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15319                    ordered, sticky, false, userId);
15320            if (DEBUG_BROADCAST) Slog.v(
15321                    TAG, "Enqueueing parallel broadcast " + r);
15322            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15323            if (!replaced) {
15324                queue.enqueueParallelBroadcastLocked(r);
15325                queue.scheduleBroadcastsLocked();
15326            }
15327            registeredReceivers = null;
15328            NR = 0;
15329        }
15330
15331        // Merge into one list.
15332        int ir = 0;
15333        if (receivers != null) {
15334            // A special case for PACKAGE_ADDED: do not allow the package
15335            // being added to see this broadcast.  This prevents them from
15336            // using this as a back door to get run as soon as they are
15337            // installed.  Maybe in the future we want to have a special install
15338            // broadcast or such for apps, but we'd like to deliberately make
15339            // this decision.
15340            String skipPackages[] = null;
15341            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15342                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15343                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15344                Uri data = intent.getData();
15345                if (data != null) {
15346                    String pkgName = data.getSchemeSpecificPart();
15347                    if (pkgName != null) {
15348                        skipPackages = new String[] { pkgName };
15349                    }
15350                }
15351            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15352                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15353            }
15354            if (skipPackages != null && (skipPackages.length > 0)) {
15355                for (String skipPackage : skipPackages) {
15356                    if (skipPackage != null) {
15357                        int NT = receivers.size();
15358                        for (int it=0; it<NT; it++) {
15359                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15360                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15361                                receivers.remove(it);
15362                                it--;
15363                                NT--;
15364                            }
15365                        }
15366                    }
15367                }
15368            }
15369
15370            int NT = receivers != null ? receivers.size() : 0;
15371            int it = 0;
15372            ResolveInfo curt = null;
15373            BroadcastFilter curr = null;
15374            while (it < NT && ir < NR) {
15375                if (curt == null) {
15376                    curt = (ResolveInfo)receivers.get(it);
15377                }
15378                if (curr == null) {
15379                    curr = registeredReceivers.get(ir);
15380                }
15381                if (curr.getPriority() >= curt.priority) {
15382                    // Insert this broadcast record into the final list.
15383                    receivers.add(it, curr);
15384                    ir++;
15385                    curr = null;
15386                    it++;
15387                    NT++;
15388                } else {
15389                    // Skip to the next ResolveInfo in the final list.
15390                    it++;
15391                    curt = null;
15392                }
15393            }
15394        }
15395        while (ir < NR) {
15396            if (receivers == null) {
15397                receivers = new ArrayList();
15398            }
15399            receivers.add(registeredReceivers.get(ir));
15400            ir++;
15401        }
15402
15403        if ((receivers != null && receivers.size() > 0)
15404                || resultTo != null) {
15405            BroadcastQueue queue = broadcastQueueForIntent(intent);
15406            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15407                    callerPackage, callingPid, callingUid, resolvedType,
15408                    requiredPermission, appOp, receivers, resultTo, resultCode,
15409                    resultData, map, ordered, sticky, false, userId);
15410            if (DEBUG_BROADCAST) Slog.v(
15411                    TAG, "Enqueueing ordered broadcast " + r
15412                    + ": prev had " + queue.mOrderedBroadcasts.size());
15413            if (DEBUG_BROADCAST) {
15414                int seq = r.intent.getIntExtra("seq", -1);
15415                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15416            }
15417            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15418            if (!replaced) {
15419                queue.enqueueOrderedBroadcastLocked(r);
15420                queue.scheduleBroadcastsLocked();
15421            }
15422        }
15423
15424        return ActivityManager.BROADCAST_SUCCESS;
15425    }
15426
15427    final Intent verifyBroadcastLocked(Intent intent) {
15428        // Refuse possible leaked file descriptors
15429        if (intent != null && intent.hasFileDescriptors() == true) {
15430            throw new IllegalArgumentException("File descriptors passed in Intent");
15431        }
15432
15433        int flags = intent.getFlags();
15434
15435        if (!mProcessesReady) {
15436            // if the caller really truly claims to know what they're doing, go
15437            // ahead and allow the broadcast without launching any receivers
15438            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15439                intent = new Intent(intent);
15440                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15441            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15442                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15443                        + " before boot completion");
15444                throw new IllegalStateException("Cannot broadcast before boot completed");
15445            }
15446        }
15447
15448        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15449            throw new IllegalArgumentException(
15450                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15451        }
15452
15453        return intent;
15454    }
15455
15456    public final int broadcastIntent(IApplicationThread caller,
15457            Intent intent, String resolvedType, IIntentReceiver resultTo,
15458            int resultCode, String resultData, Bundle map,
15459            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15460        enforceNotIsolatedCaller("broadcastIntent");
15461        synchronized(this) {
15462            intent = verifyBroadcastLocked(intent);
15463
15464            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15465            final int callingPid = Binder.getCallingPid();
15466            final int callingUid = Binder.getCallingUid();
15467            final long origId = Binder.clearCallingIdentity();
15468            int res = broadcastIntentLocked(callerApp,
15469                    callerApp != null ? callerApp.info.packageName : null,
15470                    intent, resolvedType, resultTo,
15471                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15472                    callingPid, callingUid, userId);
15473            Binder.restoreCallingIdentity(origId);
15474            return res;
15475        }
15476    }
15477
15478    int broadcastIntentInPackage(String packageName, int uid,
15479            Intent intent, String resolvedType, IIntentReceiver resultTo,
15480            int resultCode, String resultData, Bundle map,
15481            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15482        synchronized(this) {
15483            intent = verifyBroadcastLocked(intent);
15484
15485            final long origId = Binder.clearCallingIdentity();
15486            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15487                    resultTo, resultCode, resultData, map, requiredPermission,
15488                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15489            Binder.restoreCallingIdentity(origId);
15490            return res;
15491        }
15492    }
15493
15494    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15495        // Refuse possible leaked file descriptors
15496        if (intent != null && intent.hasFileDescriptors() == true) {
15497            throw new IllegalArgumentException("File descriptors passed in Intent");
15498        }
15499
15500        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15501                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15502
15503        synchronized(this) {
15504            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15505                    != PackageManager.PERMISSION_GRANTED) {
15506                String msg = "Permission Denial: unbroadcastIntent() from pid="
15507                        + Binder.getCallingPid()
15508                        + ", uid=" + Binder.getCallingUid()
15509                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15510                Slog.w(TAG, msg);
15511                throw new SecurityException(msg);
15512            }
15513            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15514            if (stickies != null) {
15515                ArrayList<Intent> list = stickies.get(intent.getAction());
15516                if (list != null) {
15517                    int N = list.size();
15518                    int i;
15519                    for (i=0; i<N; i++) {
15520                        if (intent.filterEquals(list.get(i))) {
15521                            list.remove(i);
15522                            break;
15523                        }
15524                    }
15525                    if (list.size() <= 0) {
15526                        stickies.remove(intent.getAction());
15527                    }
15528                }
15529                if (stickies.size() <= 0) {
15530                    mStickyBroadcasts.remove(userId);
15531                }
15532            }
15533        }
15534    }
15535
15536    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15537            String resultData, Bundle resultExtras, boolean resultAbort) {
15538        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15539        if (r == null) {
15540            Slog.w(TAG, "finishReceiver called but not found on queue");
15541            return false;
15542        }
15543
15544        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15545    }
15546
15547    void backgroundServicesFinishedLocked(int userId) {
15548        for (BroadcastQueue queue : mBroadcastQueues) {
15549            queue.backgroundServicesFinishedLocked(userId);
15550        }
15551    }
15552
15553    public void finishReceiver(IBinder who, int resultCode, String resultData,
15554            Bundle resultExtras, boolean resultAbort) {
15555        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15556
15557        // Refuse possible leaked file descriptors
15558        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15559            throw new IllegalArgumentException("File descriptors passed in Bundle");
15560        }
15561
15562        final long origId = Binder.clearCallingIdentity();
15563        try {
15564            boolean doNext = false;
15565            BroadcastRecord r;
15566
15567            synchronized(this) {
15568                r = broadcastRecordForReceiverLocked(who);
15569                if (r != null) {
15570                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15571                        resultData, resultExtras, resultAbort, true);
15572                }
15573            }
15574
15575            if (doNext) {
15576                r.queue.processNextBroadcast(false);
15577            }
15578            trimApplications();
15579        } finally {
15580            Binder.restoreCallingIdentity(origId);
15581        }
15582    }
15583
15584    // =========================================================
15585    // INSTRUMENTATION
15586    // =========================================================
15587
15588    public boolean startInstrumentation(ComponentName className,
15589            String profileFile, int flags, Bundle arguments,
15590            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15591            int userId, String abiOverride) {
15592        enforceNotIsolatedCaller("startInstrumentation");
15593        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15594                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15595        // Refuse possible leaked file descriptors
15596        if (arguments != null && arguments.hasFileDescriptors()) {
15597            throw new IllegalArgumentException("File descriptors passed in Bundle");
15598        }
15599
15600        synchronized(this) {
15601            InstrumentationInfo ii = null;
15602            ApplicationInfo ai = null;
15603            try {
15604                ii = mContext.getPackageManager().getInstrumentationInfo(
15605                    className, STOCK_PM_FLAGS);
15606                ai = AppGlobals.getPackageManager().getApplicationInfo(
15607                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15608            } catch (PackageManager.NameNotFoundException e) {
15609            } catch (RemoteException e) {
15610            }
15611            if (ii == null) {
15612                reportStartInstrumentationFailure(watcher, className,
15613                        "Unable to find instrumentation info for: " + className);
15614                return false;
15615            }
15616            if (ai == null) {
15617                reportStartInstrumentationFailure(watcher, className,
15618                        "Unable to find instrumentation target package: " + ii.targetPackage);
15619                return false;
15620            }
15621
15622            int match = mContext.getPackageManager().checkSignatures(
15623                    ii.targetPackage, ii.packageName);
15624            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15625                String msg = "Permission Denial: starting instrumentation "
15626                        + className + " from pid="
15627                        + Binder.getCallingPid()
15628                        + ", uid=" + Binder.getCallingPid()
15629                        + " not allowed because package " + ii.packageName
15630                        + " does not have a signature matching the target "
15631                        + ii.targetPackage;
15632                reportStartInstrumentationFailure(watcher, className, msg);
15633                throw new SecurityException(msg);
15634            }
15635
15636            final long origId = Binder.clearCallingIdentity();
15637            // Instrumentation can kill and relaunch even persistent processes
15638            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15639                    "start instr");
15640            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15641            app.instrumentationClass = className;
15642            app.instrumentationInfo = ai;
15643            app.instrumentationProfileFile = profileFile;
15644            app.instrumentationArguments = arguments;
15645            app.instrumentationWatcher = watcher;
15646            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15647            app.instrumentationResultClass = className;
15648            Binder.restoreCallingIdentity(origId);
15649        }
15650
15651        return true;
15652    }
15653
15654    /**
15655     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15656     * error to the logs, but if somebody is watching, send the report there too.  This enables
15657     * the "am" command to report errors with more information.
15658     *
15659     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15660     * @param cn The component name of the instrumentation.
15661     * @param report The error report.
15662     */
15663    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15664            ComponentName cn, String report) {
15665        Slog.w(TAG, report);
15666        try {
15667            if (watcher != null) {
15668                Bundle results = new Bundle();
15669                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15670                results.putString("Error", report);
15671                watcher.instrumentationStatus(cn, -1, results);
15672            }
15673        } catch (RemoteException e) {
15674            Slog.w(TAG, e);
15675        }
15676    }
15677
15678    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15679        if (app.instrumentationWatcher != null) {
15680            try {
15681                // NOTE:  IInstrumentationWatcher *must* be oneway here
15682                app.instrumentationWatcher.instrumentationFinished(
15683                    app.instrumentationClass,
15684                    resultCode,
15685                    results);
15686            } catch (RemoteException e) {
15687            }
15688        }
15689        if (app.instrumentationUiAutomationConnection != null) {
15690            try {
15691                app.instrumentationUiAutomationConnection.shutdown();
15692            } catch (RemoteException re) {
15693                /* ignore */
15694            }
15695            // Only a UiAutomation can set this flag and now that
15696            // it is finished we make sure it is reset to its default.
15697            mUserIsMonkey = false;
15698        }
15699        app.instrumentationWatcher = null;
15700        app.instrumentationUiAutomationConnection = null;
15701        app.instrumentationClass = null;
15702        app.instrumentationInfo = null;
15703        app.instrumentationProfileFile = null;
15704        app.instrumentationArguments = null;
15705
15706        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15707                "finished inst");
15708    }
15709
15710    public void finishInstrumentation(IApplicationThread target,
15711            int resultCode, Bundle results) {
15712        int userId = UserHandle.getCallingUserId();
15713        // Refuse possible leaked file descriptors
15714        if (results != null && results.hasFileDescriptors()) {
15715            throw new IllegalArgumentException("File descriptors passed in Intent");
15716        }
15717
15718        synchronized(this) {
15719            ProcessRecord app = getRecordForAppLocked(target);
15720            if (app == null) {
15721                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15722                return;
15723            }
15724            final long origId = Binder.clearCallingIdentity();
15725            finishInstrumentationLocked(app, resultCode, results);
15726            Binder.restoreCallingIdentity(origId);
15727        }
15728    }
15729
15730    // =========================================================
15731    // CONFIGURATION
15732    // =========================================================
15733
15734    public ConfigurationInfo getDeviceConfigurationInfo() {
15735        ConfigurationInfo config = new ConfigurationInfo();
15736        synchronized (this) {
15737            config.reqTouchScreen = mConfiguration.touchscreen;
15738            config.reqKeyboardType = mConfiguration.keyboard;
15739            config.reqNavigation = mConfiguration.navigation;
15740            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15741                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15742                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15743            }
15744            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15745                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15746                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15747            }
15748            config.reqGlEsVersion = GL_ES_VERSION;
15749        }
15750        return config;
15751    }
15752
15753    ActivityStack getFocusedStack() {
15754        return mStackSupervisor.getFocusedStack();
15755    }
15756
15757    public Configuration getConfiguration() {
15758        Configuration ci;
15759        synchronized(this) {
15760            ci = new Configuration(mConfiguration);
15761        }
15762        return ci;
15763    }
15764
15765    public void updatePersistentConfiguration(Configuration values) {
15766        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15767                "updateConfiguration()");
15768        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15769                "updateConfiguration()");
15770        if (values == null) {
15771            throw new NullPointerException("Configuration must not be null");
15772        }
15773
15774        synchronized(this) {
15775            final long origId = Binder.clearCallingIdentity();
15776            updateConfigurationLocked(values, null, true, false);
15777            Binder.restoreCallingIdentity(origId);
15778        }
15779    }
15780
15781    public void updateConfiguration(Configuration values) {
15782        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15783                "updateConfiguration()");
15784
15785        synchronized(this) {
15786            if (values == null && mWindowManager != null) {
15787                // sentinel: fetch the current configuration from the window manager
15788                values = mWindowManager.computeNewConfiguration();
15789            }
15790
15791            if (mWindowManager != null) {
15792                mProcessList.applyDisplaySize(mWindowManager);
15793            }
15794
15795            final long origId = Binder.clearCallingIdentity();
15796            if (values != null) {
15797                Settings.System.clearConfiguration(values);
15798            }
15799            updateConfigurationLocked(values, null, false, false);
15800            Binder.restoreCallingIdentity(origId);
15801        }
15802    }
15803
15804    /**
15805     * Do either or both things: (1) change the current configuration, and (2)
15806     * make sure the given activity is running with the (now) current
15807     * configuration.  Returns true if the activity has been left running, or
15808     * false if <var>starting</var> is being destroyed to match the new
15809     * configuration.
15810     * @param persistent TODO
15811     */
15812    boolean updateConfigurationLocked(Configuration values,
15813            ActivityRecord starting, boolean persistent, boolean initLocale) {
15814        int changes = 0;
15815
15816        if (values != null) {
15817            Configuration newConfig = new Configuration(mConfiguration);
15818            changes = newConfig.updateFrom(values);
15819            if (changes != 0) {
15820                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15821                    Slog.i(TAG, "Updating configuration to: " + values);
15822                }
15823
15824                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15825
15826                if (values.locale != null && !initLocale) {
15827                    saveLocaleLocked(values.locale,
15828                                     !values.locale.equals(mConfiguration.locale),
15829                                     values.userSetLocale);
15830                }
15831
15832                mConfigurationSeq++;
15833                if (mConfigurationSeq <= 0) {
15834                    mConfigurationSeq = 1;
15835                }
15836                newConfig.seq = mConfigurationSeq;
15837                mConfiguration = newConfig;
15838                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15839                //mUsageStatsService.noteStartConfig(newConfig);
15840
15841                final Configuration configCopy = new Configuration(mConfiguration);
15842
15843                // TODO: If our config changes, should we auto dismiss any currently
15844                // showing dialogs?
15845                mShowDialogs = shouldShowDialogs(newConfig);
15846
15847                AttributeCache ac = AttributeCache.instance();
15848                if (ac != null) {
15849                    ac.updateConfiguration(configCopy);
15850                }
15851
15852                // Make sure all resources in our process are updated
15853                // right now, so that anyone who is going to retrieve
15854                // resource values after we return will be sure to get
15855                // the new ones.  This is especially important during
15856                // boot, where the first config change needs to guarantee
15857                // all resources have that config before following boot
15858                // code is executed.
15859                mSystemThread.applyConfigurationToResources(configCopy);
15860
15861                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15862                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15863                    msg.obj = new Configuration(configCopy);
15864                    mHandler.sendMessage(msg);
15865                }
15866
15867                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15868                    ProcessRecord app = mLruProcesses.get(i);
15869                    try {
15870                        if (app.thread != null) {
15871                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15872                                    + app.processName + " new config " + mConfiguration);
15873                            app.thread.scheduleConfigurationChanged(configCopy);
15874                        }
15875                    } catch (Exception e) {
15876                    }
15877                }
15878                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15879                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15880                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15881                        | Intent.FLAG_RECEIVER_FOREGROUND);
15882                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15883                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15884                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15885                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15886                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15887                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15888                    broadcastIntentLocked(null, null, intent,
15889                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15890                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15891                }
15892            }
15893        }
15894
15895        boolean kept = true;
15896        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15897        // mainStack is null during startup.
15898        if (mainStack != null) {
15899            if (changes != 0 && starting == null) {
15900                // If the configuration changed, and the caller is not already
15901                // in the process of starting an activity, then find the top
15902                // activity to check if its configuration needs to change.
15903                starting = mainStack.topRunningActivityLocked(null);
15904            }
15905
15906            if (starting != null) {
15907                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15908                // And we need to make sure at this point that all other activities
15909                // are made visible with the correct configuration.
15910                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15911            }
15912        }
15913
15914        if (values != null && mWindowManager != null) {
15915            mWindowManager.setNewConfiguration(mConfiguration);
15916        }
15917
15918        return kept;
15919    }
15920
15921    /**
15922     * Decide based on the configuration whether we should shouw the ANR,
15923     * crash, etc dialogs.  The idea is that if there is no affordnace to
15924     * press the on-screen buttons, we shouldn't show the dialog.
15925     *
15926     * A thought: SystemUI might also want to get told about this, the Power
15927     * dialog / global actions also might want different behaviors.
15928     */
15929    private static final boolean shouldShowDialogs(Configuration config) {
15930        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15931                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15932    }
15933
15934    /**
15935     * Save the locale.  You must be inside a synchronized (this) block.
15936     */
15937    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15938        if(isDiff) {
15939            SystemProperties.set("user.language", l.getLanguage());
15940            SystemProperties.set("user.region", l.getCountry());
15941        }
15942
15943        if(isPersist) {
15944            SystemProperties.set("persist.sys.language", l.getLanguage());
15945            SystemProperties.set("persist.sys.country", l.getCountry());
15946            SystemProperties.set("persist.sys.localevar", l.getVariant());
15947        }
15948    }
15949
15950    @Override
15951    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
15952        synchronized (this) {
15953            ActivityRecord srec = ActivityRecord.forToken(token);
15954            if (srec.task != null && srec.task.stack != null) {
15955                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
15956            }
15957        }
15958        return false;
15959    }
15960
15961    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15962            Intent resultData) {
15963
15964        synchronized (this) {
15965            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15966            if (stack != null) {
15967                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15968            }
15969            return false;
15970        }
15971    }
15972
15973    public int getLaunchedFromUid(IBinder activityToken) {
15974        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15975        if (srec == null) {
15976            return -1;
15977        }
15978        return srec.launchedFromUid;
15979    }
15980
15981    public String getLaunchedFromPackage(IBinder activityToken) {
15982        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15983        if (srec == null) {
15984            return null;
15985        }
15986        return srec.launchedFromPackage;
15987    }
15988
15989    // =========================================================
15990    // LIFETIME MANAGEMENT
15991    // =========================================================
15992
15993    // Returns which broadcast queue the app is the current [or imminent] receiver
15994    // on, or 'null' if the app is not an active broadcast recipient.
15995    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15996        BroadcastRecord r = app.curReceiver;
15997        if (r != null) {
15998            return r.queue;
15999        }
16000
16001        // It's not the current receiver, but it might be starting up to become one
16002        synchronized (this) {
16003            for (BroadcastQueue queue : mBroadcastQueues) {
16004                r = queue.mPendingBroadcast;
16005                if (r != null && r.curApp == app) {
16006                    // found it; report which queue it's in
16007                    return queue;
16008                }
16009            }
16010        }
16011
16012        return null;
16013    }
16014
16015    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16016            boolean doingAll, long now) {
16017        if (mAdjSeq == app.adjSeq) {
16018            // This adjustment has already been computed.
16019            return app.curRawAdj;
16020        }
16021
16022        if (app.thread == null) {
16023            app.adjSeq = mAdjSeq;
16024            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16025            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16026            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16027        }
16028
16029        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16030        app.adjSource = null;
16031        app.adjTarget = null;
16032        app.empty = false;
16033        app.cached = false;
16034
16035        final int activitiesSize = app.activities.size();
16036
16037        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16038            // The max adjustment doesn't allow this app to be anything
16039            // below foreground, so it is not worth doing work for it.
16040            app.adjType = "fixed";
16041            app.adjSeq = mAdjSeq;
16042            app.curRawAdj = app.maxAdj;
16043            app.foregroundActivities = false;
16044            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16045            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16046            // System processes can do UI, and when they do we want to have
16047            // them trim their memory after the user leaves the UI.  To
16048            // facilitate this, here we need to determine whether or not it
16049            // is currently showing UI.
16050            app.systemNoUi = true;
16051            if (app == TOP_APP) {
16052                app.systemNoUi = false;
16053            } else if (activitiesSize > 0) {
16054                for (int j = 0; j < activitiesSize; j++) {
16055                    final ActivityRecord r = app.activities.get(j);
16056                    if (r.visible) {
16057                        app.systemNoUi = false;
16058                    }
16059                }
16060            }
16061            if (!app.systemNoUi) {
16062                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16063            }
16064            return (app.curAdj=app.maxAdj);
16065        }
16066
16067        app.systemNoUi = false;
16068
16069        // Determine the importance of the process, starting with most
16070        // important to least, and assign an appropriate OOM adjustment.
16071        int adj;
16072        int schedGroup;
16073        int procState;
16074        boolean foregroundActivities = false;
16075        BroadcastQueue queue;
16076        if (app == TOP_APP) {
16077            // The last app on the list is the foreground app.
16078            adj = ProcessList.FOREGROUND_APP_ADJ;
16079            schedGroup = Process.THREAD_GROUP_DEFAULT;
16080            app.adjType = "top-activity";
16081            foregroundActivities = true;
16082            procState = ActivityManager.PROCESS_STATE_TOP;
16083        } else if (app.instrumentationClass != null) {
16084            // Don't want to kill running instrumentation.
16085            adj = ProcessList.FOREGROUND_APP_ADJ;
16086            schedGroup = Process.THREAD_GROUP_DEFAULT;
16087            app.adjType = "instrumentation";
16088            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16089        } else if ((queue = isReceivingBroadcast(app)) != null) {
16090            // An app that is currently receiving a broadcast also
16091            // counts as being in the foreground for OOM killer purposes.
16092            // It's placed in a sched group based on the nature of the
16093            // broadcast as reflected by which queue it's active in.
16094            adj = ProcessList.FOREGROUND_APP_ADJ;
16095            schedGroup = (queue == mFgBroadcastQueue)
16096                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16097            app.adjType = "broadcast";
16098            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16099        } else if (app.executingServices.size() > 0) {
16100            // An app that is currently executing a service callback also
16101            // counts as being in the foreground.
16102            adj = ProcessList.FOREGROUND_APP_ADJ;
16103            schedGroup = app.execServicesFg ?
16104                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16105            app.adjType = "exec-service";
16106            procState = ActivityManager.PROCESS_STATE_SERVICE;
16107            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16108        } else {
16109            // As far as we know the process is empty.  We may change our mind later.
16110            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16111            // At this point we don't actually know the adjustment.  Use the cached adj
16112            // value that the caller wants us to.
16113            adj = cachedAdj;
16114            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16115            app.cached = true;
16116            app.empty = true;
16117            app.adjType = "cch-empty";
16118        }
16119
16120        // Examine all activities if not already foreground.
16121        if (!foregroundActivities && activitiesSize > 0) {
16122            for (int j = 0; j < activitiesSize; j++) {
16123                final ActivityRecord r = app.activities.get(j);
16124                if (r.app != app) {
16125                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16126                            + app + "?!?");
16127                    continue;
16128                }
16129                if (r.visible) {
16130                    // App has a visible activity; only upgrade adjustment.
16131                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16132                        adj = ProcessList.VISIBLE_APP_ADJ;
16133                        app.adjType = "visible";
16134                    }
16135                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16136                        procState = ActivityManager.PROCESS_STATE_TOP;
16137                    }
16138                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16139                    app.cached = false;
16140                    app.empty = false;
16141                    foregroundActivities = true;
16142                    break;
16143                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16144                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16145                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16146                        app.adjType = "pausing";
16147                    }
16148                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16149                        procState = ActivityManager.PROCESS_STATE_TOP;
16150                    }
16151                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16152                    app.cached = false;
16153                    app.empty = false;
16154                    foregroundActivities = true;
16155                } else if (r.state == ActivityState.STOPPING) {
16156                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16157                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16158                        app.adjType = "stopping";
16159                    }
16160                    // For the process state, we will at this point consider the
16161                    // process to be cached.  It will be cached either as an activity
16162                    // or empty depending on whether the activity is finishing.  We do
16163                    // this so that we can treat the process as cached for purposes of
16164                    // memory trimming (determing current memory level, trim command to
16165                    // send to process) since there can be an arbitrary number of stopping
16166                    // processes and they should soon all go into the cached state.
16167                    if (!r.finishing) {
16168                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16169                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16170                        }
16171                    }
16172                    app.cached = false;
16173                    app.empty = false;
16174                    foregroundActivities = true;
16175                } else {
16176                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16177                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16178                        app.adjType = "cch-act";
16179                    }
16180                }
16181            }
16182        }
16183
16184        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16185            if (app.foregroundServices) {
16186                // The user is aware of this app, so make it visible.
16187                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16188                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16189                app.cached = false;
16190                app.adjType = "fg-service";
16191                schedGroup = Process.THREAD_GROUP_DEFAULT;
16192            } else if (app.forcingToForeground != null) {
16193                // The user is aware of this app, so make it visible.
16194                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16195                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16196                app.cached = false;
16197                app.adjType = "force-fg";
16198                app.adjSource = app.forcingToForeground;
16199                schedGroup = Process.THREAD_GROUP_DEFAULT;
16200            }
16201        }
16202
16203        if (app == mHeavyWeightProcess) {
16204            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16205                // We don't want to kill the current heavy-weight process.
16206                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16207                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16208                app.cached = false;
16209                app.adjType = "heavy";
16210            }
16211            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16212                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16213            }
16214        }
16215
16216        if (app == mHomeProcess) {
16217            if (adj > ProcessList.HOME_APP_ADJ) {
16218                // This process is hosting what we currently consider to be the
16219                // home app, so we don't want to let it go into the background.
16220                adj = ProcessList.HOME_APP_ADJ;
16221                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16222                app.cached = false;
16223                app.adjType = "home";
16224            }
16225            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16226                procState = ActivityManager.PROCESS_STATE_HOME;
16227            }
16228        }
16229
16230        if (app == mPreviousProcess && app.activities.size() > 0) {
16231            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16232                // This was the previous process that showed UI to the user.
16233                // We want to try to keep it around more aggressively, to give
16234                // a good experience around switching between two apps.
16235                adj = ProcessList.PREVIOUS_APP_ADJ;
16236                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16237                app.cached = false;
16238                app.adjType = "previous";
16239            }
16240            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16241                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16242            }
16243        }
16244
16245        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16246                + " reason=" + app.adjType);
16247
16248        // By default, we use the computed adjustment.  It may be changed if
16249        // there are applications dependent on our services or providers, but
16250        // this gives us a baseline and makes sure we don't get into an
16251        // infinite recursion.
16252        app.adjSeq = mAdjSeq;
16253        app.curRawAdj = adj;
16254        app.hasStartedServices = false;
16255
16256        if (mBackupTarget != null && app == mBackupTarget.app) {
16257            // If possible we want to avoid killing apps while they're being backed up
16258            if (adj > ProcessList.BACKUP_APP_ADJ) {
16259                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16260                adj = ProcessList.BACKUP_APP_ADJ;
16261                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16262                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16263                }
16264                app.adjType = "backup";
16265                app.cached = false;
16266            }
16267            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16268                procState = ActivityManager.PROCESS_STATE_BACKUP;
16269            }
16270        }
16271
16272        boolean mayBeTop = false;
16273
16274        for (int is = app.services.size()-1;
16275                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16276                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16277                        || procState > ActivityManager.PROCESS_STATE_TOP);
16278                is--) {
16279            ServiceRecord s = app.services.valueAt(is);
16280            if (s.startRequested) {
16281                app.hasStartedServices = true;
16282                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16283                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16284                }
16285                if (app.hasShownUi && app != mHomeProcess) {
16286                    // If this process has shown some UI, let it immediately
16287                    // go to the LRU list because it may be pretty heavy with
16288                    // UI stuff.  We'll tag it with a label just to help
16289                    // debug and understand what is going on.
16290                    if (adj > ProcessList.SERVICE_ADJ) {
16291                        app.adjType = "cch-started-ui-services";
16292                    }
16293                } else {
16294                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16295                        // This service has seen some activity within
16296                        // recent memory, so we will keep its process ahead
16297                        // of the background processes.
16298                        if (adj > ProcessList.SERVICE_ADJ) {
16299                            adj = ProcessList.SERVICE_ADJ;
16300                            app.adjType = "started-services";
16301                            app.cached = false;
16302                        }
16303                    }
16304                    // If we have let the service slide into the background
16305                    // state, still have some text describing what it is doing
16306                    // even though the service no longer has an impact.
16307                    if (adj > ProcessList.SERVICE_ADJ) {
16308                        app.adjType = "cch-started-services";
16309                    }
16310                }
16311            }
16312            for (int conni = s.connections.size()-1;
16313                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16314                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16315                            || procState > ActivityManager.PROCESS_STATE_TOP);
16316                    conni--) {
16317                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16318                for (int i = 0;
16319                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16320                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16321                                || procState > ActivityManager.PROCESS_STATE_TOP);
16322                        i++) {
16323                    // XXX should compute this based on the max of
16324                    // all connected clients.
16325                    ConnectionRecord cr = clist.get(i);
16326                    if (cr.binding.client == app) {
16327                        // Binding to ourself is not interesting.
16328                        continue;
16329                    }
16330                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16331                        ProcessRecord client = cr.binding.client;
16332                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16333                                TOP_APP, doingAll, now);
16334                        int clientProcState = client.curProcState;
16335                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16336                            // If the other app is cached for any reason, for purposes here
16337                            // we are going to consider it empty.  The specific cached state
16338                            // doesn't propagate except under certain conditions.
16339                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16340                        }
16341                        String adjType = null;
16342                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16343                            // Not doing bind OOM management, so treat
16344                            // this guy more like a started service.
16345                            if (app.hasShownUi && app != mHomeProcess) {
16346                                // If this process has shown some UI, let it immediately
16347                                // go to the LRU list because it may be pretty heavy with
16348                                // UI stuff.  We'll tag it with a label just to help
16349                                // debug and understand what is going on.
16350                                if (adj > clientAdj) {
16351                                    adjType = "cch-bound-ui-services";
16352                                }
16353                                app.cached = false;
16354                                clientAdj = adj;
16355                                clientProcState = procState;
16356                            } else {
16357                                if (now >= (s.lastActivity
16358                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16359                                    // This service has not seen activity within
16360                                    // recent memory, so allow it to drop to the
16361                                    // LRU list if there is no other reason to keep
16362                                    // it around.  We'll also tag it with a label just
16363                                    // to help debug and undertand what is going on.
16364                                    if (adj > clientAdj) {
16365                                        adjType = "cch-bound-services";
16366                                    }
16367                                    clientAdj = adj;
16368                                }
16369                            }
16370                        }
16371                        if (adj > clientAdj) {
16372                            // If this process has recently shown UI, and
16373                            // the process that is binding to it is less
16374                            // important than being visible, then we don't
16375                            // care about the binding as much as we care
16376                            // about letting this process get into the LRU
16377                            // list to be killed and restarted if needed for
16378                            // memory.
16379                            if (app.hasShownUi && app != mHomeProcess
16380                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16381                                adjType = "cch-bound-ui-services";
16382                            } else {
16383                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16384                                        |Context.BIND_IMPORTANT)) != 0) {
16385                                    adj = clientAdj;
16386                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16387                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16388                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16389                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16390                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16391                                    adj = clientAdj;
16392                                } else {
16393                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16394                                        adj = ProcessList.VISIBLE_APP_ADJ;
16395                                    }
16396                                }
16397                                if (!client.cached) {
16398                                    app.cached = false;
16399                                }
16400                                adjType = "service";
16401                            }
16402                        }
16403                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16404                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16405                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16406                            }
16407                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16408                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16409                                    // Special handling of clients who are in the top state.
16410                                    // We *may* want to consider this process to be in the
16411                                    // top state as well, but only if there is not another
16412                                    // reason for it to be running.  Being on the top is a
16413                                    // special state, meaning you are specifically running
16414                                    // for the current top app.  If the process is already
16415                                    // running in the background for some other reason, it
16416                                    // is more important to continue considering it to be
16417                                    // in the background state.
16418                                    mayBeTop = true;
16419                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16420                                } else {
16421                                    // Special handling for above-top states (persistent
16422                                    // processes).  These should not bring the current process
16423                                    // into the top state, since they are not on top.  Instead
16424                                    // give them the best state after that.
16425                                    clientProcState =
16426                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16427                                }
16428                            }
16429                        } else {
16430                            if (clientProcState <
16431                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16432                                clientProcState =
16433                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16434                            }
16435                        }
16436                        if (procState > clientProcState) {
16437                            procState = clientProcState;
16438                        }
16439                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16440                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16441                            app.pendingUiClean = true;
16442                        }
16443                        if (adjType != null) {
16444                            app.adjType = adjType;
16445                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16446                                    .REASON_SERVICE_IN_USE;
16447                            app.adjSource = cr.binding.client;
16448                            app.adjSourceProcState = clientProcState;
16449                            app.adjTarget = s.name;
16450                        }
16451                    }
16452                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16453                        app.treatLikeActivity = true;
16454                    }
16455                    final ActivityRecord a = cr.activity;
16456                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16457                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16458                                (a.visible || a.state == ActivityState.RESUMED
16459                                 || a.state == ActivityState.PAUSING)) {
16460                            adj = ProcessList.FOREGROUND_APP_ADJ;
16461                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16462                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16463                            }
16464                            app.cached = false;
16465                            app.adjType = "service";
16466                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16467                                    .REASON_SERVICE_IN_USE;
16468                            app.adjSource = a;
16469                            app.adjSourceProcState = procState;
16470                            app.adjTarget = s.name;
16471                        }
16472                    }
16473                }
16474            }
16475        }
16476
16477        for (int provi = app.pubProviders.size()-1;
16478                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16479                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16480                        || procState > ActivityManager.PROCESS_STATE_TOP);
16481                provi--) {
16482            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16483            for (int i = cpr.connections.size()-1;
16484                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16485                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16486                            || procState > ActivityManager.PROCESS_STATE_TOP);
16487                    i--) {
16488                ContentProviderConnection conn = cpr.connections.get(i);
16489                ProcessRecord client = conn.client;
16490                if (client == app) {
16491                    // Being our own client is not interesting.
16492                    continue;
16493                }
16494                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16495                int clientProcState = client.curProcState;
16496                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16497                    // If the other app is cached for any reason, for purposes here
16498                    // we are going to consider it empty.
16499                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16500                }
16501                if (adj > clientAdj) {
16502                    if (app.hasShownUi && app != mHomeProcess
16503                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16504                        app.adjType = "cch-ui-provider";
16505                    } else {
16506                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16507                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16508                        app.adjType = "provider";
16509                    }
16510                    app.cached &= client.cached;
16511                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16512                            .REASON_PROVIDER_IN_USE;
16513                    app.adjSource = client;
16514                    app.adjSourceProcState = clientProcState;
16515                    app.adjTarget = cpr.name;
16516                }
16517                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16518                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16519                        // Special handling of clients who are in the top state.
16520                        // We *may* want to consider this process to be in the
16521                        // top state as well, but only if there is not another
16522                        // reason for it to be running.  Being on the top is a
16523                        // special state, meaning you are specifically running
16524                        // for the current top app.  If the process is already
16525                        // running in the background for some other reason, it
16526                        // is more important to continue considering it to be
16527                        // in the background state.
16528                        mayBeTop = true;
16529                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16530                    } else {
16531                        // Special handling for above-top states (persistent
16532                        // processes).  These should not bring the current process
16533                        // into the top state, since they are not on top.  Instead
16534                        // give them the best state after that.
16535                        clientProcState =
16536                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16537                    }
16538                }
16539                if (procState > clientProcState) {
16540                    procState = clientProcState;
16541                }
16542                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16543                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16544                }
16545            }
16546            // If the provider has external (non-framework) process
16547            // dependencies, ensure that its adjustment is at least
16548            // FOREGROUND_APP_ADJ.
16549            if (cpr.hasExternalProcessHandles()) {
16550                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16551                    adj = ProcessList.FOREGROUND_APP_ADJ;
16552                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16553                    app.cached = false;
16554                    app.adjType = "provider";
16555                    app.adjTarget = cpr.name;
16556                }
16557                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16558                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16559                }
16560            }
16561        }
16562
16563        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16564            // A client of one of our services or providers is in the top state.  We
16565            // *may* want to be in the top state, but not if we are already running in
16566            // the background for some other reason.  For the decision here, we are going
16567            // to pick out a few specific states that we want to remain in when a client
16568            // is top (states that tend to be longer-term) and otherwise allow it to go
16569            // to the top state.
16570            switch (procState) {
16571                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16572                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16573                case ActivityManager.PROCESS_STATE_SERVICE:
16574                    // These all are longer-term states, so pull them up to the top
16575                    // of the background states, but not all the way to the top state.
16576                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16577                    break;
16578                default:
16579                    // Otherwise, top is a better choice, so take it.
16580                    procState = ActivityManager.PROCESS_STATE_TOP;
16581                    break;
16582            }
16583        }
16584
16585        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16586            if (app.hasClientActivities) {
16587                // This is a cached process, but with client activities.  Mark it so.
16588                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16589                app.adjType = "cch-client-act";
16590            } else if (app.treatLikeActivity) {
16591                // This is a cached process, but somebody wants us to treat it like it has
16592                // an activity, okay!
16593                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16594                app.adjType = "cch-as-act";
16595            }
16596        }
16597
16598        if (adj == ProcessList.SERVICE_ADJ) {
16599            if (doingAll) {
16600                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16601                mNewNumServiceProcs++;
16602                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16603                if (!app.serviceb) {
16604                    // This service isn't far enough down on the LRU list to
16605                    // normally be a B service, but if we are low on RAM and it
16606                    // is large we want to force it down since we would prefer to
16607                    // keep launcher over it.
16608                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16609                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16610                        app.serviceHighRam = true;
16611                        app.serviceb = true;
16612                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16613                    } else {
16614                        mNewNumAServiceProcs++;
16615                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16616                    }
16617                } else {
16618                    app.serviceHighRam = false;
16619                }
16620            }
16621            if (app.serviceb) {
16622                adj = ProcessList.SERVICE_B_ADJ;
16623            }
16624        }
16625
16626        app.curRawAdj = adj;
16627
16628        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16629        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16630        if (adj > app.maxAdj) {
16631            adj = app.maxAdj;
16632            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16633                schedGroup = Process.THREAD_GROUP_DEFAULT;
16634            }
16635        }
16636
16637        // Do final modification to adj.  Everything we do between here and applying
16638        // the final setAdj must be done in this function, because we will also use
16639        // it when computing the final cached adj later.  Note that we don't need to
16640        // worry about this for max adj above, since max adj will always be used to
16641        // keep it out of the cached vaues.
16642        app.curAdj = app.modifyRawOomAdj(adj);
16643        app.curSchedGroup = schedGroup;
16644        app.curProcState = procState;
16645        app.foregroundActivities = foregroundActivities;
16646
16647        return app.curRawAdj;
16648    }
16649
16650    /**
16651     * Schedule PSS collection of a process.
16652     */
16653    void requestPssLocked(ProcessRecord proc, int procState) {
16654        if (mPendingPssProcesses.contains(proc)) {
16655            return;
16656        }
16657        if (mPendingPssProcesses.size() == 0) {
16658            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16659        }
16660        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16661        proc.pssProcState = procState;
16662        mPendingPssProcesses.add(proc);
16663    }
16664
16665    /**
16666     * Schedule PSS collection of all processes.
16667     */
16668    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16669        if (!always) {
16670            if (now < (mLastFullPssTime +
16671                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16672                return;
16673            }
16674        }
16675        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16676        mLastFullPssTime = now;
16677        mFullPssPending = true;
16678        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16679        mPendingPssProcesses.clear();
16680        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16681            ProcessRecord app = mLruProcesses.get(i);
16682            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16683                app.pssProcState = app.setProcState;
16684                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16685                        isSleeping(), now);
16686                mPendingPssProcesses.add(app);
16687            }
16688        }
16689        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16690    }
16691
16692    /**
16693     * Ask a given process to GC right now.
16694     */
16695    final void performAppGcLocked(ProcessRecord app) {
16696        try {
16697            app.lastRequestedGc = SystemClock.uptimeMillis();
16698            if (app.thread != null) {
16699                if (app.reportLowMemory) {
16700                    app.reportLowMemory = false;
16701                    app.thread.scheduleLowMemory();
16702                } else {
16703                    app.thread.processInBackground();
16704                }
16705            }
16706        } catch (Exception e) {
16707            // whatever.
16708        }
16709    }
16710
16711    /**
16712     * Returns true if things are idle enough to perform GCs.
16713     */
16714    private final boolean canGcNowLocked() {
16715        boolean processingBroadcasts = false;
16716        for (BroadcastQueue q : mBroadcastQueues) {
16717            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16718                processingBroadcasts = true;
16719            }
16720        }
16721        return !processingBroadcasts
16722                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16723    }
16724
16725    /**
16726     * Perform GCs on all processes that are waiting for it, but only
16727     * if things are idle.
16728     */
16729    final void performAppGcsLocked() {
16730        final int N = mProcessesToGc.size();
16731        if (N <= 0) {
16732            return;
16733        }
16734        if (canGcNowLocked()) {
16735            while (mProcessesToGc.size() > 0) {
16736                ProcessRecord proc = mProcessesToGc.remove(0);
16737                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16738                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16739                            <= SystemClock.uptimeMillis()) {
16740                        // To avoid spamming the system, we will GC processes one
16741                        // at a time, waiting a few seconds between each.
16742                        performAppGcLocked(proc);
16743                        scheduleAppGcsLocked();
16744                        return;
16745                    } else {
16746                        // It hasn't been long enough since we last GCed this
16747                        // process...  put it in the list to wait for its time.
16748                        addProcessToGcListLocked(proc);
16749                        break;
16750                    }
16751                }
16752            }
16753
16754            scheduleAppGcsLocked();
16755        }
16756    }
16757
16758    /**
16759     * If all looks good, perform GCs on all processes waiting for them.
16760     */
16761    final void performAppGcsIfAppropriateLocked() {
16762        if (canGcNowLocked()) {
16763            performAppGcsLocked();
16764            return;
16765        }
16766        // Still not idle, wait some more.
16767        scheduleAppGcsLocked();
16768    }
16769
16770    /**
16771     * Schedule the execution of all pending app GCs.
16772     */
16773    final void scheduleAppGcsLocked() {
16774        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16775
16776        if (mProcessesToGc.size() > 0) {
16777            // Schedule a GC for the time to the next process.
16778            ProcessRecord proc = mProcessesToGc.get(0);
16779            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16780
16781            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16782            long now = SystemClock.uptimeMillis();
16783            if (when < (now+GC_TIMEOUT)) {
16784                when = now + GC_TIMEOUT;
16785            }
16786            mHandler.sendMessageAtTime(msg, when);
16787        }
16788    }
16789
16790    /**
16791     * Add a process to the array of processes waiting to be GCed.  Keeps the
16792     * list in sorted order by the last GC time.  The process can't already be
16793     * on the list.
16794     */
16795    final void addProcessToGcListLocked(ProcessRecord proc) {
16796        boolean added = false;
16797        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16798            if (mProcessesToGc.get(i).lastRequestedGc <
16799                    proc.lastRequestedGc) {
16800                added = true;
16801                mProcessesToGc.add(i+1, proc);
16802                break;
16803            }
16804        }
16805        if (!added) {
16806            mProcessesToGc.add(0, proc);
16807        }
16808    }
16809
16810    /**
16811     * Set up to ask a process to GC itself.  This will either do it
16812     * immediately, or put it on the list of processes to gc the next
16813     * time things are idle.
16814     */
16815    final void scheduleAppGcLocked(ProcessRecord app) {
16816        long now = SystemClock.uptimeMillis();
16817        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16818            return;
16819        }
16820        if (!mProcessesToGc.contains(app)) {
16821            addProcessToGcListLocked(app);
16822            scheduleAppGcsLocked();
16823        }
16824    }
16825
16826    final void checkExcessivePowerUsageLocked(boolean doKills) {
16827        updateCpuStatsNow();
16828
16829        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16830        boolean doWakeKills = doKills;
16831        boolean doCpuKills = doKills;
16832        if (mLastPowerCheckRealtime == 0) {
16833            doWakeKills = false;
16834        }
16835        if (mLastPowerCheckUptime == 0) {
16836            doCpuKills = false;
16837        }
16838        if (stats.isScreenOn()) {
16839            doWakeKills = false;
16840        }
16841        final long curRealtime = SystemClock.elapsedRealtime();
16842        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16843        final long curUptime = SystemClock.uptimeMillis();
16844        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16845        mLastPowerCheckRealtime = curRealtime;
16846        mLastPowerCheckUptime = curUptime;
16847        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16848            doWakeKills = false;
16849        }
16850        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16851            doCpuKills = false;
16852        }
16853        int i = mLruProcesses.size();
16854        while (i > 0) {
16855            i--;
16856            ProcessRecord app = mLruProcesses.get(i);
16857            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16858                long wtime;
16859                synchronized (stats) {
16860                    wtime = stats.getProcessWakeTime(app.info.uid,
16861                            app.pid, curRealtime);
16862                }
16863                long wtimeUsed = wtime - app.lastWakeTime;
16864                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16865                if (DEBUG_POWER) {
16866                    StringBuilder sb = new StringBuilder(128);
16867                    sb.append("Wake for ");
16868                    app.toShortString(sb);
16869                    sb.append(": over ");
16870                    TimeUtils.formatDuration(realtimeSince, sb);
16871                    sb.append(" used ");
16872                    TimeUtils.formatDuration(wtimeUsed, sb);
16873                    sb.append(" (");
16874                    sb.append((wtimeUsed*100)/realtimeSince);
16875                    sb.append("%)");
16876                    Slog.i(TAG, sb.toString());
16877                    sb.setLength(0);
16878                    sb.append("CPU for ");
16879                    app.toShortString(sb);
16880                    sb.append(": over ");
16881                    TimeUtils.formatDuration(uptimeSince, sb);
16882                    sb.append(" used ");
16883                    TimeUtils.formatDuration(cputimeUsed, sb);
16884                    sb.append(" (");
16885                    sb.append((cputimeUsed*100)/uptimeSince);
16886                    sb.append("%)");
16887                    Slog.i(TAG, sb.toString());
16888                }
16889                // If a process has held a wake lock for more
16890                // than 50% of the time during this period,
16891                // that sounds bad.  Kill!
16892                if (doWakeKills && realtimeSince > 0
16893                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16894                    synchronized (stats) {
16895                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16896                                realtimeSince, wtimeUsed);
16897                    }
16898                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16899                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16900                } else if (doCpuKills && uptimeSince > 0
16901                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16902                    synchronized (stats) {
16903                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16904                                uptimeSince, cputimeUsed);
16905                    }
16906                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16907                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16908                } else {
16909                    app.lastWakeTime = wtime;
16910                    app.lastCpuTime = app.curCpuTime;
16911                }
16912            }
16913        }
16914    }
16915
16916    private final boolean applyOomAdjLocked(ProcessRecord app,
16917            ProcessRecord TOP_APP, boolean doingAll, long now) {
16918        boolean success = true;
16919
16920        if (app.curRawAdj != app.setRawAdj) {
16921            app.setRawAdj = app.curRawAdj;
16922        }
16923
16924        int changes = 0;
16925
16926        if (app.curAdj != app.setAdj) {
16927            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16928            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16929                TAG, "Set " + app.pid + " " + app.processName +
16930                " adj " + app.curAdj + ": " + app.adjType);
16931            app.setAdj = app.curAdj;
16932        }
16933
16934        if (app.setSchedGroup != app.curSchedGroup) {
16935            app.setSchedGroup = app.curSchedGroup;
16936            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16937                    "Setting process group of " + app.processName
16938                    + " to " + app.curSchedGroup);
16939            if (app.waitingToKill != null &&
16940                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16941                app.kill(app.waitingToKill, true);
16942                success = false;
16943            } else {
16944                if (true) {
16945                    long oldId = Binder.clearCallingIdentity();
16946                    try {
16947                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16948                    } catch (Exception e) {
16949                        Slog.w(TAG, "Failed setting process group of " + app.pid
16950                                + " to " + app.curSchedGroup);
16951                        e.printStackTrace();
16952                    } finally {
16953                        Binder.restoreCallingIdentity(oldId);
16954                    }
16955                } else {
16956                    if (app.thread != null) {
16957                        try {
16958                            app.thread.setSchedulingGroup(app.curSchedGroup);
16959                        } catch (RemoteException e) {
16960                        }
16961                    }
16962                }
16963                Process.setSwappiness(app.pid,
16964                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16965            }
16966        }
16967        if (app.repForegroundActivities != app.foregroundActivities) {
16968            app.repForegroundActivities = app.foregroundActivities;
16969            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16970        }
16971        if (app.repProcState != app.curProcState) {
16972            app.repProcState = app.curProcState;
16973            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16974            if (app.thread != null) {
16975                try {
16976                    if (false) {
16977                        //RuntimeException h = new RuntimeException("here");
16978                        Slog.i(TAG, "Sending new process state " + app.repProcState
16979                                + " to " + app /*, h*/);
16980                    }
16981                    app.thread.setProcessState(app.repProcState);
16982                } catch (RemoteException e) {
16983                }
16984            }
16985        }
16986        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16987                app.setProcState)) {
16988            app.lastStateTime = now;
16989            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16990                    isSleeping(), now);
16991            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16992                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16993                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16994                    + (app.nextPssTime-now) + ": " + app);
16995        } else {
16996            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16997                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16998                requestPssLocked(app, app.setProcState);
16999                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17000                        isSleeping(), now);
17001            } else if (false && DEBUG_PSS) {
17002                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17003            }
17004        }
17005        if (app.setProcState != app.curProcState) {
17006            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17007                    "Proc state change of " + app.processName
17008                    + " to " + app.curProcState);
17009            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17010            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17011            if (setImportant && !curImportant) {
17012                // This app is no longer something we consider important enough to allow to
17013                // use arbitrary amounts of battery power.  Note
17014                // its current wake lock time to later know to kill it if
17015                // it is not behaving well.
17016                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17017                synchronized (stats) {
17018                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17019                            app.pid, SystemClock.elapsedRealtime());
17020                }
17021                app.lastCpuTime = app.curCpuTime;
17022
17023            }
17024            app.setProcState = app.curProcState;
17025            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17026                app.notCachedSinceIdle = false;
17027            }
17028            if (!doingAll) {
17029                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17030            } else {
17031                app.procStateChanged = true;
17032            }
17033        }
17034
17035        if (changes != 0) {
17036            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17037            int i = mPendingProcessChanges.size()-1;
17038            ProcessChangeItem item = null;
17039            while (i >= 0) {
17040                item = mPendingProcessChanges.get(i);
17041                if (item.pid == app.pid) {
17042                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17043                    break;
17044                }
17045                i--;
17046            }
17047            if (i < 0) {
17048                // No existing item in pending changes; need a new one.
17049                final int NA = mAvailProcessChanges.size();
17050                if (NA > 0) {
17051                    item = mAvailProcessChanges.remove(NA-1);
17052                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17053                } else {
17054                    item = new ProcessChangeItem();
17055                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17056                }
17057                item.changes = 0;
17058                item.pid = app.pid;
17059                item.uid = app.info.uid;
17060                if (mPendingProcessChanges.size() == 0) {
17061                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17062                            "*** Enqueueing dispatch processes changed!");
17063                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17064                }
17065                mPendingProcessChanges.add(item);
17066            }
17067            item.changes |= changes;
17068            item.processState = app.repProcState;
17069            item.foregroundActivities = app.repForegroundActivities;
17070            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17071                    + Integer.toHexString(System.identityHashCode(item))
17072                    + " " + app.toShortString() + ": changes=" + item.changes
17073                    + " procState=" + item.processState
17074                    + " foreground=" + item.foregroundActivities
17075                    + " type=" + app.adjType + " source=" + app.adjSource
17076                    + " target=" + app.adjTarget);
17077        }
17078
17079        return success;
17080    }
17081
17082    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17083        if (proc.thread != null) {
17084            if (proc.baseProcessTracker != null) {
17085                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17086            }
17087            if (proc.repProcState >= 0) {
17088                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17089                        proc.repProcState);
17090            }
17091        }
17092    }
17093
17094    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17095            ProcessRecord TOP_APP, boolean doingAll, long now) {
17096        if (app.thread == null) {
17097            return false;
17098        }
17099
17100        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17101
17102        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17103    }
17104
17105    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17106            boolean oomAdj) {
17107        if (isForeground != proc.foregroundServices) {
17108            proc.foregroundServices = isForeground;
17109            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17110                    proc.info.uid);
17111            if (isForeground) {
17112                if (curProcs == null) {
17113                    curProcs = new ArrayList<ProcessRecord>();
17114                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17115                }
17116                if (!curProcs.contains(proc)) {
17117                    curProcs.add(proc);
17118                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17119                            proc.info.packageName, proc.info.uid);
17120                }
17121            } else {
17122                if (curProcs != null) {
17123                    if (curProcs.remove(proc)) {
17124                        mBatteryStatsService.noteEvent(
17125                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17126                                proc.info.packageName, proc.info.uid);
17127                        if (curProcs.size() <= 0) {
17128                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17129                        }
17130                    }
17131                }
17132            }
17133            if (oomAdj) {
17134                updateOomAdjLocked();
17135            }
17136        }
17137    }
17138
17139    private final ActivityRecord resumedAppLocked() {
17140        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17141        String pkg;
17142        int uid;
17143        if (act != null) {
17144            pkg = act.packageName;
17145            uid = act.info.applicationInfo.uid;
17146        } else {
17147            pkg = null;
17148            uid = -1;
17149        }
17150        // Has the UID or resumed package name changed?
17151        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17152                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17153            if (mCurResumedPackage != null) {
17154                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17155                        mCurResumedPackage, mCurResumedUid);
17156            }
17157            mCurResumedPackage = pkg;
17158            mCurResumedUid = uid;
17159            if (mCurResumedPackage != null) {
17160                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17161                        mCurResumedPackage, mCurResumedUid);
17162            }
17163        }
17164        return act;
17165    }
17166
17167    final boolean updateOomAdjLocked(ProcessRecord app) {
17168        final ActivityRecord TOP_ACT = resumedAppLocked();
17169        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17170        final boolean wasCached = app.cached;
17171
17172        mAdjSeq++;
17173
17174        // This is the desired cached adjusment we want to tell it to use.
17175        // If our app is currently cached, we know it, and that is it.  Otherwise,
17176        // we don't know it yet, and it needs to now be cached we will then
17177        // need to do a complete oom adj.
17178        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17179                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17180        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17181                SystemClock.uptimeMillis());
17182        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17183            // Changed to/from cached state, so apps after it in the LRU
17184            // list may also be changed.
17185            updateOomAdjLocked();
17186        }
17187        return success;
17188    }
17189
17190    final void updateOomAdjLocked() {
17191        final ActivityRecord TOP_ACT = resumedAppLocked();
17192        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17193        final long now = SystemClock.uptimeMillis();
17194        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17195        final int N = mLruProcesses.size();
17196
17197        if (false) {
17198            RuntimeException e = new RuntimeException();
17199            e.fillInStackTrace();
17200            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17201        }
17202
17203        mAdjSeq++;
17204        mNewNumServiceProcs = 0;
17205        mNewNumAServiceProcs = 0;
17206
17207        final int emptyProcessLimit;
17208        final int cachedProcessLimit;
17209        if (mProcessLimit <= 0) {
17210            emptyProcessLimit = cachedProcessLimit = 0;
17211        } else if (mProcessLimit == 1) {
17212            emptyProcessLimit = 1;
17213            cachedProcessLimit = 0;
17214        } else {
17215            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17216            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17217        }
17218
17219        // Let's determine how many processes we have running vs.
17220        // how many slots we have for background processes; we may want
17221        // to put multiple processes in a slot of there are enough of
17222        // them.
17223        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17224                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17225        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17226        if (numEmptyProcs > cachedProcessLimit) {
17227            // If there are more empty processes than our limit on cached
17228            // processes, then use the cached process limit for the factor.
17229            // This ensures that the really old empty processes get pushed
17230            // down to the bottom, so if we are running low on memory we will
17231            // have a better chance at keeping around more cached processes
17232            // instead of a gazillion empty processes.
17233            numEmptyProcs = cachedProcessLimit;
17234        }
17235        int emptyFactor = numEmptyProcs/numSlots;
17236        if (emptyFactor < 1) emptyFactor = 1;
17237        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17238        if (cachedFactor < 1) cachedFactor = 1;
17239        int stepCached = 0;
17240        int stepEmpty = 0;
17241        int numCached = 0;
17242        int numEmpty = 0;
17243        int numTrimming = 0;
17244
17245        mNumNonCachedProcs = 0;
17246        mNumCachedHiddenProcs = 0;
17247
17248        // First update the OOM adjustment for each of the
17249        // application processes based on their current state.
17250        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17251        int nextCachedAdj = curCachedAdj+1;
17252        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17253        int nextEmptyAdj = curEmptyAdj+2;
17254        for (int i=N-1; i>=0; i--) {
17255            ProcessRecord app = mLruProcesses.get(i);
17256            if (!app.killedByAm && app.thread != null) {
17257                app.procStateChanged = false;
17258                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17259
17260                // If we haven't yet assigned the final cached adj
17261                // to the process, do that now.
17262                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17263                    switch (app.curProcState) {
17264                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17265                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17266                            // This process is a cached process holding activities...
17267                            // assign it the next cached value for that type, and then
17268                            // step that cached level.
17269                            app.curRawAdj = curCachedAdj;
17270                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17271                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17272                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17273                                    + ")");
17274                            if (curCachedAdj != nextCachedAdj) {
17275                                stepCached++;
17276                                if (stepCached >= cachedFactor) {
17277                                    stepCached = 0;
17278                                    curCachedAdj = nextCachedAdj;
17279                                    nextCachedAdj += 2;
17280                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17281                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17282                                    }
17283                                }
17284                            }
17285                            break;
17286                        default:
17287                            // For everything else, assign next empty cached process
17288                            // level and bump that up.  Note that this means that
17289                            // long-running services that have dropped down to the
17290                            // cached level will be treated as empty (since their process
17291                            // state is still as a service), which is what we want.
17292                            app.curRawAdj = curEmptyAdj;
17293                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17294                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17295                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17296                                    + ")");
17297                            if (curEmptyAdj != nextEmptyAdj) {
17298                                stepEmpty++;
17299                                if (stepEmpty >= emptyFactor) {
17300                                    stepEmpty = 0;
17301                                    curEmptyAdj = nextEmptyAdj;
17302                                    nextEmptyAdj += 2;
17303                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17304                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17305                                    }
17306                                }
17307                            }
17308                            break;
17309                    }
17310                }
17311
17312                applyOomAdjLocked(app, TOP_APP, true, now);
17313
17314                // Count the number of process types.
17315                switch (app.curProcState) {
17316                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17317                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17318                        mNumCachedHiddenProcs++;
17319                        numCached++;
17320                        if (numCached > cachedProcessLimit) {
17321                            app.kill("cached #" + numCached, true);
17322                        }
17323                        break;
17324                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17325                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17326                                && app.lastActivityTime < oldTime) {
17327                            app.kill("empty for "
17328                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17329                                    / 1000) + "s", true);
17330                        } else {
17331                            numEmpty++;
17332                            if (numEmpty > emptyProcessLimit) {
17333                                app.kill("empty #" + numEmpty, true);
17334                            }
17335                        }
17336                        break;
17337                    default:
17338                        mNumNonCachedProcs++;
17339                        break;
17340                }
17341
17342                if (app.isolated && app.services.size() <= 0) {
17343                    // If this is an isolated process, and there are no
17344                    // services running in it, then the process is no longer
17345                    // needed.  We agressively kill these because we can by
17346                    // definition not re-use the same process again, and it is
17347                    // good to avoid having whatever code was running in them
17348                    // left sitting around after no longer needed.
17349                    app.kill("isolated not needed", true);
17350                }
17351
17352                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17353                        && !app.killedByAm) {
17354                    numTrimming++;
17355                }
17356            }
17357        }
17358
17359        mNumServiceProcs = mNewNumServiceProcs;
17360
17361        // Now determine the memory trimming level of background processes.
17362        // Unfortunately we need to start at the back of the list to do this
17363        // properly.  We only do this if the number of background apps we
17364        // are managing to keep around is less than half the maximum we desire;
17365        // if we are keeping a good number around, we'll let them use whatever
17366        // memory they want.
17367        final int numCachedAndEmpty = numCached + numEmpty;
17368        int memFactor;
17369        if (numCached <= ProcessList.TRIM_CACHED_APPS
17370                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17371            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17372                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17373            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17374                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17375            } else {
17376                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17377            }
17378        } else {
17379            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17380        }
17381        // We always allow the memory level to go up (better).  We only allow it to go
17382        // down if we are in a state where that is allowed, *and* the total number of processes
17383        // has gone down since last time.
17384        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17385                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17386                + " last=" + mLastNumProcesses);
17387        if (memFactor > mLastMemoryLevel) {
17388            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17389                memFactor = mLastMemoryLevel;
17390                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17391            }
17392        }
17393        mLastMemoryLevel = memFactor;
17394        mLastNumProcesses = mLruProcesses.size();
17395        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17396        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17397        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17398            if (mLowRamStartTime == 0) {
17399                mLowRamStartTime = now;
17400            }
17401            int step = 0;
17402            int fgTrimLevel;
17403            switch (memFactor) {
17404                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17405                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17406                    break;
17407                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17408                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17409                    break;
17410                default:
17411                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17412                    break;
17413            }
17414            int factor = numTrimming/3;
17415            int minFactor = 2;
17416            if (mHomeProcess != null) minFactor++;
17417            if (mPreviousProcess != null) minFactor++;
17418            if (factor < minFactor) factor = minFactor;
17419            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17420            for (int i=N-1; i>=0; i--) {
17421                ProcessRecord app = mLruProcesses.get(i);
17422                if (allChanged || app.procStateChanged) {
17423                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17424                    app.procStateChanged = false;
17425                }
17426                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17427                        && !app.killedByAm) {
17428                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17429                        try {
17430                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17431                                    "Trimming memory of " + app.processName
17432                                    + " to " + curLevel);
17433                            app.thread.scheduleTrimMemory(curLevel);
17434                        } catch (RemoteException e) {
17435                        }
17436                        if (false) {
17437                            // For now we won't do this; our memory trimming seems
17438                            // to be good enough at this point that destroying
17439                            // activities causes more harm than good.
17440                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17441                                    && app != mHomeProcess && app != mPreviousProcess) {
17442                                // Need to do this on its own message because the stack may not
17443                                // be in a consistent state at this point.
17444                                // For these apps we will also finish their activities
17445                                // to help them free memory.
17446                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17447                            }
17448                        }
17449                    }
17450                    app.trimMemoryLevel = curLevel;
17451                    step++;
17452                    if (step >= factor) {
17453                        step = 0;
17454                        switch (curLevel) {
17455                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17456                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17457                                break;
17458                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17459                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17460                                break;
17461                        }
17462                    }
17463                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17464                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17465                            && app.thread != null) {
17466                        try {
17467                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17468                                    "Trimming memory of heavy-weight " + app.processName
17469                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17470                            app.thread.scheduleTrimMemory(
17471                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17472                        } catch (RemoteException e) {
17473                        }
17474                    }
17475                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17476                } else {
17477                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17478                            || app.systemNoUi) && app.pendingUiClean) {
17479                        // If this application is now in the background and it
17480                        // had done UI, then give it the special trim level to
17481                        // have it free UI resources.
17482                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17483                        if (app.trimMemoryLevel < level && app.thread != null) {
17484                            try {
17485                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17486                                        "Trimming memory of bg-ui " + app.processName
17487                                        + " to " + level);
17488                                app.thread.scheduleTrimMemory(level);
17489                            } catch (RemoteException e) {
17490                            }
17491                        }
17492                        app.pendingUiClean = false;
17493                    }
17494                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17495                        try {
17496                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17497                                    "Trimming memory of fg " + app.processName
17498                                    + " to " + fgTrimLevel);
17499                            app.thread.scheduleTrimMemory(fgTrimLevel);
17500                        } catch (RemoteException e) {
17501                        }
17502                    }
17503                    app.trimMemoryLevel = fgTrimLevel;
17504                }
17505            }
17506        } else {
17507            if (mLowRamStartTime != 0) {
17508                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17509                mLowRamStartTime = 0;
17510            }
17511            for (int i=N-1; i>=0; i--) {
17512                ProcessRecord app = mLruProcesses.get(i);
17513                if (allChanged || app.procStateChanged) {
17514                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17515                    app.procStateChanged = false;
17516                }
17517                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17518                        || app.systemNoUi) && app.pendingUiClean) {
17519                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17520                            && app.thread != null) {
17521                        try {
17522                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17523                                    "Trimming memory of ui hidden " + app.processName
17524                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17525                            app.thread.scheduleTrimMemory(
17526                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17527                        } catch (RemoteException e) {
17528                        }
17529                    }
17530                    app.pendingUiClean = false;
17531                }
17532                app.trimMemoryLevel = 0;
17533            }
17534        }
17535
17536        if (mAlwaysFinishActivities) {
17537            // Need to do this on its own message because the stack may not
17538            // be in a consistent state at this point.
17539            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17540        }
17541
17542        if (allChanged) {
17543            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17544        }
17545
17546        if (mProcessStats.shouldWriteNowLocked(now)) {
17547            mHandler.post(new Runnable() {
17548                @Override public void run() {
17549                    synchronized (ActivityManagerService.this) {
17550                        mProcessStats.writeStateAsyncLocked();
17551                    }
17552                }
17553            });
17554        }
17555
17556        if (DEBUG_OOM_ADJ) {
17557            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17558        }
17559    }
17560
17561    final void trimApplications() {
17562        synchronized (this) {
17563            int i;
17564
17565            // First remove any unused application processes whose package
17566            // has been removed.
17567            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17568                final ProcessRecord app = mRemovedProcesses.get(i);
17569                if (app.activities.size() == 0
17570                        && app.curReceiver == null && app.services.size() == 0) {
17571                    Slog.i(
17572                        TAG, "Exiting empty application process "
17573                        + app.processName + " ("
17574                        + (app.thread != null ? app.thread.asBinder() : null)
17575                        + ")\n");
17576                    if (app.pid > 0 && app.pid != MY_PID) {
17577                        app.kill("empty", false);
17578                    } else {
17579                        try {
17580                            app.thread.scheduleExit();
17581                        } catch (Exception e) {
17582                            // Ignore exceptions.
17583                        }
17584                    }
17585                    cleanUpApplicationRecordLocked(app, false, true, -1);
17586                    mRemovedProcesses.remove(i);
17587
17588                    if (app.persistent) {
17589                        addAppLocked(app.info, false, null /* ABI override */);
17590                    }
17591                }
17592            }
17593
17594            // Now update the oom adj for all processes.
17595            updateOomAdjLocked();
17596        }
17597    }
17598
17599    /** This method sends the specified signal to each of the persistent apps */
17600    public void signalPersistentProcesses(int sig) throws RemoteException {
17601        if (sig != Process.SIGNAL_USR1) {
17602            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17603        }
17604
17605        synchronized (this) {
17606            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17607                    != PackageManager.PERMISSION_GRANTED) {
17608                throw new SecurityException("Requires permission "
17609                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17610            }
17611
17612            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17613                ProcessRecord r = mLruProcesses.get(i);
17614                if (r.thread != null && r.persistent) {
17615                    Process.sendSignal(r.pid, sig);
17616                }
17617            }
17618        }
17619    }
17620
17621    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17622        if (proc == null || proc == mProfileProc) {
17623            proc = mProfileProc;
17624            profileType = mProfileType;
17625            clearProfilerLocked();
17626        }
17627        if (proc == null) {
17628            return;
17629        }
17630        try {
17631            proc.thread.profilerControl(false, null, profileType);
17632        } catch (RemoteException e) {
17633            throw new IllegalStateException("Process disappeared");
17634        }
17635    }
17636
17637    private void clearProfilerLocked() {
17638        if (mProfileFd != null) {
17639            try {
17640                mProfileFd.close();
17641            } catch (IOException e) {
17642            }
17643        }
17644        mProfileApp = null;
17645        mProfileProc = null;
17646        mProfileFile = null;
17647        mProfileType = 0;
17648        mAutoStopProfiler = false;
17649        mSamplingInterval = 0;
17650    }
17651
17652    public boolean profileControl(String process, int userId, boolean start,
17653            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17654
17655        try {
17656            synchronized (this) {
17657                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17658                // its own permission.
17659                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17660                        != PackageManager.PERMISSION_GRANTED) {
17661                    throw new SecurityException("Requires permission "
17662                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17663                }
17664
17665                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17666                    throw new IllegalArgumentException("null profile info or fd");
17667                }
17668
17669                ProcessRecord proc = null;
17670                if (process != null) {
17671                    proc = findProcessLocked(process, userId, "profileControl");
17672                }
17673
17674                if (start && (proc == null || proc.thread == null)) {
17675                    throw new IllegalArgumentException("Unknown process: " + process);
17676                }
17677
17678                if (start) {
17679                    stopProfilerLocked(null, 0);
17680                    setProfileApp(proc.info, proc.processName, profilerInfo);
17681                    mProfileProc = proc;
17682                    mProfileType = profileType;
17683                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17684                    try {
17685                        fd = fd.dup();
17686                    } catch (IOException e) {
17687                        fd = null;
17688                    }
17689                    profilerInfo.profileFd = fd;
17690                    proc.thread.profilerControl(start, profilerInfo, profileType);
17691                    fd = null;
17692                    mProfileFd = null;
17693                } else {
17694                    stopProfilerLocked(proc, profileType);
17695                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17696                        try {
17697                            profilerInfo.profileFd.close();
17698                        } catch (IOException e) {
17699                        }
17700                    }
17701                }
17702
17703                return true;
17704            }
17705        } catch (RemoteException e) {
17706            throw new IllegalStateException("Process disappeared");
17707        } finally {
17708            if (profilerInfo != null && profilerInfo.profileFd != null) {
17709                try {
17710                    profilerInfo.profileFd.close();
17711                } catch (IOException e) {
17712                }
17713            }
17714        }
17715    }
17716
17717    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17718        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17719                userId, true, ALLOW_FULL_ONLY, callName, null);
17720        ProcessRecord proc = null;
17721        try {
17722            int pid = Integer.parseInt(process);
17723            synchronized (mPidsSelfLocked) {
17724                proc = mPidsSelfLocked.get(pid);
17725            }
17726        } catch (NumberFormatException e) {
17727        }
17728
17729        if (proc == null) {
17730            ArrayMap<String, SparseArray<ProcessRecord>> all
17731                    = mProcessNames.getMap();
17732            SparseArray<ProcessRecord> procs = all.get(process);
17733            if (procs != null && procs.size() > 0) {
17734                proc = procs.valueAt(0);
17735                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17736                    for (int i=1; i<procs.size(); i++) {
17737                        ProcessRecord thisProc = procs.valueAt(i);
17738                        if (thisProc.userId == userId) {
17739                            proc = thisProc;
17740                            break;
17741                        }
17742                    }
17743                }
17744            }
17745        }
17746
17747        return proc;
17748    }
17749
17750    public boolean dumpHeap(String process, int userId, boolean managed,
17751            String path, ParcelFileDescriptor fd) throws RemoteException {
17752
17753        try {
17754            synchronized (this) {
17755                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17756                // its own permission (same as profileControl).
17757                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17758                        != PackageManager.PERMISSION_GRANTED) {
17759                    throw new SecurityException("Requires permission "
17760                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17761                }
17762
17763                if (fd == null) {
17764                    throw new IllegalArgumentException("null fd");
17765                }
17766
17767                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17768                if (proc == null || proc.thread == null) {
17769                    throw new IllegalArgumentException("Unknown process: " + process);
17770                }
17771
17772                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17773                if (!isDebuggable) {
17774                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17775                        throw new SecurityException("Process not debuggable: " + proc);
17776                    }
17777                }
17778
17779                proc.thread.dumpHeap(managed, path, fd);
17780                fd = null;
17781                return true;
17782            }
17783        } catch (RemoteException e) {
17784            throw new IllegalStateException("Process disappeared");
17785        } finally {
17786            if (fd != null) {
17787                try {
17788                    fd.close();
17789                } catch (IOException e) {
17790                }
17791            }
17792        }
17793    }
17794
17795    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17796    public void monitor() {
17797        synchronized (this) { }
17798    }
17799
17800    void onCoreSettingsChange(Bundle settings) {
17801        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17802            ProcessRecord processRecord = mLruProcesses.get(i);
17803            try {
17804                if (processRecord.thread != null) {
17805                    processRecord.thread.setCoreSettings(settings);
17806                }
17807            } catch (RemoteException re) {
17808                /* ignore */
17809            }
17810        }
17811    }
17812
17813    // Multi-user methods
17814
17815    /**
17816     * Start user, if its not already running, but don't bring it to foreground.
17817     */
17818    @Override
17819    public boolean startUserInBackground(final int userId) {
17820        return startUser(userId, /* foreground */ false);
17821    }
17822
17823    /**
17824     * Start user, if its not already running, and bring it to foreground.
17825     */
17826    boolean startUserInForeground(final int userId, Dialog dlg) {
17827        boolean result = startUser(userId, /* foreground */ true);
17828        dlg.dismiss();
17829        return result;
17830    }
17831
17832    /**
17833     * Refreshes the list of users related to the current user when either a
17834     * user switch happens or when a new related user is started in the
17835     * background.
17836     */
17837    private void updateCurrentProfileIdsLocked() {
17838        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17839                mCurrentUserId, false /* enabledOnly */);
17840        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17841        for (int i = 0; i < currentProfileIds.length; i++) {
17842            currentProfileIds[i] = profiles.get(i).id;
17843        }
17844        mCurrentProfileIds = currentProfileIds;
17845
17846        synchronized (mUserProfileGroupIdsSelfLocked) {
17847            mUserProfileGroupIdsSelfLocked.clear();
17848            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17849            for (int i = 0; i < users.size(); i++) {
17850                UserInfo user = users.get(i);
17851                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17852                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17853                }
17854            }
17855        }
17856    }
17857
17858    private Set getProfileIdsLocked(int userId) {
17859        Set userIds = new HashSet<Integer>();
17860        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17861                userId, false /* enabledOnly */);
17862        for (UserInfo user : profiles) {
17863            userIds.add(Integer.valueOf(user.id));
17864        }
17865        return userIds;
17866    }
17867
17868    @Override
17869    public boolean switchUser(final int userId) {
17870        String userName;
17871        synchronized (this) {
17872            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17873            if (userInfo == null) {
17874                Slog.w(TAG, "No user info for user #" + userId);
17875                return false;
17876            }
17877            if (userInfo.isManagedProfile()) {
17878                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17879                return false;
17880            }
17881            userName = userInfo.name;
17882        }
17883        mHandler.removeMessages(START_USER_SWITCH_MSG);
17884        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17885        return true;
17886    }
17887
17888    private void showUserSwitchDialog(int userId, String userName) {
17889        // The dialog will show and then initiate the user switch by calling startUserInForeground
17890        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17891                true /* above system */);
17892        d.show();
17893    }
17894
17895    private boolean startUser(final int userId, final boolean foreground) {
17896        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17897                != PackageManager.PERMISSION_GRANTED) {
17898            String msg = "Permission Denial: switchUser() from pid="
17899                    + Binder.getCallingPid()
17900                    + ", uid=" + Binder.getCallingUid()
17901                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17902            Slog.w(TAG, msg);
17903            throw new SecurityException(msg);
17904        }
17905
17906        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17907
17908        final long ident = Binder.clearCallingIdentity();
17909        try {
17910            synchronized (this) {
17911                final int oldUserId = mCurrentUserId;
17912                if (oldUserId == userId) {
17913                    return true;
17914                }
17915
17916                mStackSupervisor.setLockTaskModeLocked(null, false);
17917
17918                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17919                if (userInfo == null) {
17920                    Slog.w(TAG, "No user info for user #" + userId);
17921                    return false;
17922                }
17923                if (foreground && userInfo.isManagedProfile()) {
17924                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17925                    return false;
17926                }
17927
17928                if (foreground) {
17929                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17930                            R.anim.screen_user_enter);
17931                }
17932
17933                boolean needStart = false;
17934
17935                // If the user we are switching to is not currently started, then
17936                // we need to start it now.
17937                if (mStartedUsers.get(userId) == null) {
17938                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17939                    updateStartedUserArrayLocked();
17940                    needStart = true;
17941                }
17942
17943                final Integer userIdInt = Integer.valueOf(userId);
17944                mUserLru.remove(userIdInt);
17945                mUserLru.add(userIdInt);
17946
17947                if (foreground) {
17948                    mCurrentUserId = userId;
17949                    updateCurrentProfileIdsLocked();
17950                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17951                    // Once the internal notion of the active user has switched, we lock the device
17952                    // with the option to show the user switcher on the keyguard.
17953                    mWindowManager.lockNow(null);
17954                } else {
17955                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17956                    updateCurrentProfileIdsLocked();
17957                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17958                    mUserLru.remove(currentUserIdInt);
17959                    mUserLru.add(currentUserIdInt);
17960                }
17961
17962                final UserStartedState uss = mStartedUsers.get(userId);
17963
17964                // Make sure user is in the started state.  If it is currently
17965                // stopping, we need to knock that off.
17966                if (uss.mState == UserStartedState.STATE_STOPPING) {
17967                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17968                    // so we can just fairly silently bring the user back from
17969                    // the almost-dead.
17970                    uss.mState = UserStartedState.STATE_RUNNING;
17971                    updateStartedUserArrayLocked();
17972                    needStart = true;
17973                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17974                    // This means ACTION_SHUTDOWN has been sent, so we will
17975                    // need to treat this as a new boot of the user.
17976                    uss.mState = UserStartedState.STATE_BOOTING;
17977                    updateStartedUserArrayLocked();
17978                    needStart = true;
17979                }
17980
17981                if (uss.mState == UserStartedState.STATE_BOOTING) {
17982                    // Booting up a new user, need to tell system services about it.
17983                    // Note that this is on the same handler as scheduling of broadcasts,
17984                    // which is important because it needs to go first.
17985                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17986                }
17987
17988                if (foreground) {
17989                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17990                            oldUserId));
17991                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17992                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17993                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17994                            oldUserId, userId, uss));
17995                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17996                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17997                }
17998
17999                if (needStart) {
18000                    // Send USER_STARTED broadcast
18001                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18002                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18003                            | Intent.FLAG_RECEIVER_FOREGROUND);
18004                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18005                    broadcastIntentLocked(null, null, intent,
18006                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18007                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18008                }
18009
18010                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18011                    if (userId != UserHandle.USER_OWNER) {
18012                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18013                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18014                        broadcastIntentLocked(null, null, intent, null,
18015                                new IIntentReceiver.Stub() {
18016                                    public void performReceive(Intent intent, int resultCode,
18017                                            String data, Bundle extras, boolean ordered,
18018                                            boolean sticky, int sendingUser) {
18019                                        onUserInitialized(uss, foreground, oldUserId, userId);
18020                                    }
18021                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18022                                true, false, MY_PID, Process.SYSTEM_UID,
18023                                userId);
18024                        uss.initializing = true;
18025                    } else {
18026                        getUserManagerLocked().makeInitialized(userInfo.id);
18027                    }
18028                }
18029
18030                if (foreground) {
18031                    if (!uss.initializing) {
18032                        moveUserToForeground(uss, oldUserId, userId);
18033                    }
18034                } else {
18035                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18036                }
18037
18038                if (needStart) {
18039                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18040                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18041                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18042                    broadcastIntentLocked(null, null, intent,
18043                            null, new IIntentReceiver.Stub() {
18044                                @Override
18045                                public void performReceive(Intent intent, int resultCode, String data,
18046                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18047                                        throws RemoteException {
18048                                }
18049                            }, 0, null, null,
18050                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18051                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18052                }
18053            }
18054        } finally {
18055            Binder.restoreCallingIdentity(ident);
18056        }
18057
18058        return true;
18059    }
18060
18061    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18062        long ident = Binder.clearCallingIdentity();
18063        try {
18064            Intent intent;
18065            if (oldUserId >= 0) {
18066                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18067                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18068                int count = profiles.size();
18069                for (int i = 0; i < count; i++) {
18070                    int profileUserId = profiles.get(i).id;
18071                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18072                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18073                            | Intent.FLAG_RECEIVER_FOREGROUND);
18074                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18075                    broadcastIntentLocked(null, null, intent,
18076                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18077                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18078                }
18079            }
18080            if (newUserId >= 0) {
18081                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18082                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18083                int count = profiles.size();
18084                for (int i = 0; i < count; i++) {
18085                    int profileUserId = profiles.get(i).id;
18086                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18087                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18088                            | Intent.FLAG_RECEIVER_FOREGROUND);
18089                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18090                    broadcastIntentLocked(null, null, intent,
18091                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18092                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18093                }
18094                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18095                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18096                        | Intent.FLAG_RECEIVER_FOREGROUND);
18097                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18098                broadcastIntentLocked(null, null, intent,
18099                        null, null, 0, null, null,
18100                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18101                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18102            }
18103        } finally {
18104            Binder.restoreCallingIdentity(ident);
18105        }
18106    }
18107
18108    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18109            final int newUserId) {
18110        final int N = mUserSwitchObservers.beginBroadcast();
18111        if (N > 0) {
18112            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18113                int mCount = 0;
18114                @Override
18115                public void sendResult(Bundle data) throws RemoteException {
18116                    synchronized (ActivityManagerService.this) {
18117                        if (mCurUserSwitchCallback == this) {
18118                            mCount++;
18119                            if (mCount == N) {
18120                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18121                            }
18122                        }
18123                    }
18124                }
18125            };
18126            synchronized (this) {
18127                uss.switching = true;
18128                mCurUserSwitchCallback = callback;
18129            }
18130            for (int i=0; i<N; i++) {
18131                try {
18132                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18133                            newUserId, callback);
18134                } catch (RemoteException e) {
18135                }
18136            }
18137        } else {
18138            synchronized (this) {
18139                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18140            }
18141        }
18142        mUserSwitchObservers.finishBroadcast();
18143    }
18144
18145    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18146        synchronized (this) {
18147            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18148            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18149        }
18150    }
18151
18152    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18153        mCurUserSwitchCallback = null;
18154        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18155        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18156                oldUserId, newUserId, uss));
18157    }
18158
18159    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18160        synchronized (this) {
18161            if (foreground) {
18162                moveUserToForeground(uss, oldUserId, newUserId);
18163            }
18164        }
18165
18166        completeSwitchAndInitalize(uss, newUserId, true, false);
18167    }
18168
18169    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18170        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18171        if (homeInFront) {
18172            startHomeActivityLocked(newUserId);
18173        } else {
18174            mStackSupervisor.resumeTopActivitiesLocked();
18175        }
18176        EventLogTags.writeAmSwitchUser(newUserId);
18177        getUserManagerLocked().userForeground(newUserId);
18178        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18179    }
18180
18181    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18182        completeSwitchAndInitalize(uss, newUserId, false, true);
18183    }
18184
18185    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18186            boolean clearInitializing, boolean clearSwitching) {
18187        boolean unfrozen = false;
18188        synchronized (this) {
18189            if (clearInitializing) {
18190                uss.initializing = false;
18191                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18192            }
18193            if (clearSwitching) {
18194                uss.switching = false;
18195            }
18196            if (!uss.switching && !uss.initializing) {
18197                mWindowManager.stopFreezingScreen();
18198                unfrozen = true;
18199            }
18200        }
18201        if (unfrozen) {
18202            final int N = mUserSwitchObservers.beginBroadcast();
18203            for (int i=0; i<N; i++) {
18204                try {
18205                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18206                } catch (RemoteException e) {
18207                }
18208            }
18209            mUserSwitchObservers.finishBroadcast();
18210        }
18211    }
18212
18213    void scheduleStartProfilesLocked() {
18214        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18215            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18216                    DateUtils.SECOND_IN_MILLIS);
18217        }
18218    }
18219
18220    void startProfilesLocked() {
18221        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18222        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18223                mCurrentUserId, false /* enabledOnly */);
18224        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18225        for (UserInfo user : profiles) {
18226            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18227                    && user.id != mCurrentUserId) {
18228                toStart.add(user);
18229            }
18230        }
18231        final int n = toStart.size();
18232        int i = 0;
18233        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18234            startUserInBackground(toStart.get(i).id);
18235        }
18236        if (i < n) {
18237            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18238        }
18239    }
18240
18241    void finishUserBoot(UserStartedState uss) {
18242        synchronized (this) {
18243            if (uss.mState == UserStartedState.STATE_BOOTING
18244                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18245                uss.mState = UserStartedState.STATE_RUNNING;
18246                final int userId = uss.mHandle.getIdentifier();
18247                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18248                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18249                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18250                broadcastIntentLocked(null, null, intent,
18251                        null, null, 0, null, null,
18252                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18253                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18254            }
18255        }
18256    }
18257
18258    void finishUserSwitch(UserStartedState uss) {
18259        synchronized (this) {
18260            finishUserBoot(uss);
18261
18262            startProfilesLocked();
18263
18264            int num = mUserLru.size();
18265            int i = 0;
18266            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18267                Integer oldUserId = mUserLru.get(i);
18268                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18269                if (oldUss == null) {
18270                    // Shouldn't happen, but be sane if it does.
18271                    mUserLru.remove(i);
18272                    num--;
18273                    continue;
18274                }
18275                if (oldUss.mState == UserStartedState.STATE_STOPPING
18276                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18277                    // This user is already stopping, doesn't count.
18278                    num--;
18279                    i++;
18280                    continue;
18281                }
18282                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18283                    // Owner and current can't be stopped, but count as running.
18284                    i++;
18285                    continue;
18286                }
18287                // This is a user to be stopped.
18288                stopUserLocked(oldUserId, null);
18289                num--;
18290                i++;
18291            }
18292        }
18293    }
18294
18295    @Override
18296    public int stopUser(final int userId, final IStopUserCallback callback) {
18297        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18298                != PackageManager.PERMISSION_GRANTED) {
18299            String msg = "Permission Denial: switchUser() from pid="
18300                    + Binder.getCallingPid()
18301                    + ", uid=" + Binder.getCallingUid()
18302                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18303            Slog.w(TAG, msg);
18304            throw new SecurityException(msg);
18305        }
18306        if (userId <= 0) {
18307            throw new IllegalArgumentException("Can't stop primary user " + userId);
18308        }
18309        synchronized (this) {
18310            return stopUserLocked(userId, callback);
18311        }
18312    }
18313
18314    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18315        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18316        if (mCurrentUserId == userId) {
18317            return ActivityManager.USER_OP_IS_CURRENT;
18318        }
18319
18320        final UserStartedState uss = mStartedUsers.get(userId);
18321        if (uss == null) {
18322            // User is not started, nothing to do...  but we do need to
18323            // callback if requested.
18324            if (callback != null) {
18325                mHandler.post(new Runnable() {
18326                    @Override
18327                    public void run() {
18328                        try {
18329                            callback.userStopped(userId);
18330                        } catch (RemoteException e) {
18331                        }
18332                    }
18333                });
18334            }
18335            return ActivityManager.USER_OP_SUCCESS;
18336        }
18337
18338        if (callback != null) {
18339            uss.mStopCallbacks.add(callback);
18340        }
18341
18342        if (uss.mState != UserStartedState.STATE_STOPPING
18343                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18344            uss.mState = UserStartedState.STATE_STOPPING;
18345            updateStartedUserArrayLocked();
18346
18347            long ident = Binder.clearCallingIdentity();
18348            try {
18349                // We are going to broadcast ACTION_USER_STOPPING and then
18350                // once that is done send a final ACTION_SHUTDOWN and then
18351                // stop the user.
18352                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18353                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18354                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18355                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18356                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18357                // This is the result receiver for the final shutdown broadcast.
18358                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18359                    @Override
18360                    public void performReceive(Intent intent, int resultCode, String data,
18361                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18362                        finishUserStop(uss);
18363                    }
18364                };
18365                // This is the result receiver for the initial stopping broadcast.
18366                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18367                    @Override
18368                    public void performReceive(Intent intent, int resultCode, String data,
18369                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18370                        // On to the next.
18371                        synchronized (ActivityManagerService.this) {
18372                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18373                                // Whoops, we are being started back up.  Abort, abort!
18374                                return;
18375                            }
18376                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18377                        }
18378                        mBatteryStatsService.noteEvent(
18379                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18380                                Integer.toString(userId), userId);
18381                        mSystemServiceManager.stopUser(userId);
18382                        broadcastIntentLocked(null, null, shutdownIntent,
18383                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18384                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18385                    }
18386                };
18387                // Kick things off.
18388                broadcastIntentLocked(null, null, stoppingIntent,
18389                        null, stoppingReceiver, 0, null, null,
18390                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18391                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18392            } finally {
18393                Binder.restoreCallingIdentity(ident);
18394            }
18395        }
18396
18397        return ActivityManager.USER_OP_SUCCESS;
18398    }
18399
18400    void finishUserStop(UserStartedState uss) {
18401        final int userId = uss.mHandle.getIdentifier();
18402        boolean stopped;
18403        ArrayList<IStopUserCallback> callbacks;
18404        synchronized (this) {
18405            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18406            if (mStartedUsers.get(userId) != uss) {
18407                stopped = false;
18408            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18409                stopped = false;
18410            } else {
18411                stopped = true;
18412                // User can no longer run.
18413                mStartedUsers.remove(userId);
18414                mUserLru.remove(Integer.valueOf(userId));
18415                updateStartedUserArrayLocked();
18416
18417                // Clean up all state and processes associated with the user.
18418                // Kill all the processes for the user.
18419                forceStopUserLocked(userId, "finish user");
18420            }
18421
18422            // Explicitly remove the old information in mRecentTasks.
18423            removeRecentTasksForUserLocked(userId);
18424        }
18425
18426        for (int i=0; i<callbacks.size(); i++) {
18427            try {
18428                if (stopped) callbacks.get(i).userStopped(userId);
18429                else callbacks.get(i).userStopAborted(userId);
18430            } catch (RemoteException e) {
18431            }
18432        }
18433
18434        if (stopped) {
18435            mSystemServiceManager.cleanupUser(userId);
18436            synchronized (this) {
18437                mStackSupervisor.removeUserLocked(userId);
18438            }
18439        }
18440    }
18441
18442    @Override
18443    public UserInfo getCurrentUser() {
18444        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18445                != PackageManager.PERMISSION_GRANTED) && (
18446                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18447                != PackageManager.PERMISSION_GRANTED)) {
18448            String msg = "Permission Denial: getCurrentUser() from pid="
18449                    + Binder.getCallingPid()
18450                    + ", uid=" + Binder.getCallingUid()
18451                    + " requires " + INTERACT_ACROSS_USERS;
18452            Slog.w(TAG, msg);
18453            throw new SecurityException(msg);
18454        }
18455        synchronized (this) {
18456            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18457        }
18458    }
18459
18460    int getCurrentUserIdLocked() {
18461        return mCurrentUserId;
18462    }
18463
18464    @Override
18465    public boolean isUserRunning(int userId, boolean orStopped) {
18466        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18467                != PackageManager.PERMISSION_GRANTED) {
18468            String msg = "Permission Denial: isUserRunning() from pid="
18469                    + Binder.getCallingPid()
18470                    + ", uid=" + Binder.getCallingUid()
18471                    + " requires " + INTERACT_ACROSS_USERS;
18472            Slog.w(TAG, msg);
18473            throw new SecurityException(msg);
18474        }
18475        synchronized (this) {
18476            return isUserRunningLocked(userId, orStopped);
18477        }
18478    }
18479
18480    boolean isUserRunningLocked(int userId, boolean orStopped) {
18481        UserStartedState state = mStartedUsers.get(userId);
18482        if (state == null) {
18483            return false;
18484        }
18485        if (orStopped) {
18486            return true;
18487        }
18488        return state.mState != UserStartedState.STATE_STOPPING
18489                && state.mState != UserStartedState.STATE_SHUTDOWN;
18490    }
18491
18492    @Override
18493    public int[] getRunningUserIds() {
18494        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18495                != PackageManager.PERMISSION_GRANTED) {
18496            String msg = "Permission Denial: isUserRunning() from pid="
18497                    + Binder.getCallingPid()
18498                    + ", uid=" + Binder.getCallingUid()
18499                    + " requires " + INTERACT_ACROSS_USERS;
18500            Slog.w(TAG, msg);
18501            throw new SecurityException(msg);
18502        }
18503        synchronized (this) {
18504            return mStartedUserArray;
18505        }
18506    }
18507
18508    private void updateStartedUserArrayLocked() {
18509        int num = 0;
18510        for (int i=0; i<mStartedUsers.size();  i++) {
18511            UserStartedState uss = mStartedUsers.valueAt(i);
18512            // This list does not include stopping users.
18513            if (uss.mState != UserStartedState.STATE_STOPPING
18514                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18515                num++;
18516            }
18517        }
18518        mStartedUserArray = new int[num];
18519        num = 0;
18520        for (int i=0; i<mStartedUsers.size();  i++) {
18521            UserStartedState uss = mStartedUsers.valueAt(i);
18522            if (uss.mState != UserStartedState.STATE_STOPPING
18523                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18524                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18525                num++;
18526            }
18527        }
18528    }
18529
18530    @Override
18531    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18532        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18533                != PackageManager.PERMISSION_GRANTED) {
18534            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18535                    + Binder.getCallingPid()
18536                    + ", uid=" + Binder.getCallingUid()
18537                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18538            Slog.w(TAG, msg);
18539            throw new SecurityException(msg);
18540        }
18541
18542        mUserSwitchObservers.register(observer);
18543    }
18544
18545    @Override
18546    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18547        mUserSwitchObservers.unregister(observer);
18548    }
18549
18550    private boolean userExists(int userId) {
18551        if (userId == 0) {
18552            return true;
18553        }
18554        UserManagerService ums = getUserManagerLocked();
18555        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18556    }
18557
18558    int[] getUsersLocked() {
18559        UserManagerService ums = getUserManagerLocked();
18560        return ums != null ? ums.getUserIds() : new int[] { 0 };
18561    }
18562
18563    UserManagerService getUserManagerLocked() {
18564        if (mUserManager == null) {
18565            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18566            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18567        }
18568        return mUserManager;
18569    }
18570
18571    private int applyUserId(int uid, int userId) {
18572        return UserHandle.getUid(userId, uid);
18573    }
18574
18575    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18576        if (info == null) return null;
18577        ApplicationInfo newInfo = new ApplicationInfo(info);
18578        newInfo.uid = applyUserId(info.uid, userId);
18579        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18580                + info.packageName;
18581        return newInfo;
18582    }
18583
18584    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18585        if (aInfo == null
18586                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18587            return aInfo;
18588        }
18589
18590        ActivityInfo info = new ActivityInfo(aInfo);
18591        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18592        return info;
18593    }
18594
18595    private final class LocalService extends ActivityManagerInternal {
18596        @Override
18597        public void goingToSleep() {
18598            ActivityManagerService.this.goingToSleep();
18599        }
18600
18601        @Override
18602        public void wakingUp() {
18603            ActivityManagerService.this.wakingUp();
18604        }
18605
18606        @Override
18607        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18608                String processName, String abiOverride, int uid, Runnable crashHandler) {
18609            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18610                    processName, abiOverride, uid, crashHandler);
18611        }
18612    }
18613
18614    /**
18615     * An implementation of IAppTask, that allows an app to manage its own tasks via
18616     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18617     * only the process that calls getAppTasks() can call the AppTask methods.
18618     */
18619    class AppTaskImpl extends IAppTask.Stub {
18620        private int mTaskId;
18621        private int mCallingUid;
18622
18623        public AppTaskImpl(int taskId, int callingUid) {
18624            mTaskId = taskId;
18625            mCallingUid = callingUid;
18626        }
18627
18628        private void checkCaller() {
18629            if (mCallingUid != Binder.getCallingUid()) {
18630                throw new SecurityException("Caller " + mCallingUid
18631                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18632            }
18633        }
18634
18635        @Override
18636        public void finishAndRemoveTask() {
18637            checkCaller();
18638
18639            synchronized (ActivityManagerService.this) {
18640                long origId = Binder.clearCallingIdentity();
18641                try {
18642                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18643                    if (tr == null) {
18644                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18645                    }
18646                    // Only kill the process if we are not a new document
18647                    int flags = tr.getBaseIntent().getFlags();
18648                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18649                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18650                    removeTaskByIdLocked(mTaskId,
18651                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18652                } finally {
18653                    Binder.restoreCallingIdentity(origId);
18654                }
18655            }
18656        }
18657
18658        @Override
18659        public ActivityManager.RecentTaskInfo getTaskInfo() {
18660            checkCaller();
18661
18662            synchronized (ActivityManagerService.this) {
18663                long origId = Binder.clearCallingIdentity();
18664                try {
18665                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18666                    if (tr == null) {
18667                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18668                    }
18669                    return createRecentTaskInfoFromTaskRecord(tr);
18670                } finally {
18671                    Binder.restoreCallingIdentity(origId);
18672                }
18673            }
18674        }
18675
18676        @Override
18677        public void moveToFront() {
18678            checkCaller();
18679
18680            final TaskRecord tr;
18681            synchronized (ActivityManagerService.this) {
18682                tr = recentTaskForIdLocked(mTaskId);
18683                if (tr == null) {
18684                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18685                }
18686                if (tr.getRootActivity() != null) {
18687                    long origId = Binder.clearCallingIdentity();
18688                    try {
18689                        moveTaskToFrontLocked(tr.taskId, 0, null);
18690                        return;
18691                    } finally {
18692                        Binder.restoreCallingIdentity(origId);
18693                    }
18694                }
18695            }
18696
18697            startActivityFromRecentsInner(tr.taskId, null);
18698        }
18699
18700        @Override
18701        public int startActivity(IBinder whoThread, String callingPackage,
18702                Intent intent, String resolvedType, Bundle options) {
18703            checkCaller();
18704
18705            int callingUser = UserHandle.getCallingUserId();
18706            TaskRecord tr;
18707            IApplicationThread appThread;
18708            synchronized (ActivityManagerService.this) {
18709                tr = recentTaskForIdLocked(mTaskId);
18710                if (tr == null) {
18711                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18712                }
18713                appThread = ApplicationThreadNative.asInterface(whoThread);
18714                if (appThread == null) {
18715                    throw new IllegalArgumentException("Bad app thread " + appThread);
18716                }
18717            }
18718            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18719                    resolvedType, null, null, null, null, 0, 0, null, null,
18720                    null, options, callingUser, null, tr);
18721        }
18722
18723        @Override
18724        public void setExcludeFromRecents(boolean exclude) {
18725            checkCaller();
18726
18727            synchronized (ActivityManagerService.this) {
18728                long origId = Binder.clearCallingIdentity();
18729                try {
18730                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18731                    if (tr == null) {
18732                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18733                    }
18734                    Intent intent = tr.getBaseIntent();
18735                    if (exclude) {
18736                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18737                    } else {
18738                        intent.setFlags(intent.getFlags()
18739                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18740                    }
18741                } finally {
18742                    Binder.restoreCallingIdentity(origId);
18743                }
18744            }
18745        }
18746    }
18747}
18748