ActivityManagerService.java revision 7d9eefd871f1cdc5ebc36fa92dae48a737ae2928
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                if (r.changeWindowTranslucency(true)) {
10233                    mWindowManager.setAppFullscreen(token, true);
10234                    r.task.stack.releaseBackgroundResources();
10235                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10236                    return true;
10237                }
10238                return false;
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                if (r.changeWindowTranslucency(false)) {
10260                    r.task.stack.convertToTranslucent(r);
10261                    mWindowManager.setAppFullscreen(token, false);
10262                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10263                    return true;
10264                } else {
10265                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10266                    return false;
10267                }
10268            }
10269        } finally {
10270            Binder.restoreCallingIdentity(origId);
10271        }
10272    }
10273
10274    @Override
10275    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10276        final long origId = Binder.clearCallingIdentity();
10277        try {
10278            synchronized (this) {
10279                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10280                if (r != null) {
10281                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10282                }
10283            }
10284            return false;
10285        } finally {
10286            Binder.restoreCallingIdentity(origId);
10287        }
10288    }
10289
10290    @Override
10291    public boolean isBackgroundVisibleBehind(IBinder token) {
10292        final long origId = Binder.clearCallingIdentity();
10293        try {
10294            synchronized (this) {
10295                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10296                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10297                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10298                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10299                return visible;
10300            }
10301        } finally {
10302            Binder.restoreCallingIdentity(origId);
10303        }
10304    }
10305
10306    @Override
10307    public ActivityOptions getActivityOptions(IBinder token) {
10308        final long origId = Binder.clearCallingIdentity();
10309        try {
10310            synchronized (this) {
10311                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10312                if (r != null) {
10313                    final ActivityOptions activityOptions = r.pendingOptions;
10314                    r.pendingOptions = null;
10315                    return activityOptions;
10316                }
10317                return null;
10318            }
10319        } finally {
10320            Binder.restoreCallingIdentity(origId);
10321        }
10322    }
10323
10324    @Override
10325    public void setImmersive(IBinder token, boolean immersive) {
10326        synchronized(this) {
10327            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10328            if (r == null) {
10329                throw new IllegalArgumentException();
10330            }
10331            r.immersive = immersive;
10332
10333            // update associated state if we're frontmost
10334            if (r == mFocusedActivity) {
10335                if (DEBUG_IMMERSIVE) {
10336                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10337                }
10338                applyUpdateLockStateLocked(r);
10339            }
10340        }
10341    }
10342
10343    @Override
10344    public boolean isImmersive(IBinder token) {
10345        synchronized (this) {
10346            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10347            if (r == null) {
10348                throw new IllegalArgumentException();
10349            }
10350            return r.immersive;
10351        }
10352    }
10353
10354    public boolean isTopActivityImmersive() {
10355        enforceNotIsolatedCaller("startActivity");
10356        synchronized (this) {
10357            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10358            return (r != null) ? r.immersive : false;
10359        }
10360    }
10361
10362    @Override
10363    public boolean isTopOfTask(IBinder token) {
10364        synchronized (this) {
10365            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10366            if (r == null) {
10367                throw new IllegalArgumentException();
10368            }
10369            return r.task.getTopActivity() == r;
10370        }
10371    }
10372
10373    public final void enterSafeMode() {
10374        synchronized(this) {
10375            // It only makes sense to do this before the system is ready
10376            // and started launching other packages.
10377            if (!mSystemReady) {
10378                try {
10379                    AppGlobals.getPackageManager().enterSafeMode();
10380                } catch (RemoteException e) {
10381                }
10382            }
10383
10384            mSafeMode = true;
10385        }
10386    }
10387
10388    public final void showSafeModeOverlay() {
10389        View v = LayoutInflater.from(mContext).inflate(
10390                com.android.internal.R.layout.safe_mode, null);
10391        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10392        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10393        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10394        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10395        lp.gravity = Gravity.BOTTOM | Gravity.START;
10396        lp.format = v.getBackground().getOpacity();
10397        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10398                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10399        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10400        ((WindowManager)mContext.getSystemService(
10401                Context.WINDOW_SERVICE)).addView(v, lp);
10402    }
10403
10404    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10405        if (!(sender instanceof PendingIntentRecord)) {
10406            return;
10407        }
10408        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10409        synchronized (stats) {
10410            if (mBatteryStatsService.isOnBattery()) {
10411                mBatteryStatsService.enforceCallingPermission();
10412                PendingIntentRecord rec = (PendingIntentRecord)sender;
10413                int MY_UID = Binder.getCallingUid();
10414                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10415                BatteryStatsImpl.Uid.Pkg pkg =
10416                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10417                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10418                pkg.incWakeupsLocked();
10419            }
10420        }
10421    }
10422
10423    public boolean killPids(int[] pids, String pReason, boolean secure) {
10424        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10425            throw new SecurityException("killPids only available to the system");
10426        }
10427        String reason = (pReason == null) ? "Unknown" : pReason;
10428        // XXX Note: don't acquire main activity lock here, because the window
10429        // manager calls in with its locks held.
10430
10431        boolean killed = false;
10432        synchronized (mPidsSelfLocked) {
10433            int[] types = new int[pids.length];
10434            int worstType = 0;
10435            for (int i=0; i<pids.length; i++) {
10436                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10437                if (proc != null) {
10438                    int type = proc.setAdj;
10439                    types[i] = type;
10440                    if (type > worstType) {
10441                        worstType = type;
10442                    }
10443                }
10444            }
10445
10446            // If the worst oom_adj is somewhere in the cached proc LRU range,
10447            // then constrain it so we will kill all cached procs.
10448            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10449                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10450                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10451            }
10452
10453            // If this is not a secure call, don't let it kill processes that
10454            // are important.
10455            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10456                worstType = ProcessList.SERVICE_ADJ;
10457            }
10458
10459            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10460            for (int i=0; i<pids.length; i++) {
10461                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10462                if (proc == null) {
10463                    continue;
10464                }
10465                int adj = proc.setAdj;
10466                if (adj >= worstType && !proc.killedByAm) {
10467                    proc.kill(reason, true);
10468                    killed = true;
10469                }
10470            }
10471        }
10472        return killed;
10473    }
10474
10475    @Override
10476    public void killUid(int uid, String reason) {
10477        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10478            throw new SecurityException("killUid only available to the system");
10479        }
10480        synchronized (this) {
10481            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10482                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10483                    reason != null ? reason : "kill uid");
10484        }
10485    }
10486
10487    @Override
10488    public boolean killProcessesBelowForeground(String reason) {
10489        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10490            throw new SecurityException("killProcessesBelowForeground() only available to system");
10491        }
10492
10493        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10494    }
10495
10496    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10497        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10498            throw new SecurityException("killProcessesBelowAdj() only available to system");
10499        }
10500
10501        boolean killed = false;
10502        synchronized (mPidsSelfLocked) {
10503            final int size = mPidsSelfLocked.size();
10504            for (int i = 0; i < size; i++) {
10505                final int pid = mPidsSelfLocked.keyAt(i);
10506                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10507                if (proc == null) continue;
10508
10509                final int adj = proc.setAdj;
10510                if (adj > belowAdj && !proc.killedByAm) {
10511                    proc.kill(reason, true);
10512                    killed = true;
10513                }
10514            }
10515        }
10516        return killed;
10517    }
10518
10519    @Override
10520    public void hang(final IBinder who, boolean allowRestart) {
10521        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10522                != PackageManager.PERMISSION_GRANTED) {
10523            throw new SecurityException("Requires permission "
10524                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10525        }
10526
10527        final IBinder.DeathRecipient death = new DeathRecipient() {
10528            @Override
10529            public void binderDied() {
10530                synchronized (this) {
10531                    notifyAll();
10532                }
10533            }
10534        };
10535
10536        try {
10537            who.linkToDeath(death, 0);
10538        } catch (RemoteException e) {
10539            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10540            return;
10541        }
10542
10543        synchronized (this) {
10544            Watchdog.getInstance().setAllowRestart(allowRestart);
10545            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10546            synchronized (death) {
10547                while (who.isBinderAlive()) {
10548                    try {
10549                        death.wait();
10550                    } catch (InterruptedException e) {
10551                    }
10552                }
10553            }
10554            Watchdog.getInstance().setAllowRestart(true);
10555        }
10556    }
10557
10558    @Override
10559    public void restart() {
10560        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10561                != PackageManager.PERMISSION_GRANTED) {
10562            throw new SecurityException("Requires permission "
10563                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10564        }
10565
10566        Log.i(TAG, "Sending shutdown broadcast...");
10567
10568        BroadcastReceiver br = new BroadcastReceiver() {
10569            @Override public void onReceive(Context context, Intent intent) {
10570                // Now the broadcast is done, finish up the low-level shutdown.
10571                Log.i(TAG, "Shutting down activity manager...");
10572                shutdown(10000);
10573                Log.i(TAG, "Shutdown complete, restarting!");
10574                Process.killProcess(Process.myPid());
10575                System.exit(10);
10576            }
10577        };
10578
10579        // First send the high-level shut down broadcast.
10580        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10581        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10582        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10583        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10584        mContext.sendOrderedBroadcastAsUser(intent,
10585                UserHandle.ALL, null, br, mHandler, 0, null, null);
10586        */
10587        br.onReceive(mContext, intent);
10588    }
10589
10590    private long getLowRamTimeSinceIdle(long now) {
10591        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10592    }
10593
10594    @Override
10595    public void performIdleMaintenance() {
10596        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10597                != PackageManager.PERMISSION_GRANTED) {
10598            throw new SecurityException("Requires permission "
10599                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10600        }
10601
10602        synchronized (this) {
10603            final long now = SystemClock.uptimeMillis();
10604            final long timeSinceLastIdle = now - mLastIdleTime;
10605            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10606            mLastIdleTime = now;
10607            mLowRamTimeSinceLastIdle = 0;
10608            if (mLowRamStartTime != 0) {
10609                mLowRamStartTime = now;
10610            }
10611
10612            StringBuilder sb = new StringBuilder(128);
10613            sb.append("Idle maintenance over ");
10614            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10615            sb.append(" low RAM for ");
10616            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10617            Slog.i(TAG, sb.toString());
10618
10619            // If at least 1/3 of our time since the last idle period has been spent
10620            // with RAM low, then we want to kill processes.
10621            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10622
10623            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10624                ProcessRecord proc = mLruProcesses.get(i);
10625                if (proc.notCachedSinceIdle) {
10626                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10627                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10628                        if (doKilling && proc.initialIdlePss != 0
10629                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10630                            proc.kill("idle maint (pss " + proc.lastPss
10631                                    + " from " + proc.initialIdlePss + ")", true);
10632                        }
10633                    }
10634                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10635                    proc.notCachedSinceIdle = true;
10636                    proc.initialIdlePss = 0;
10637                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10638                            isSleeping(), now);
10639                }
10640            }
10641
10642            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10643            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10644        }
10645    }
10646
10647    private void retrieveSettings() {
10648        final ContentResolver resolver = mContext.getContentResolver();
10649        String debugApp = Settings.Global.getString(
10650            resolver, Settings.Global.DEBUG_APP);
10651        boolean waitForDebugger = Settings.Global.getInt(
10652            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10653        boolean alwaysFinishActivities = Settings.Global.getInt(
10654            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10655        boolean forceRtl = Settings.Global.getInt(
10656                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10657        // Transfer any global setting for forcing RTL layout, into a System Property
10658        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10659
10660        Configuration configuration = new Configuration();
10661        Settings.System.getConfiguration(resolver, configuration);
10662        if (forceRtl) {
10663            // This will take care of setting the correct layout direction flags
10664            configuration.setLayoutDirection(configuration.locale);
10665        }
10666
10667        synchronized (this) {
10668            mDebugApp = mOrigDebugApp = debugApp;
10669            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10670            mAlwaysFinishActivities = alwaysFinishActivities;
10671            // This happens before any activities are started, so we can
10672            // change mConfiguration in-place.
10673            updateConfigurationLocked(configuration, null, false, true);
10674            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10675        }
10676    }
10677
10678    public boolean testIsSystemReady() {
10679        // no need to synchronize(this) just to read & return the value
10680        return mSystemReady;
10681    }
10682
10683    private static File getCalledPreBootReceiversFile() {
10684        File dataDir = Environment.getDataDirectory();
10685        File systemDir = new File(dataDir, "system");
10686        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10687        return fname;
10688    }
10689
10690    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10691        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10692        File file = getCalledPreBootReceiversFile();
10693        FileInputStream fis = null;
10694        try {
10695            fis = new FileInputStream(file);
10696            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10697            int fvers = dis.readInt();
10698            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10699                String vers = dis.readUTF();
10700                String codename = dis.readUTF();
10701                String build = dis.readUTF();
10702                if (android.os.Build.VERSION.RELEASE.equals(vers)
10703                        && android.os.Build.VERSION.CODENAME.equals(codename)
10704                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10705                    int num = dis.readInt();
10706                    while (num > 0) {
10707                        num--;
10708                        String pkg = dis.readUTF();
10709                        String cls = dis.readUTF();
10710                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10711                    }
10712                }
10713            }
10714        } catch (FileNotFoundException e) {
10715        } catch (IOException e) {
10716            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10717        } finally {
10718            if (fis != null) {
10719                try {
10720                    fis.close();
10721                } catch (IOException e) {
10722                }
10723            }
10724        }
10725        return lastDoneReceivers;
10726    }
10727
10728    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10729        File file = getCalledPreBootReceiversFile();
10730        FileOutputStream fos = null;
10731        DataOutputStream dos = null;
10732        try {
10733            fos = new FileOutputStream(file);
10734            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10735            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10736            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10737            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10738            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10739            dos.writeInt(list.size());
10740            for (int i=0; i<list.size(); i++) {
10741                dos.writeUTF(list.get(i).getPackageName());
10742                dos.writeUTF(list.get(i).getClassName());
10743            }
10744        } catch (IOException e) {
10745            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10746            file.delete();
10747        } finally {
10748            FileUtils.sync(fos);
10749            if (dos != null) {
10750                try {
10751                    dos.close();
10752                } catch (IOException e) {
10753                    // TODO Auto-generated catch block
10754                    e.printStackTrace();
10755                }
10756            }
10757        }
10758    }
10759
10760    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10761            ArrayList<ComponentName> doneReceivers, int userId) {
10762        boolean waitingUpdate = false;
10763        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10764        List<ResolveInfo> ris = null;
10765        try {
10766            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10767                    intent, null, 0, userId);
10768        } catch (RemoteException e) {
10769        }
10770        if (ris != null) {
10771            for (int i=ris.size()-1; i>=0; i--) {
10772                if ((ris.get(i).activityInfo.applicationInfo.flags
10773                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10774                    ris.remove(i);
10775                }
10776            }
10777            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10778
10779            // For User 0, load the version number. When delivering to a new user, deliver
10780            // to all receivers.
10781            if (userId == UserHandle.USER_OWNER) {
10782                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10783                for (int i=0; i<ris.size(); i++) {
10784                    ActivityInfo ai = ris.get(i).activityInfo;
10785                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10786                    if (lastDoneReceivers.contains(comp)) {
10787                        // We already did the pre boot receiver for this app with the current
10788                        // platform version, so don't do it again...
10789                        ris.remove(i);
10790                        i--;
10791                        // ...however, do keep it as one that has been done, so we don't
10792                        // forget about it when rewriting the file of last done receivers.
10793                        doneReceivers.add(comp);
10794                    }
10795                }
10796            }
10797
10798            // If primary user, send broadcast to all available users, else just to userId
10799            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10800                    : new int[] { userId };
10801            for (int i = 0; i < ris.size(); i++) {
10802                ActivityInfo ai = ris.get(i).activityInfo;
10803                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10804                doneReceivers.add(comp);
10805                intent.setComponent(comp);
10806                for (int j=0; j<users.length; j++) {
10807                    IIntentReceiver finisher = null;
10808                    // On last receiver and user, set up a completion callback
10809                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10810                        finisher = new IIntentReceiver.Stub() {
10811                            public void performReceive(Intent intent, int resultCode,
10812                                    String data, Bundle extras, boolean ordered,
10813                                    boolean sticky, int sendingUser) {
10814                                // The raw IIntentReceiver interface is called
10815                                // with the AM lock held, so redispatch to
10816                                // execute our code without the lock.
10817                                mHandler.post(onFinishCallback);
10818                            }
10819                        };
10820                    }
10821                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10822                            + " for user " + users[j]);
10823                    broadcastIntentLocked(null, null, intent, null, finisher,
10824                            0, null, null, null, AppOpsManager.OP_NONE,
10825                            true, false, MY_PID, Process.SYSTEM_UID,
10826                            users[j]);
10827                    if (finisher != null) {
10828                        waitingUpdate = true;
10829                    }
10830                }
10831            }
10832        }
10833
10834        return waitingUpdate;
10835    }
10836
10837    public void systemReady(final Runnable goingCallback) {
10838        synchronized(this) {
10839            if (mSystemReady) {
10840                // If we're done calling all the receivers, run the next "boot phase" passed in
10841                // by the SystemServer
10842                if (goingCallback != null) {
10843                    goingCallback.run();
10844                }
10845                return;
10846            }
10847
10848            // Make sure we have the current profile info, since it is needed for
10849            // security checks.
10850            updateCurrentProfileIdsLocked();
10851
10852            if (mRecentTasks == null) {
10853                mRecentTasks = mTaskPersister.restoreTasksLocked();
10854                if (!mRecentTasks.isEmpty()) {
10855                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10856                }
10857                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10858                mTaskPersister.startPersisting();
10859            }
10860
10861            // Check to see if there are any update receivers to run.
10862            if (!mDidUpdate) {
10863                if (mWaitingUpdate) {
10864                    return;
10865                }
10866                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10867                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10868                    public void run() {
10869                        synchronized (ActivityManagerService.this) {
10870                            mDidUpdate = true;
10871                        }
10872                        writeLastDonePreBootReceivers(doneReceivers);
10873                        showBootMessage(mContext.getText(
10874                                R.string.android_upgrading_complete),
10875                                false);
10876                        systemReady(goingCallback);
10877                    }
10878                }, doneReceivers, UserHandle.USER_OWNER);
10879
10880                if (mWaitingUpdate) {
10881                    return;
10882                }
10883                mDidUpdate = true;
10884            }
10885
10886            mAppOpsService.systemReady();
10887            mSystemReady = true;
10888        }
10889
10890        ArrayList<ProcessRecord> procsToKill = null;
10891        synchronized(mPidsSelfLocked) {
10892            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10893                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10894                if (!isAllowedWhileBooting(proc.info)){
10895                    if (procsToKill == null) {
10896                        procsToKill = new ArrayList<ProcessRecord>();
10897                    }
10898                    procsToKill.add(proc);
10899                }
10900            }
10901        }
10902
10903        synchronized(this) {
10904            if (procsToKill != null) {
10905                for (int i=procsToKill.size()-1; i>=0; i--) {
10906                    ProcessRecord proc = procsToKill.get(i);
10907                    Slog.i(TAG, "Removing system update proc: " + proc);
10908                    removeProcessLocked(proc, true, false, "system update done");
10909                }
10910            }
10911
10912            // Now that we have cleaned up any update processes, we
10913            // are ready to start launching real processes and know that
10914            // we won't trample on them any more.
10915            mProcessesReady = true;
10916        }
10917
10918        Slog.i(TAG, "System now ready");
10919        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10920            SystemClock.uptimeMillis());
10921
10922        synchronized(this) {
10923            // Make sure we have no pre-ready processes sitting around.
10924
10925            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10926                ResolveInfo ri = mContext.getPackageManager()
10927                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10928                                STOCK_PM_FLAGS);
10929                CharSequence errorMsg = null;
10930                if (ri != null) {
10931                    ActivityInfo ai = ri.activityInfo;
10932                    ApplicationInfo app = ai.applicationInfo;
10933                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10934                        mTopAction = Intent.ACTION_FACTORY_TEST;
10935                        mTopData = null;
10936                        mTopComponent = new ComponentName(app.packageName,
10937                                ai.name);
10938                    } else {
10939                        errorMsg = mContext.getResources().getText(
10940                                com.android.internal.R.string.factorytest_not_system);
10941                    }
10942                } else {
10943                    errorMsg = mContext.getResources().getText(
10944                            com.android.internal.R.string.factorytest_no_action);
10945                }
10946                if (errorMsg != null) {
10947                    mTopAction = null;
10948                    mTopData = null;
10949                    mTopComponent = null;
10950                    Message msg = Message.obtain();
10951                    msg.what = SHOW_FACTORY_ERROR_MSG;
10952                    msg.getData().putCharSequence("msg", errorMsg);
10953                    mHandler.sendMessage(msg);
10954                }
10955            }
10956        }
10957
10958        retrieveSettings();
10959
10960        synchronized (this) {
10961            readGrantedUriPermissionsLocked();
10962        }
10963
10964        if (goingCallback != null) goingCallback.run();
10965
10966        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10967                Integer.toString(mCurrentUserId), mCurrentUserId);
10968        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10969                Integer.toString(mCurrentUserId), mCurrentUserId);
10970        mSystemServiceManager.startUser(mCurrentUserId);
10971
10972        synchronized (this) {
10973            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10974                try {
10975                    List apps = AppGlobals.getPackageManager().
10976                        getPersistentApplications(STOCK_PM_FLAGS);
10977                    if (apps != null) {
10978                        int N = apps.size();
10979                        int i;
10980                        for (i=0; i<N; i++) {
10981                            ApplicationInfo info
10982                                = (ApplicationInfo)apps.get(i);
10983                            if (info != null &&
10984                                    !info.packageName.equals("android")) {
10985                                addAppLocked(info, false, null /* ABI override */);
10986                            }
10987                        }
10988                    }
10989                } catch (RemoteException ex) {
10990                    // pm is in same process, this will never happen.
10991                }
10992            }
10993
10994            // Start up initial activity.
10995            mBooting = true;
10996
10997            try {
10998                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10999                    Message msg = Message.obtain();
11000                    msg.what = SHOW_UID_ERROR_MSG;
11001                    mHandler.sendMessage(msg);
11002                }
11003            } catch (RemoteException e) {
11004            }
11005
11006            long ident = Binder.clearCallingIdentity();
11007            try {
11008                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11009                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11010                        | Intent.FLAG_RECEIVER_FOREGROUND);
11011                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11012                broadcastIntentLocked(null, null, intent,
11013                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11014                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11015                intent = new Intent(Intent.ACTION_USER_STARTING);
11016                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11017                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11018                broadcastIntentLocked(null, null, intent,
11019                        null, new IIntentReceiver.Stub() {
11020                            @Override
11021                            public void performReceive(Intent intent, int resultCode, String data,
11022                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11023                                    throws RemoteException {
11024                            }
11025                        }, 0, null, null,
11026                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11027                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11028            } catch (Throwable t) {
11029                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11030            } finally {
11031                Binder.restoreCallingIdentity(ident);
11032            }
11033            mStackSupervisor.resumeTopActivitiesLocked();
11034            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11035        }
11036    }
11037
11038    private boolean makeAppCrashingLocked(ProcessRecord app,
11039            String shortMsg, String longMsg, String stackTrace) {
11040        app.crashing = true;
11041        app.crashingReport = generateProcessError(app,
11042                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11043        startAppProblemLocked(app);
11044        app.stopFreezingAllLocked();
11045        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11046    }
11047
11048    private void makeAppNotRespondingLocked(ProcessRecord app,
11049            String activity, String shortMsg, String longMsg) {
11050        app.notResponding = true;
11051        app.notRespondingReport = generateProcessError(app,
11052                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11053                activity, shortMsg, longMsg, null);
11054        startAppProblemLocked(app);
11055        app.stopFreezingAllLocked();
11056    }
11057
11058    /**
11059     * Generate a process error record, suitable for attachment to a ProcessRecord.
11060     *
11061     * @param app The ProcessRecord in which the error occurred.
11062     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11063     *                      ActivityManager.AppErrorStateInfo
11064     * @param activity The activity associated with the crash, if known.
11065     * @param shortMsg Short message describing the crash.
11066     * @param longMsg Long message describing the crash.
11067     * @param stackTrace Full crash stack trace, may be null.
11068     *
11069     * @return Returns a fully-formed AppErrorStateInfo record.
11070     */
11071    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11072            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11073        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11074
11075        report.condition = condition;
11076        report.processName = app.processName;
11077        report.pid = app.pid;
11078        report.uid = app.info.uid;
11079        report.tag = activity;
11080        report.shortMsg = shortMsg;
11081        report.longMsg = longMsg;
11082        report.stackTrace = stackTrace;
11083
11084        return report;
11085    }
11086
11087    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11088        synchronized (this) {
11089            app.crashing = false;
11090            app.crashingReport = null;
11091            app.notResponding = false;
11092            app.notRespondingReport = null;
11093            if (app.anrDialog == fromDialog) {
11094                app.anrDialog = null;
11095            }
11096            if (app.waitDialog == fromDialog) {
11097                app.waitDialog = null;
11098            }
11099            if (app.pid > 0 && app.pid != MY_PID) {
11100                handleAppCrashLocked(app, null, null, null);
11101                app.kill("user request after error", true);
11102            }
11103        }
11104    }
11105
11106    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11107            String stackTrace) {
11108        long now = SystemClock.uptimeMillis();
11109
11110        Long crashTime;
11111        if (!app.isolated) {
11112            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11113        } else {
11114            crashTime = null;
11115        }
11116        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11117            // This process loses!
11118            Slog.w(TAG, "Process " + app.info.processName
11119                    + " has crashed too many times: killing!");
11120            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11121                    app.userId, app.info.processName, app.uid);
11122            mStackSupervisor.handleAppCrashLocked(app);
11123            if (!app.persistent) {
11124                // We don't want to start this process again until the user
11125                // explicitly does so...  but for persistent process, we really
11126                // need to keep it running.  If a persistent process is actually
11127                // repeatedly crashing, then badness for everyone.
11128                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11129                        app.info.processName);
11130                if (!app.isolated) {
11131                    // XXX We don't have a way to mark isolated processes
11132                    // as bad, since they don't have a peristent identity.
11133                    mBadProcesses.put(app.info.processName, app.uid,
11134                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11135                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11136                }
11137                app.bad = true;
11138                app.removed = true;
11139                // Don't let services in this process be restarted and potentially
11140                // annoy the user repeatedly.  Unless it is persistent, since those
11141                // processes run critical code.
11142                removeProcessLocked(app, false, false, "crash");
11143                mStackSupervisor.resumeTopActivitiesLocked();
11144                return false;
11145            }
11146            mStackSupervisor.resumeTopActivitiesLocked();
11147        } else {
11148            mStackSupervisor.finishTopRunningActivityLocked(app);
11149        }
11150
11151        // Bump up the crash count of any services currently running in the proc.
11152        for (int i=app.services.size()-1; i>=0; i--) {
11153            // Any services running in the application need to be placed
11154            // back in the pending list.
11155            ServiceRecord sr = app.services.valueAt(i);
11156            sr.crashCount++;
11157        }
11158
11159        // If the crashing process is what we consider to be the "home process" and it has been
11160        // replaced by a third-party app, clear the package preferred activities from packages
11161        // with a home activity running in the process to prevent a repeatedly crashing app
11162        // from blocking the user to manually clear the list.
11163        final ArrayList<ActivityRecord> activities = app.activities;
11164        if (app == mHomeProcess && activities.size() > 0
11165                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11166            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11167                final ActivityRecord r = activities.get(activityNdx);
11168                if (r.isHomeActivity()) {
11169                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11170                    try {
11171                        ActivityThread.getPackageManager()
11172                                .clearPackagePreferredActivities(r.packageName);
11173                    } catch (RemoteException c) {
11174                        // pm is in same process, this will never happen.
11175                    }
11176                }
11177            }
11178        }
11179
11180        if (!app.isolated) {
11181            // XXX Can't keep track of crash times for isolated processes,
11182            // because they don't have a perisistent identity.
11183            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11184        }
11185
11186        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11187        return true;
11188    }
11189
11190    void startAppProblemLocked(ProcessRecord app) {
11191        // If this app is not running under the current user, then we
11192        // can't give it a report button because that would require
11193        // launching the report UI under a different user.
11194        app.errorReportReceiver = null;
11195
11196        for (int userId : mCurrentProfileIds) {
11197            if (app.userId == userId) {
11198                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11199                        mContext, app.info.packageName, app.info.flags);
11200            }
11201        }
11202        skipCurrentReceiverLocked(app);
11203    }
11204
11205    void skipCurrentReceiverLocked(ProcessRecord app) {
11206        for (BroadcastQueue queue : mBroadcastQueues) {
11207            queue.skipCurrentReceiverLocked(app);
11208        }
11209    }
11210
11211    /**
11212     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11213     * The application process will exit immediately after this call returns.
11214     * @param app object of the crashing app, null for the system server
11215     * @param crashInfo describing the exception
11216     */
11217    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11218        ProcessRecord r = findAppProcess(app, "Crash");
11219        final String processName = app == null ? "system_server"
11220                : (r == null ? "unknown" : r.processName);
11221
11222        handleApplicationCrashInner("crash", r, processName, crashInfo);
11223    }
11224
11225    /* Native crash reporting uses this inner version because it needs to be somewhat
11226     * decoupled from the AM-managed cleanup lifecycle
11227     */
11228    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11229            ApplicationErrorReport.CrashInfo crashInfo) {
11230        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11231                UserHandle.getUserId(Binder.getCallingUid()), processName,
11232                r == null ? -1 : r.info.flags,
11233                crashInfo.exceptionClassName,
11234                crashInfo.exceptionMessage,
11235                crashInfo.throwFileName,
11236                crashInfo.throwLineNumber);
11237
11238        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11239
11240        crashApplication(r, crashInfo);
11241    }
11242
11243    public void handleApplicationStrictModeViolation(
11244            IBinder app,
11245            int violationMask,
11246            StrictMode.ViolationInfo info) {
11247        ProcessRecord r = findAppProcess(app, "StrictMode");
11248        if (r == null) {
11249            return;
11250        }
11251
11252        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11253            Integer stackFingerprint = info.hashCode();
11254            boolean logIt = true;
11255            synchronized (mAlreadyLoggedViolatedStacks) {
11256                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11257                    logIt = false;
11258                    // TODO: sub-sample into EventLog for these, with
11259                    // the info.durationMillis?  Then we'd get
11260                    // the relative pain numbers, without logging all
11261                    // the stack traces repeatedly.  We'd want to do
11262                    // likewise in the client code, which also does
11263                    // dup suppression, before the Binder call.
11264                } else {
11265                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11266                        mAlreadyLoggedViolatedStacks.clear();
11267                    }
11268                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11269                }
11270            }
11271            if (logIt) {
11272                logStrictModeViolationToDropBox(r, info);
11273            }
11274        }
11275
11276        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11277            AppErrorResult result = new AppErrorResult();
11278            synchronized (this) {
11279                final long origId = Binder.clearCallingIdentity();
11280
11281                Message msg = Message.obtain();
11282                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11283                HashMap<String, Object> data = new HashMap<String, Object>();
11284                data.put("result", result);
11285                data.put("app", r);
11286                data.put("violationMask", violationMask);
11287                data.put("info", info);
11288                msg.obj = data;
11289                mHandler.sendMessage(msg);
11290
11291                Binder.restoreCallingIdentity(origId);
11292            }
11293            int res = result.get();
11294            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11295        }
11296    }
11297
11298    // Depending on the policy in effect, there could be a bunch of
11299    // these in quick succession so we try to batch these together to
11300    // minimize disk writes, number of dropbox entries, and maximize
11301    // compression, by having more fewer, larger records.
11302    private void logStrictModeViolationToDropBox(
11303            ProcessRecord process,
11304            StrictMode.ViolationInfo info) {
11305        if (info == null) {
11306            return;
11307        }
11308        final boolean isSystemApp = process == null ||
11309                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11310                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11311        final String processName = process == null ? "unknown" : process.processName;
11312        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11313        final DropBoxManager dbox = (DropBoxManager)
11314                mContext.getSystemService(Context.DROPBOX_SERVICE);
11315
11316        // Exit early if the dropbox isn't configured to accept this report type.
11317        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11318
11319        boolean bufferWasEmpty;
11320        boolean needsFlush;
11321        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11322        synchronized (sb) {
11323            bufferWasEmpty = sb.length() == 0;
11324            appendDropBoxProcessHeaders(process, processName, sb);
11325            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11326            sb.append("System-App: ").append(isSystemApp).append("\n");
11327            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11328            if (info.violationNumThisLoop != 0) {
11329                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11330            }
11331            if (info.numAnimationsRunning != 0) {
11332                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11333            }
11334            if (info.broadcastIntentAction != null) {
11335                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11336            }
11337            if (info.durationMillis != -1) {
11338                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11339            }
11340            if (info.numInstances != -1) {
11341                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11342            }
11343            if (info.tags != null) {
11344                for (String tag : info.tags) {
11345                    sb.append("Span-Tag: ").append(tag).append("\n");
11346                }
11347            }
11348            sb.append("\n");
11349            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11350                sb.append(info.crashInfo.stackTrace);
11351            }
11352            sb.append("\n");
11353
11354            // Only buffer up to ~64k.  Various logging bits truncate
11355            // things at 128k.
11356            needsFlush = (sb.length() > 64 * 1024);
11357        }
11358
11359        // Flush immediately if the buffer's grown too large, or this
11360        // is a non-system app.  Non-system apps are isolated with a
11361        // different tag & policy and not batched.
11362        //
11363        // Batching is useful during internal testing with
11364        // StrictMode settings turned up high.  Without batching,
11365        // thousands of separate files could be created on boot.
11366        if (!isSystemApp || needsFlush) {
11367            new Thread("Error dump: " + dropboxTag) {
11368                @Override
11369                public void run() {
11370                    String report;
11371                    synchronized (sb) {
11372                        report = sb.toString();
11373                        sb.delete(0, sb.length());
11374                        sb.trimToSize();
11375                    }
11376                    if (report.length() != 0) {
11377                        dbox.addText(dropboxTag, report);
11378                    }
11379                }
11380            }.start();
11381            return;
11382        }
11383
11384        // System app batching:
11385        if (!bufferWasEmpty) {
11386            // An existing dropbox-writing thread is outstanding, so
11387            // we don't need to start it up.  The existing thread will
11388            // catch the buffer appends we just did.
11389            return;
11390        }
11391
11392        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11393        // (After this point, we shouldn't access AMS internal data structures.)
11394        new Thread("Error dump: " + dropboxTag) {
11395            @Override
11396            public void run() {
11397                // 5 second sleep to let stacks arrive and be batched together
11398                try {
11399                    Thread.sleep(5000);  // 5 seconds
11400                } catch (InterruptedException e) {}
11401
11402                String errorReport;
11403                synchronized (mStrictModeBuffer) {
11404                    errorReport = mStrictModeBuffer.toString();
11405                    if (errorReport.length() == 0) {
11406                        return;
11407                    }
11408                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11409                    mStrictModeBuffer.trimToSize();
11410                }
11411                dbox.addText(dropboxTag, errorReport);
11412            }
11413        }.start();
11414    }
11415
11416    /**
11417     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11418     * @param app object of the crashing app, null for the system server
11419     * @param tag reported by the caller
11420     * @param system whether this wtf is coming from the system
11421     * @param crashInfo describing the context of the error
11422     * @return true if the process should exit immediately (WTF is fatal)
11423     */
11424    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11425            final ApplicationErrorReport.CrashInfo crashInfo) {
11426        final ProcessRecord r = findAppProcess(app, "WTF");
11427        final String processName = app == null ? "system_server"
11428                : (r == null ? "unknown" : r.processName);
11429
11430        EventLog.writeEvent(EventLogTags.AM_WTF,
11431                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11432                processName,
11433                r == null ? -1 : r.info.flags,
11434                tag, crashInfo.exceptionMessage);
11435
11436        if (system) {
11437            // If this is coming from the system, we could very well have low-level
11438            // system locks held, so we want to do this all asynchronously.  And we
11439            // never want this to become fatal, so there is that too.
11440            mHandler.post(new Runnable() {
11441                @Override public void run() {
11442                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11443                            crashInfo);
11444                }
11445            });
11446            return false;
11447        }
11448
11449        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11450
11451        if (r != null && r.pid != Process.myPid() &&
11452                Settings.Global.getInt(mContext.getContentResolver(),
11453                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11454            crashApplication(r, crashInfo);
11455            return true;
11456        } else {
11457            return false;
11458        }
11459    }
11460
11461    /**
11462     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11463     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11464     */
11465    private ProcessRecord findAppProcess(IBinder app, String reason) {
11466        if (app == null) {
11467            return null;
11468        }
11469
11470        synchronized (this) {
11471            final int NP = mProcessNames.getMap().size();
11472            for (int ip=0; ip<NP; ip++) {
11473                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11474                final int NA = apps.size();
11475                for (int ia=0; ia<NA; ia++) {
11476                    ProcessRecord p = apps.valueAt(ia);
11477                    if (p.thread != null && p.thread.asBinder() == app) {
11478                        return p;
11479                    }
11480                }
11481            }
11482
11483            Slog.w(TAG, "Can't find mystery application for " + reason
11484                    + " from pid=" + Binder.getCallingPid()
11485                    + " uid=" + Binder.getCallingUid() + ": " + app);
11486            return null;
11487        }
11488    }
11489
11490    /**
11491     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11492     * to append various headers to the dropbox log text.
11493     */
11494    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11495            StringBuilder sb) {
11496        // Watchdog thread ends up invoking this function (with
11497        // a null ProcessRecord) to add the stack file to dropbox.
11498        // Do not acquire a lock on this (am) in such cases, as it
11499        // could cause a potential deadlock, if and when watchdog
11500        // is invoked due to unavailability of lock on am and it
11501        // would prevent watchdog from killing system_server.
11502        if (process == null) {
11503            sb.append("Process: ").append(processName).append("\n");
11504            return;
11505        }
11506        // Note: ProcessRecord 'process' is guarded by the service
11507        // instance.  (notably process.pkgList, which could otherwise change
11508        // concurrently during execution of this method)
11509        synchronized (this) {
11510            sb.append("Process: ").append(processName).append("\n");
11511            int flags = process.info.flags;
11512            IPackageManager pm = AppGlobals.getPackageManager();
11513            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11514            for (int ip=0; ip<process.pkgList.size(); ip++) {
11515                String pkg = process.pkgList.keyAt(ip);
11516                sb.append("Package: ").append(pkg);
11517                try {
11518                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11519                    if (pi != null) {
11520                        sb.append(" v").append(pi.versionCode);
11521                        if (pi.versionName != null) {
11522                            sb.append(" (").append(pi.versionName).append(")");
11523                        }
11524                    }
11525                } catch (RemoteException e) {
11526                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11527                }
11528                sb.append("\n");
11529            }
11530        }
11531    }
11532
11533    private static String processClass(ProcessRecord process) {
11534        if (process == null || process.pid == MY_PID) {
11535            return "system_server";
11536        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11537            return "system_app";
11538        } else {
11539            return "data_app";
11540        }
11541    }
11542
11543    /**
11544     * Write a description of an error (crash, WTF, ANR) to the drop box.
11545     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11546     * @param process which caused the error, null means the system server
11547     * @param activity which triggered the error, null if unknown
11548     * @param parent activity related to the error, null if unknown
11549     * @param subject line related to the error, null if absent
11550     * @param report in long form describing the error, null if absent
11551     * @param logFile to include in the report, null if none
11552     * @param crashInfo giving an application stack trace, null if absent
11553     */
11554    public void addErrorToDropBox(String eventType,
11555            ProcessRecord process, String processName, ActivityRecord activity,
11556            ActivityRecord parent, String subject,
11557            final String report, final File logFile,
11558            final ApplicationErrorReport.CrashInfo crashInfo) {
11559        // NOTE -- this must never acquire the ActivityManagerService lock,
11560        // otherwise the watchdog may be prevented from resetting the system.
11561
11562        final String dropboxTag = processClass(process) + "_" + eventType;
11563        final DropBoxManager dbox = (DropBoxManager)
11564                mContext.getSystemService(Context.DROPBOX_SERVICE);
11565
11566        // Exit early if the dropbox isn't configured to accept this report type.
11567        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11568
11569        final StringBuilder sb = new StringBuilder(1024);
11570        appendDropBoxProcessHeaders(process, processName, sb);
11571        if (activity != null) {
11572            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11573        }
11574        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11575            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11576        }
11577        if (parent != null && parent != activity) {
11578            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11579        }
11580        if (subject != null) {
11581            sb.append("Subject: ").append(subject).append("\n");
11582        }
11583        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11584        if (Debug.isDebuggerConnected()) {
11585            sb.append("Debugger: Connected\n");
11586        }
11587        sb.append("\n");
11588
11589        // Do the rest in a worker thread to avoid blocking the caller on I/O
11590        // (After this point, we shouldn't access AMS internal data structures.)
11591        Thread worker = new Thread("Error dump: " + dropboxTag) {
11592            @Override
11593            public void run() {
11594                if (report != null) {
11595                    sb.append(report);
11596                }
11597                if (logFile != null) {
11598                    try {
11599                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11600                                    "\n\n[[TRUNCATED]]"));
11601                    } catch (IOException e) {
11602                        Slog.e(TAG, "Error reading " + logFile, e);
11603                    }
11604                }
11605                if (crashInfo != null && crashInfo.stackTrace != null) {
11606                    sb.append(crashInfo.stackTrace);
11607                }
11608
11609                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11610                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11611                if (lines > 0) {
11612                    sb.append("\n");
11613
11614                    // Merge several logcat streams, and take the last N lines
11615                    InputStreamReader input = null;
11616                    try {
11617                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11618                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11619                                "-b", "crash",
11620                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11621
11622                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11623                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11624                        input = new InputStreamReader(logcat.getInputStream());
11625
11626                        int num;
11627                        char[] buf = new char[8192];
11628                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11629                    } catch (IOException e) {
11630                        Slog.e(TAG, "Error running logcat", e);
11631                    } finally {
11632                        if (input != null) try { input.close(); } catch (IOException e) {}
11633                    }
11634                }
11635
11636                dbox.addText(dropboxTag, sb.toString());
11637            }
11638        };
11639
11640        if (process == null) {
11641            // If process is null, we are being called from some internal code
11642            // and may be about to die -- run this synchronously.
11643            worker.run();
11644        } else {
11645            worker.start();
11646        }
11647    }
11648
11649    /**
11650     * Bring up the "unexpected error" dialog box for a crashing app.
11651     * Deal with edge cases (intercepts from instrumented applications,
11652     * ActivityController, error intent receivers, that sort of thing).
11653     * @param r the application crashing
11654     * @param crashInfo describing the failure
11655     */
11656    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11657        long timeMillis = System.currentTimeMillis();
11658        String shortMsg = crashInfo.exceptionClassName;
11659        String longMsg = crashInfo.exceptionMessage;
11660        String stackTrace = crashInfo.stackTrace;
11661        if (shortMsg != null && longMsg != null) {
11662            longMsg = shortMsg + ": " + longMsg;
11663        } else if (shortMsg != null) {
11664            longMsg = shortMsg;
11665        }
11666
11667        AppErrorResult result = new AppErrorResult();
11668        synchronized (this) {
11669            if (mController != null) {
11670                try {
11671                    String name = r != null ? r.processName : null;
11672                    int pid = r != null ? r.pid : Binder.getCallingPid();
11673                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11674                    if (!mController.appCrashed(name, pid,
11675                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11676                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11677                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11678                            Slog.w(TAG, "Skip killing native crashed app " + name
11679                                    + "(" + pid + ") during testing");
11680                        } else {
11681                            Slog.w(TAG, "Force-killing crashed app " + name
11682                                    + " at watcher's request");
11683                            if (r != null) {
11684                                r.kill("crash", true);
11685                            } else {
11686                                // Huh.
11687                                Process.killProcess(pid);
11688                                Process.killProcessGroup(uid, pid);
11689                            }
11690                        }
11691                        return;
11692                    }
11693                } catch (RemoteException e) {
11694                    mController = null;
11695                    Watchdog.getInstance().setActivityController(null);
11696                }
11697            }
11698
11699            final long origId = Binder.clearCallingIdentity();
11700
11701            // If this process is running instrumentation, finish it.
11702            if (r != null && r.instrumentationClass != null) {
11703                Slog.w(TAG, "Error in app " + r.processName
11704                      + " running instrumentation " + r.instrumentationClass + ":");
11705                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11706                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11707                Bundle info = new Bundle();
11708                info.putString("shortMsg", shortMsg);
11709                info.putString("longMsg", longMsg);
11710                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11711                Binder.restoreCallingIdentity(origId);
11712                return;
11713            }
11714
11715            // If we can't identify the process or it's already exceeded its crash quota,
11716            // quit right away without showing a crash dialog.
11717            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11718                Binder.restoreCallingIdentity(origId);
11719                return;
11720            }
11721
11722            Message msg = Message.obtain();
11723            msg.what = SHOW_ERROR_MSG;
11724            HashMap data = new HashMap();
11725            data.put("result", result);
11726            data.put("app", r);
11727            msg.obj = data;
11728            mHandler.sendMessage(msg);
11729
11730            Binder.restoreCallingIdentity(origId);
11731        }
11732
11733        int res = result.get();
11734
11735        Intent appErrorIntent = null;
11736        synchronized (this) {
11737            if (r != null && !r.isolated) {
11738                // XXX Can't keep track of crash time for isolated processes,
11739                // since they don't have a persistent identity.
11740                mProcessCrashTimes.put(r.info.processName, r.uid,
11741                        SystemClock.uptimeMillis());
11742            }
11743            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11744                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11745            }
11746        }
11747
11748        if (appErrorIntent != null) {
11749            try {
11750                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11751            } catch (ActivityNotFoundException e) {
11752                Slog.w(TAG, "bug report receiver dissappeared", e);
11753            }
11754        }
11755    }
11756
11757    Intent createAppErrorIntentLocked(ProcessRecord r,
11758            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11759        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11760        if (report == null) {
11761            return null;
11762        }
11763        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11764        result.setComponent(r.errorReportReceiver);
11765        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11766        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11767        return result;
11768    }
11769
11770    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11771            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11772        if (r.errorReportReceiver == null) {
11773            return null;
11774        }
11775
11776        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11777            return null;
11778        }
11779
11780        ApplicationErrorReport report = new ApplicationErrorReport();
11781        report.packageName = r.info.packageName;
11782        report.installerPackageName = r.errorReportReceiver.getPackageName();
11783        report.processName = r.processName;
11784        report.time = timeMillis;
11785        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11786
11787        if (r.crashing || r.forceCrashReport) {
11788            report.type = ApplicationErrorReport.TYPE_CRASH;
11789            report.crashInfo = crashInfo;
11790        } else if (r.notResponding) {
11791            report.type = ApplicationErrorReport.TYPE_ANR;
11792            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11793
11794            report.anrInfo.activity = r.notRespondingReport.tag;
11795            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11796            report.anrInfo.info = r.notRespondingReport.longMsg;
11797        }
11798
11799        return report;
11800    }
11801
11802    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11803        enforceNotIsolatedCaller("getProcessesInErrorState");
11804        // assume our apps are happy - lazy create the list
11805        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11806
11807        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11808                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11809        int userId = UserHandle.getUserId(Binder.getCallingUid());
11810
11811        synchronized (this) {
11812
11813            // iterate across all processes
11814            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11815                ProcessRecord app = mLruProcesses.get(i);
11816                if (!allUsers && app.userId != userId) {
11817                    continue;
11818                }
11819                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11820                    // This one's in trouble, so we'll generate a report for it
11821                    // crashes are higher priority (in case there's a crash *and* an anr)
11822                    ActivityManager.ProcessErrorStateInfo report = null;
11823                    if (app.crashing) {
11824                        report = app.crashingReport;
11825                    } else if (app.notResponding) {
11826                        report = app.notRespondingReport;
11827                    }
11828
11829                    if (report != null) {
11830                        if (errList == null) {
11831                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11832                        }
11833                        errList.add(report);
11834                    } else {
11835                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11836                                " crashing = " + app.crashing +
11837                                " notResponding = " + app.notResponding);
11838                    }
11839                }
11840            }
11841        }
11842
11843        return errList;
11844    }
11845
11846    static int procStateToImportance(int procState, int memAdj,
11847            ActivityManager.RunningAppProcessInfo currApp) {
11848        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11849        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11850            currApp.lru = memAdj;
11851        } else {
11852            currApp.lru = 0;
11853        }
11854        return imp;
11855    }
11856
11857    private void fillInProcMemInfo(ProcessRecord app,
11858            ActivityManager.RunningAppProcessInfo outInfo) {
11859        outInfo.pid = app.pid;
11860        outInfo.uid = app.info.uid;
11861        if (mHeavyWeightProcess == app) {
11862            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11863        }
11864        if (app.persistent) {
11865            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11866        }
11867        if (app.activities.size() > 0) {
11868            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11869        }
11870        outInfo.lastTrimLevel = app.trimMemoryLevel;
11871        int adj = app.curAdj;
11872        int procState = app.curProcState;
11873        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11874        outInfo.importanceReasonCode = app.adjTypeCode;
11875        outInfo.processState = app.curProcState;
11876    }
11877
11878    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11879        enforceNotIsolatedCaller("getRunningAppProcesses");
11880        // Lazy instantiation of list
11881        List<ActivityManager.RunningAppProcessInfo> runList = null;
11882        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11883                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11884        int userId = UserHandle.getUserId(Binder.getCallingUid());
11885        synchronized (this) {
11886            // Iterate across all processes
11887            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11888                ProcessRecord app = mLruProcesses.get(i);
11889                if (!allUsers && app.userId != userId) {
11890                    continue;
11891                }
11892                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11893                    // Generate process state info for running application
11894                    ActivityManager.RunningAppProcessInfo currApp =
11895                        new ActivityManager.RunningAppProcessInfo(app.processName,
11896                                app.pid, app.getPackageList());
11897                    fillInProcMemInfo(app, currApp);
11898                    if (app.adjSource instanceof ProcessRecord) {
11899                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11900                        currApp.importanceReasonImportance =
11901                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11902                                        app.adjSourceProcState);
11903                    } else if (app.adjSource instanceof ActivityRecord) {
11904                        ActivityRecord r = (ActivityRecord)app.adjSource;
11905                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11906                    }
11907                    if (app.adjTarget instanceof ComponentName) {
11908                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11909                    }
11910                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11911                    //        + " lru=" + currApp.lru);
11912                    if (runList == null) {
11913                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11914                    }
11915                    runList.add(currApp);
11916                }
11917            }
11918        }
11919        return runList;
11920    }
11921
11922    public List<ApplicationInfo> getRunningExternalApplications() {
11923        enforceNotIsolatedCaller("getRunningExternalApplications");
11924        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11925        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11926        if (runningApps != null && runningApps.size() > 0) {
11927            Set<String> extList = new HashSet<String>();
11928            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11929                if (app.pkgList != null) {
11930                    for (String pkg : app.pkgList) {
11931                        extList.add(pkg);
11932                    }
11933                }
11934            }
11935            IPackageManager pm = AppGlobals.getPackageManager();
11936            for (String pkg : extList) {
11937                try {
11938                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11939                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11940                        retList.add(info);
11941                    }
11942                } catch (RemoteException e) {
11943                }
11944            }
11945        }
11946        return retList;
11947    }
11948
11949    @Override
11950    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11951        enforceNotIsolatedCaller("getMyMemoryState");
11952        synchronized (this) {
11953            ProcessRecord proc;
11954            synchronized (mPidsSelfLocked) {
11955                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11956            }
11957            fillInProcMemInfo(proc, outInfo);
11958        }
11959    }
11960
11961    @Override
11962    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11963        if (checkCallingPermission(android.Manifest.permission.DUMP)
11964                != PackageManager.PERMISSION_GRANTED) {
11965            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11966                    + Binder.getCallingPid()
11967                    + ", uid=" + Binder.getCallingUid()
11968                    + " without permission "
11969                    + android.Manifest.permission.DUMP);
11970            return;
11971        }
11972
11973        boolean dumpAll = false;
11974        boolean dumpClient = false;
11975        String dumpPackage = null;
11976
11977        int opti = 0;
11978        while (opti < args.length) {
11979            String opt = args[opti];
11980            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11981                break;
11982            }
11983            opti++;
11984            if ("-a".equals(opt)) {
11985                dumpAll = true;
11986            } else if ("-c".equals(opt)) {
11987                dumpClient = true;
11988            } else if ("-h".equals(opt)) {
11989                pw.println("Activity manager dump options:");
11990                pw.println("  [-a] [-c] [-h] [cmd] ...");
11991                pw.println("  cmd may be one of:");
11992                pw.println("    a[ctivities]: activity stack state");
11993                pw.println("    r[recents]: recent activities state");
11994                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11995                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11996                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11997                pw.println("    o[om]: out of memory management");
11998                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11999                pw.println("    provider [COMP_SPEC]: provider client-side state");
12000                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12001                pw.println("    service [COMP_SPEC]: service client-side state");
12002                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12003                pw.println("    all: dump all activities");
12004                pw.println("    top: dump the top activity");
12005                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12006                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12007                pw.println("    a partial substring in a component name, a");
12008                pw.println("    hex object identifier.");
12009                pw.println("  -a: include all available server state.");
12010                pw.println("  -c: include client state.");
12011                return;
12012            } else {
12013                pw.println("Unknown argument: " + opt + "; use -h for help");
12014            }
12015        }
12016
12017        long origId = Binder.clearCallingIdentity();
12018        boolean more = false;
12019        // Is the caller requesting to dump a particular piece of data?
12020        if (opti < args.length) {
12021            String cmd = args[opti];
12022            opti++;
12023            if ("activities".equals(cmd) || "a".equals(cmd)) {
12024                synchronized (this) {
12025                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12026                }
12027            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12028                synchronized (this) {
12029                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12030                }
12031            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12032                String[] newArgs;
12033                String name;
12034                if (opti >= args.length) {
12035                    name = null;
12036                    newArgs = EMPTY_STRING_ARRAY;
12037                } else {
12038                    name = args[opti];
12039                    opti++;
12040                    newArgs = new String[args.length - opti];
12041                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12042                            args.length - opti);
12043                }
12044                synchronized (this) {
12045                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12046                }
12047            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12048                String[] newArgs;
12049                String name;
12050                if (opti >= args.length) {
12051                    name = null;
12052                    newArgs = EMPTY_STRING_ARRAY;
12053                } else {
12054                    name = args[opti];
12055                    opti++;
12056                    newArgs = new String[args.length - opti];
12057                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12058                            args.length - opti);
12059                }
12060                synchronized (this) {
12061                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12062                }
12063            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12064                String[] newArgs;
12065                String name;
12066                if (opti >= args.length) {
12067                    name = null;
12068                    newArgs = EMPTY_STRING_ARRAY;
12069                } else {
12070                    name = args[opti];
12071                    opti++;
12072                    newArgs = new String[args.length - opti];
12073                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12074                            args.length - opti);
12075                }
12076                synchronized (this) {
12077                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12078                }
12079            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12080                synchronized (this) {
12081                    dumpOomLocked(fd, pw, args, opti, true);
12082                }
12083            } else if ("provider".equals(cmd)) {
12084                String[] newArgs;
12085                String name;
12086                if (opti >= args.length) {
12087                    name = null;
12088                    newArgs = EMPTY_STRING_ARRAY;
12089                } else {
12090                    name = args[opti];
12091                    opti++;
12092                    newArgs = new String[args.length - opti];
12093                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12094                }
12095                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12096                    pw.println("No providers match: " + name);
12097                    pw.println("Use -h for help.");
12098                }
12099            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12100                synchronized (this) {
12101                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12102                }
12103            } else if ("service".equals(cmd)) {
12104                String[] newArgs;
12105                String name;
12106                if (opti >= args.length) {
12107                    name = null;
12108                    newArgs = EMPTY_STRING_ARRAY;
12109                } else {
12110                    name = args[opti];
12111                    opti++;
12112                    newArgs = new String[args.length - opti];
12113                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12114                            args.length - opti);
12115                }
12116                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12117                    pw.println("No services match: " + name);
12118                    pw.println("Use -h for help.");
12119                }
12120            } else if ("package".equals(cmd)) {
12121                String[] newArgs;
12122                if (opti >= args.length) {
12123                    pw.println("package: no package name specified");
12124                    pw.println("Use -h for help.");
12125                } else {
12126                    dumpPackage = args[opti];
12127                    opti++;
12128                    newArgs = new String[args.length - opti];
12129                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12130                            args.length - opti);
12131                    args = newArgs;
12132                    opti = 0;
12133                    more = true;
12134                }
12135            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12136                synchronized (this) {
12137                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12138                }
12139            } else {
12140                // Dumping a single activity?
12141                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12142                    pw.println("Bad activity command, or no activities match: " + cmd);
12143                    pw.println("Use -h for help.");
12144                }
12145            }
12146            if (!more) {
12147                Binder.restoreCallingIdentity(origId);
12148                return;
12149            }
12150        }
12151
12152        // No piece of data specified, dump everything.
12153        synchronized (this) {
12154            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12155            pw.println();
12156            if (dumpAll) {
12157                pw.println("-------------------------------------------------------------------------------");
12158            }
12159            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12160            pw.println();
12161            if (dumpAll) {
12162                pw.println("-------------------------------------------------------------------------------");
12163            }
12164            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12165            pw.println();
12166            if (dumpAll) {
12167                pw.println("-------------------------------------------------------------------------------");
12168            }
12169            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12170            pw.println();
12171            if (dumpAll) {
12172                pw.println("-------------------------------------------------------------------------------");
12173            }
12174            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12175            pw.println();
12176            if (dumpAll) {
12177                pw.println("-------------------------------------------------------------------------------");
12178            }
12179            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12180            pw.println();
12181            if (dumpAll) {
12182                pw.println("-------------------------------------------------------------------------------");
12183            }
12184            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12185        }
12186        Binder.restoreCallingIdentity(origId);
12187    }
12188
12189    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12190            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12191        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12192
12193        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12194                dumpPackage);
12195        boolean needSep = printedAnything;
12196
12197        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12198                dumpPackage, needSep, "  mFocusedActivity: ");
12199        if (printed) {
12200            printedAnything = true;
12201            needSep = false;
12202        }
12203
12204        if (dumpPackage == null) {
12205            if (needSep) {
12206                pw.println();
12207            }
12208            needSep = true;
12209            printedAnything = true;
12210            mStackSupervisor.dump(pw, "  ");
12211        }
12212
12213        if (!printedAnything) {
12214            pw.println("  (nothing)");
12215        }
12216    }
12217
12218    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12219            int opti, boolean dumpAll, String dumpPackage) {
12220        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12221
12222        boolean printedAnything = false;
12223
12224        if (mRecentTasks.size() > 0) {
12225            boolean printedHeader = false;
12226
12227            final int N = mRecentTasks.size();
12228            for (int i=0; i<N; i++) {
12229                TaskRecord tr = mRecentTasks.get(i);
12230                if (dumpPackage != null) {
12231                    if (tr.realActivity == null ||
12232                            !dumpPackage.equals(tr.realActivity)) {
12233                        continue;
12234                    }
12235                }
12236                if (!printedHeader) {
12237                    pw.println("  Recent tasks:");
12238                    printedHeader = true;
12239                    printedAnything = true;
12240                }
12241                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12242                        pw.println(tr);
12243                if (dumpAll) {
12244                    mRecentTasks.get(i).dump(pw, "    ");
12245                }
12246            }
12247        }
12248
12249        if (!printedAnything) {
12250            pw.println("  (nothing)");
12251        }
12252    }
12253
12254    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12255            int opti, boolean dumpAll, String dumpPackage) {
12256        boolean needSep = false;
12257        boolean printedAnything = false;
12258        int numPers = 0;
12259
12260        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12261
12262        if (dumpAll) {
12263            final int NP = mProcessNames.getMap().size();
12264            for (int ip=0; ip<NP; ip++) {
12265                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12266                final int NA = procs.size();
12267                for (int ia=0; ia<NA; ia++) {
12268                    ProcessRecord r = procs.valueAt(ia);
12269                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12270                        continue;
12271                    }
12272                    if (!needSep) {
12273                        pw.println("  All known processes:");
12274                        needSep = true;
12275                        printedAnything = true;
12276                    }
12277                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12278                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12279                        pw.print(" "); pw.println(r);
12280                    r.dump(pw, "    ");
12281                    if (r.persistent) {
12282                        numPers++;
12283                    }
12284                }
12285            }
12286        }
12287
12288        if (mIsolatedProcesses.size() > 0) {
12289            boolean printed = false;
12290            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12291                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12292                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12293                    continue;
12294                }
12295                if (!printed) {
12296                    if (needSep) {
12297                        pw.println();
12298                    }
12299                    pw.println("  Isolated process list (sorted by uid):");
12300                    printedAnything = true;
12301                    printed = true;
12302                    needSep = true;
12303                }
12304                pw.println(String.format("%sIsolated #%2d: %s",
12305                        "    ", i, r.toString()));
12306            }
12307        }
12308
12309        if (mLruProcesses.size() > 0) {
12310            if (needSep) {
12311                pw.println();
12312            }
12313            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12314                    pw.print(" total, non-act at ");
12315                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12316                    pw.print(", non-svc at ");
12317                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12318                    pw.println("):");
12319            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12320            needSep = true;
12321            printedAnything = true;
12322        }
12323
12324        if (dumpAll || dumpPackage != null) {
12325            synchronized (mPidsSelfLocked) {
12326                boolean printed = false;
12327                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12328                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12329                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12330                        continue;
12331                    }
12332                    if (!printed) {
12333                        if (needSep) pw.println();
12334                        needSep = true;
12335                        pw.println("  PID mappings:");
12336                        printed = true;
12337                        printedAnything = true;
12338                    }
12339                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12340                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12341                }
12342            }
12343        }
12344
12345        if (mForegroundProcesses.size() > 0) {
12346            synchronized (mPidsSelfLocked) {
12347                boolean printed = false;
12348                for (int i=0; i<mForegroundProcesses.size(); i++) {
12349                    ProcessRecord r = mPidsSelfLocked.get(
12350                            mForegroundProcesses.valueAt(i).pid);
12351                    if (dumpPackage != null && (r == null
12352                            || !r.pkgList.containsKey(dumpPackage))) {
12353                        continue;
12354                    }
12355                    if (!printed) {
12356                        if (needSep) pw.println();
12357                        needSep = true;
12358                        pw.println("  Foreground Processes:");
12359                        printed = true;
12360                        printedAnything = true;
12361                    }
12362                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12363                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12364                }
12365            }
12366        }
12367
12368        if (mPersistentStartingProcesses.size() > 0) {
12369            if (needSep) pw.println();
12370            needSep = true;
12371            printedAnything = true;
12372            pw.println("  Persisent processes that are starting:");
12373            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12374                    "Starting Norm", "Restarting PERS", dumpPackage);
12375        }
12376
12377        if (mRemovedProcesses.size() > 0) {
12378            if (needSep) pw.println();
12379            needSep = true;
12380            printedAnything = true;
12381            pw.println("  Processes that are being removed:");
12382            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12383                    "Removed Norm", "Removed PERS", dumpPackage);
12384        }
12385
12386        if (mProcessesOnHold.size() > 0) {
12387            if (needSep) pw.println();
12388            needSep = true;
12389            printedAnything = true;
12390            pw.println("  Processes that are on old until the system is ready:");
12391            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12392                    "OnHold Norm", "OnHold PERS", dumpPackage);
12393        }
12394
12395        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12396
12397        if (mProcessCrashTimes.getMap().size() > 0) {
12398            boolean printed = false;
12399            long now = SystemClock.uptimeMillis();
12400            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12401            final int NP = pmap.size();
12402            for (int ip=0; ip<NP; ip++) {
12403                String pname = pmap.keyAt(ip);
12404                SparseArray<Long> uids = pmap.valueAt(ip);
12405                final int N = uids.size();
12406                for (int i=0; i<N; i++) {
12407                    int puid = uids.keyAt(i);
12408                    ProcessRecord r = mProcessNames.get(pname, puid);
12409                    if (dumpPackage != null && (r == null
12410                            || !r.pkgList.containsKey(dumpPackage))) {
12411                        continue;
12412                    }
12413                    if (!printed) {
12414                        if (needSep) pw.println();
12415                        needSep = true;
12416                        pw.println("  Time since processes crashed:");
12417                        printed = true;
12418                        printedAnything = true;
12419                    }
12420                    pw.print("    Process "); pw.print(pname);
12421                            pw.print(" uid "); pw.print(puid);
12422                            pw.print(": last crashed ");
12423                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12424                            pw.println(" ago");
12425                }
12426            }
12427        }
12428
12429        if (mBadProcesses.getMap().size() > 0) {
12430            boolean printed = false;
12431            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12432            final int NP = pmap.size();
12433            for (int ip=0; ip<NP; ip++) {
12434                String pname = pmap.keyAt(ip);
12435                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12436                final int N = uids.size();
12437                for (int i=0; i<N; i++) {
12438                    int puid = uids.keyAt(i);
12439                    ProcessRecord r = mProcessNames.get(pname, puid);
12440                    if (dumpPackage != null && (r == null
12441                            || !r.pkgList.containsKey(dumpPackage))) {
12442                        continue;
12443                    }
12444                    if (!printed) {
12445                        if (needSep) pw.println();
12446                        needSep = true;
12447                        pw.println("  Bad processes:");
12448                        printedAnything = true;
12449                    }
12450                    BadProcessInfo info = uids.valueAt(i);
12451                    pw.print("    Bad process "); pw.print(pname);
12452                            pw.print(" uid "); pw.print(puid);
12453                            pw.print(": crashed at time "); pw.println(info.time);
12454                    if (info.shortMsg != null) {
12455                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12456                    }
12457                    if (info.longMsg != null) {
12458                        pw.print("      Long msg: "); pw.println(info.longMsg);
12459                    }
12460                    if (info.stack != null) {
12461                        pw.println("      Stack:");
12462                        int lastPos = 0;
12463                        for (int pos=0; pos<info.stack.length(); pos++) {
12464                            if (info.stack.charAt(pos) == '\n') {
12465                                pw.print("        ");
12466                                pw.write(info.stack, lastPos, pos-lastPos);
12467                                pw.println();
12468                                lastPos = pos+1;
12469                            }
12470                        }
12471                        if (lastPos < info.stack.length()) {
12472                            pw.print("        ");
12473                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12474                            pw.println();
12475                        }
12476                    }
12477                }
12478            }
12479        }
12480
12481        if (dumpPackage == null) {
12482            pw.println();
12483            needSep = false;
12484            pw.println("  mStartedUsers:");
12485            for (int i=0; i<mStartedUsers.size(); i++) {
12486                UserStartedState uss = mStartedUsers.valueAt(i);
12487                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12488                        pw.print(": "); uss.dump("", pw);
12489            }
12490            pw.print("  mStartedUserArray: [");
12491            for (int i=0; i<mStartedUserArray.length; i++) {
12492                if (i > 0) pw.print(", ");
12493                pw.print(mStartedUserArray[i]);
12494            }
12495            pw.println("]");
12496            pw.print("  mUserLru: [");
12497            for (int i=0; i<mUserLru.size(); i++) {
12498                if (i > 0) pw.print(", ");
12499                pw.print(mUserLru.get(i));
12500            }
12501            pw.println("]");
12502            if (dumpAll) {
12503                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12504            }
12505            synchronized (mUserProfileGroupIdsSelfLocked) {
12506                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12507                    pw.println("  mUserProfileGroupIds:");
12508                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12509                        pw.print("    User #");
12510                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12511                        pw.print(" -> profile #");
12512                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12513                    }
12514                }
12515            }
12516        }
12517        if (mHomeProcess != null && (dumpPackage == null
12518                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12519            if (needSep) {
12520                pw.println();
12521                needSep = false;
12522            }
12523            pw.println("  mHomeProcess: " + mHomeProcess);
12524        }
12525        if (mPreviousProcess != null && (dumpPackage == null
12526                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12527            if (needSep) {
12528                pw.println();
12529                needSep = false;
12530            }
12531            pw.println("  mPreviousProcess: " + mPreviousProcess);
12532        }
12533        if (dumpAll) {
12534            StringBuilder sb = new StringBuilder(128);
12535            sb.append("  mPreviousProcessVisibleTime: ");
12536            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12537            pw.println(sb);
12538        }
12539        if (mHeavyWeightProcess != null && (dumpPackage == null
12540                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12541            if (needSep) {
12542                pw.println();
12543                needSep = false;
12544            }
12545            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12546        }
12547        if (dumpPackage == null) {
12548            pw.println("  mConfiguration: " + mConfiguration);
12549        }
12550        if (dumpAll) {
12551            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12552            if (mCompatModePackages.getPackages().size() > 0) {
12553                boolean printed = false;
12554                for (Map.Entry<String, Integer> entry
12555                        : mCompatModePackages.getPackages().entrySet()) {
12556                    String pkg = entry.getKey();
12557                    int mode = entry.getValue();
12558                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12559                        continue;
12560                    }
12561                    if (!printed) {
12562                        pw.println("  mScreenCompatPackages:");
12563                        printed = true;
12564                    }
12565                    pw.print("    "); pw.print(pkg); pw.print(": ");
12566                            pw.print(mode); pw.println();
12567                }
12568            }
12569        }
12570        if (dumpPackage == null) {
12571            if (mSleeping || mWentToSleep || mLockScreenShown) {
12572                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12573                        + " mLockScreenShown " + mLockScreenShown);
12574            }
12575            if (mShuttingDown || mRunningVoice) {
12576                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12577            }
12578        }
12579        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12580                || mOrigWaitForDebugger) {
12581            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12582                    || dumpPackage.equals(mOrigDebugApp)) {
12583                if (needSep) {
12584                    pw.println();
12585                    needSep = false;
12586                }
12587                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12588                        + " mDebugTransient=" + mDebugTransient
12589                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12590            }
12591        }
12592        if (mOpenGlTraceApp != null) {
12593            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12594                if (needSep) {
12595                    pw.println();
12596                    needSep = false;
12597                }
12598                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12599            }
12600        }
12601        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12602                || mProfileFd != null) {
12603            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12604                if (needSep) {
12605                    pw.println();
12606                    needSep = false;
12607                }
12608                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12609                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12610                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12611                        + mAutoStopProfiler);
12612                pw.println("  mProfileType=" + mProfileType);
12613            }
12614        }
12615        if (dumpPackage == null) {
12616            if (mAlwaysFinishActivities || mController != null) {
12617                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12618                        + " mController=" + mController);
12619            }
12620            if (dumpAll) {
12621                pw.println("  Total persistent processes: " + numPers);
12622                pw.println("  mProcessesReady=" + mProcessesReady
12623                        + " mSystemReady=" + mSystemReady);
12624                pw.println("  mBooting=" + mBooting
12625                        + " mBooted=" + mBooted
12626                        + " mFactoryTest=" + mFactoryTest);
12627                pw.print("  mLastPowerCheckRealtime=");
12628                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12629                        pw.println("");
12630                pw.print("  mLastPowerCheckUptime=");
12631                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12632                        pw.println("");
12633                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12634                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12635                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12636                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12637                        + " (" + mLruProcesses.size() + " total)"
12638                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12639                        + " mNumServiceProcs=" + mNumServiceProcs
12640                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12641                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12642                        + " mLastMemoryLevel" + mLastMemoryLevel
12643                        + " mLastNumProcesses" + mLastNumProcesses);
12644                long now = SystemClock.uptimeMillis();
12645                pw.print("  mLastIdleTime=");
12646                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12647                        pw.print(" mLowRamSinceLastIdle=");
12648                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12649                        pw.println();
12650            }
12651        }
12652
12653        if (!printedAnything) {
12654            pw.println("  (nothing)");
12655        }
12656    }
12657
12658    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12659            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12660        if (mProcessesToGc.size() > 0) {
12661            boolean printed = false;
12662            long now = SystemClock.uptimeMillis();
12663            for (int i=0; i<mProcessesToGc.size(); i++) {
12664                ProcessRecord proc = mProcessesToGc.get(i);
12665                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12666                    continue;
12667                }
12668                if (!printed) {
12669                    if (needSep) pw.println();
12670                    needSep = true;
12671                    pw.println("  Processes that are waiting to GC:");
12672                    printed = true;
12673                }
12674                pw.print("    Process "); pw.println(proc);
12675                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12676                        pw.print(", last gced=");
12677                        pw.print(now-proc.lastRequestedGc);
12678                        pw.print(" ms ago, last lowMem=");
12679                        pw.print(now-proc.lastLowMemory);
12680                        pw.println(" ms ago");
12681
12682            }
12683        }
12684        return needSep;
12685    }
12686
12687    void printOomLevel(PrintWriter pw, String name, int adj) {
12688        pw.print("    ");
12689        if (adj >= 0) {
12690            pw.print(' ');
12691            if (adj < 10) pw.print(' ');
12692        } else {
12693            if (adj > -10) pw.print(' ');
12694        }
12695        pw.print(adj);
12696        pw.print(": ");
12697        pw.print(name);
12698        pw.print(" (");
12699        pw.print(mProcessList.getMemLevel(adj)/1024);
12700        pw.println(" kB)");
12701    }
12702
12703    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12704            int opti, boolean dumpAll) {
12705        boolean needSep = false;
12706
12707        if (mLruProcesses.size() > 0) {
12708            if (needSep) pw.println();
12709            needSep = true;
12710            pw.println("  OOM levels:");
12711            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12712            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12713            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12714            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12715            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12716            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12717            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12718            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12719            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12720            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12721            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12722            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12723            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12724
12725            if (needSep) pw.println();
12726            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12727                    pw.print(" total, non-act at ");
12728                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12729                    pw.print(", non-svc at ");
12730                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12731                    pw.println("):");
12732            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12733            needSep = true;
12734        }
12735
12736        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12737
12738        pw.println();
12739        pw.println("  mHomeProcess: " + mHomeProcess);
12740        pw.println("  mPreviousProcess: " + mPreviousProcess);
12741        if (mHeavyWeightProcess != null) {
12742            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12743        }
12744
12745        return true;
12746    }
12747
12748    /**
12749     * There are three ways to call this:
12750     *  - no provider specified: dump all the providers
12751     *  - a flattened component name that matched an existing provider was specified as the
12752     *    first arg: dump that one provider
12753     *  - the first arg isn't the flattened component name of an existing provider:
12754     *    dump all providers whose component contains the first arg as a substring
12755     */
12756    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12757            int opti, boolean dumpAll) {
12758        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12759    }
12760
12761    static class ItemMatcher {
12762        ArrayList<ComponentName> components;
12763        ArrayList<String> strings;
12764        ArrayList<Integer> objects;
12765        boolean all;
12766
12767        ItemMatcher() {
12768            all = true;
12769        }
12770
12771        void build(String name) {
12772            ComponentName componentName = ComponentName.unflattenFromString(name);
12773            if (componentName != null) {
12774                if (components == null) {
12775                    components = new ArrayList<ComponentName>();
12776                }
12777                components.add(componentName);
12778                all = false;
12779            } else {
12780                int objectId = 0;
12781                // Not a '/' separated full component name; maybe an object ID?
12782                try {
12783                    objectId = Integer.parseInt(name, 16);
12784                    if (objects == null) {
12785                        objects = new ArrayList<Integer>();
12786                    }
12787                    objects.add(objectId);
12788                    all = false;
12789                } catch (RuntimeException e) {
12790                    // Not an integer; just do string match.
12791                    if (strings == null) {
12792                        strings = new ArrayList<String>();
12793                    }
12794                    strings.add(name);
12795                    all = false;
12796                }
12797            }
12798        }
12799
12800        int build(String[] args, int opti) {
12801            for (; opti<args.length; opti++) {
12802                String name = args[opti];
12803                if ("--".equals(name)) {
12804                    return opti+1;
12805                }
12806                build(name);
12807            }
12808            return opti;
12809        }
12810
12811        boolean match(Object object, ComponentName comp) {
12812            if (all) {
12813                return true;
12814            }
12815            if (components != null) {
12816                for (int i=0; i<components.size(); i++) {
12817                    if (components.get(i).equals(comp)) {
12818                        return true;
12819                    }
12820                }
12821            }
12822            if (objects != null) {
12823                for (int i=0; i<objects.size(); i++) {
12824                    if (System.identityHashCode(object) == objects.get(i)) {
12825                        return true;
12826                    }
12827                }
12828            }
12829            if (strings != null) {
12830                String flat = comp.flattenToString();
12831                for (int i=0; i<strings.size(); i++) {
12832                    if (flat.contains(strings.get(i))) {
12833                        return true;
12834                    }
12835                }
12836            }
12837            return false;
12838        }
12839    }
12840
12841    /**
12842     * There are three things that cmd can be:
12843     *  - a flattened component name that matches an existing activity
12844     *  - the cmd arg isn't the flattened component name of an existing activity:
12845     *    dump all activity whose component contains the cmd as a substring
12846     *  - A hex number of the ActivityRecord object instance.
12847     */
12848    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12849            int opti, boolean dumpAll) {
12850        ArrayList<ActivityRecord> activities;
12851
12852        synchronized (this) {
12853            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12854        }
12855
12856        if (activities.size() <= 0) {
12857            return false;
12858        }
12859
12860        String[] newArgs = new String[args.length - opti];
12861        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12862
12863        TaskRecord lastTask = null;
12864        boolean needSep = false;
12865        for (int i=activities.size()-1; i>=0; i--) {
12866            ActivityRecord r = activities.get(i);
12867            if (needSep) {
12868                pw.println();
12869            }
12870            needSep = true;
12871            synchronized (this) {
12872                if (lastTask != r.task) {
12873                    lastTask = r.task;
12874                    pw.print("TASK "); pw.print(lastTask.affinity);
12875                            pw.print(" id="); pw.println(lastTask.taskId);
12876                    if (dumpAll) {
12877                        lastTask.dump(pw, "  ");
12878                    }
12879                }
12880            }
12881            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12882        }
12883        return true;
12884    }
12885
12886    /**
12887     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12888     * there is a thread associated with the activity.
12889     */
12890    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12891            final ActivityRecord r, String[] args, boolean dumpAll) {
12892        String innerPrefix = prefix + "  ";
12893        synchronized (this) {
12894            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12895                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12896                    pw.print(" pid=");
12897                    if (r.app != null) pw.println(r.app.pid);
12898                    else pw.println("(not running)");
12899            if (dumpAll) {
12900                r.dump(pw, innerPrefix);
12901            }
12902        }
12903        if (r.app != null && r.app.thread != null) {
12904            // flush anything that is already in the PrintWriter since the thread is going
12905            // to write to the file descriptor directly
12906            pw.flush();
12907            try {
12908                TransferPipe tp = new TransferPipe();
12909                try {
12910                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12911                            r.appToken, innerPrefix, args);
12912                    tp.go(fd);
12913                } finally {
12914                    tp.kill();
12915                }
12916            } catch (IOException e) {
12917                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12918            } catch (RemoteException e) {
12919                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12920            }
12921        }
12922    }
12923
12924    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12925            int opti, boolean dumpAll, String dumpPackage) {
12926        boolean needSep = false;
12927        boolean onlyHistory = false;
12928        boolean printedAnything = false;
12929
12930        if ("history".equals(dumpPackage)) {
12931            if (opti < args.length && "-s".equals(args[opti])) {
12932                dumpAll = false;
12933            }
12934            onlyHistory = true;
12935            dumpPackage = null;
12936        }
12937
12938        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12939        if (!onlyHistory && dumpAll) {
12940            if (mRegisteredReceivers.size() > 0) {
12941                boolean printed = false;
12942                Iterator it = mRegisteredReceivers.values().iterator();
12943                while (it.hasNext()) {
12944                    ReceiverList r = (ReceiverList)it.next();
12945                    if (dumpPackage != null && (r.app == null ||
12946                            !dumpPackage.equals(r.app.info.packageName))) {
12947                        continue;
12948                    }
12949                    if (!printed) {
12950                        pw.println("  Registered Receivers:");
12951                        needSep = true;
12952                        printed = true;
12953                        printedAnything = true;
12954                    }
12955                    pw.print("  * "); pw.println(r);
12956                    r.dump(pw, "    ");
12957                }
12958            }
12959
12960            if (mReceiverResolver.dump(pw, needSep ?
12961                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12962                    "    ", dumpPackage, false)) {
12963                needSep = true;
12964                printedAnything = true;
12965            }
12966        }
12967
12968        for (BroadcastQueue q : mBroadcastQueues) {
12969            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12970            printedAnything |= needSep;
12971        }
12972
12973        needSep = true;
12974
12975        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12976            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12977                if (needSep) {
12978                    pw.println();
12979                }
12980                needSep = true;
12981                printedAnything = true;
12982                pw.print("  Sticky broadcasts for user ");
12983                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12984                StringBuilder sb = new StringBuilder(128);
12985                for (Map.Entry<String, ArrayList<Intent>> ent
12986                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12987                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12988                    if (dumpAll) {
12989                        pw.println(":");
12990                        ArrayList<Intent> intents = ent.getValue();
12991                        final int N = intents.size();
12992                        for (int i=0; i<N; i++) {
12993                            sb.setLength(0);
12994                            sb.append("    Intent: ");
12995                            intents.get(i).toShortString(sb, false, true, false, false);
12996                            pw.println(sb.toString());
12997                            Bundle bundle = intents.get(i).getExtras();
12998                            if (bundle != null) {
12999                                pw.print("      ");
13000                                pw.println(bundle.toString());
13001                            }
13002                        }
13003                    } else {
13004                        pw.println("");
13005                    }
13006                }
13007            }
13008        }
13009
13010        if (!onlyHistory && dumpAll) {
13011            pw.println();
13012            for (BroadcastQueue queue : mBroadcastQueues) {
13013                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13014                        + queue.mBroadcastsScheduled);
13015            }
13016            pw.println("  mHandler:");
13017            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13018            needSep = true;
13019            printedAnything = true;
13020        }
13021
13022        if (!printedAnything) {
13023            pw.println("  (nothing)");
13024        }
13025    }
13026
13027    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13028            int opti, boolean dumpAll, String dumpPackage) {
13029        boolean needSep;
13030        boolean printedAnything = false;
13031
13032        ItemMatcher matcher = new ItemMatcher();
13033        matcher.build(args, opti);
13034
13035        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13036
13037        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13038        printedAnything |= needSep;
13039
13040        if (mLaunchingProviders.size() > 0) {
13041            boolean printed = false;
13042            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13043                ContentProviderRecord r = mLaunchingProviders.get(i);
13044                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13045                    continue;
13046                }
13047                if (!printed) {
13048                    if (needSep) pw.println();
13049                    needSep = true;
13050                    pw.println("  Launching content providers:");
13051                    printed = true;
13052                    printedAnything = true;
13053                }
13054                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13055                        pw.println(r);
13056            }
13057        }
13058
13059        if (mGrantedUriPermissions.size() > 0) {
13060            boolean printed = false;
13061            int dumpUid = -2;
13062            if (dumpPackage != null) {
13063                try {
13064                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13065                } catch (NameNotFoundException e) {
13066                    dumpUid = -1;
13067                }
13068            }
13069            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13070                int uid = mGrantedUriPermissions.keyAt(i);
13071                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13072                    continue;
13073                }
13074                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13075                if (!printed) {
13076                    if (needSep) pw.println();
13077                    needSep = true;
13078                    pw.println("  Granted Uri Permissions:");
13079                    printed = true;
13080                    printedAnything = true;
13081                }
13082                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13083                for (UriPermission perm : perms.values()) {
13084                    pw.print("    "); pw.println(perm);
13085                    if (dumpAll) {
13086                        perm.dump(pw, "      ");
13087                    }
13088                }
13089            }
13090        }
13091
13092        if (!printedAnything) {
13093            pw.println("  (nothing)");
13094        }
13095    }
13096
13097    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13098            int opti, boolean dumpAll, String dumpPackage) {
13099        boolean printed = false;
13100
13101        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13102
13103        if (mIntentSenderRecords.size() > 0) {
13104            Iterator<WeakReference<PendingIntentRecord>> it
13105                    = mIntentSenderRecords.values().iterator();
13106            while (it.hasNext()) {
13107                WeakReference<PendingIntentRecord> ref = it.next();
13108                PendingIntentRecord rec = ref != null ? ref.get(): null;
13109                if (dumpPackage != null && (rec == null
13110                        || !dumpPackage.equals(rec.key.packageName))) {
13111                    continue;
13112                }
13113                printed = true;
13114                if (rec != null) {
13115                    pw.print("  * "); pw.println(rec);
13116                    if (dumpAll) {
13117                        rec.dump(pw, "    ");
13118                    }
13119                } else {
13120                    pw.print("  * "); pw.println(ref);
13121                }
13122            }
13123        }
13124
13125        if (!printed) {
13126            pw.println("  (nothing)");
13127        }
13128    }
13129
13130    private static final int dumpProcessList(PrintWriter pw,
13131            ActivityManagerService service, List list,
13132            String prefix, String normalLabel, String persistentLabel,
13133            String dumpPackage) {
13134        int numPers = 0;
13135        final int N = list.size()-1;
13136        for (int i=N; i>=0; i--) {
13137            ProcessRecord r = (ProcessRecord)list.get(i);
13138            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13139                continue;
13140            }
13141            pw.println(String.format("%s%s #%2d: %s",
13142                    prefix, (r.persistent ? persistentLabel : normalLabel),
13143                    i, r.toString()));
13144            if (r.persistent) {
13145                numPers++;
13146            }
13147        }
13148        return numPers;
13149    }
13150
13151    private static final boolean dumpProcessOomList(PrintWriter pw,
13152            ActivityManagerService service, List<ProcessRecord> origList,
13153            String prefix, String normalLabel, String persistentLabel,
13154            boolean inclDetails, String dumpPackage) {
13155
13156        ArrayList<Pair<ProcessRecord, Integer>> list
13157                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13158        for (int i=0; i<origList.size(); i++) {
13159            ProcessRecord r = origList.get(i);
13160            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13161                continue;
13162            }
13163            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13164        }
13165
13166        if (list.size() <= 0) {
13167            return false;
13168        }
13169
13170        Comparator<Pair<ProcessRecord, Integer>> comparator
13171                = new Comparator<Pair<ProcessRecord, Integer>>() {
13172            @Override
13173            public int compare(Pair<ProcessRecord, Integer> object1,
13174                    Pair<ProcessRecord, Integer> object2) {
13175                if (object1.first.setAdj != object2.first.setAdj) {
13176                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13177                }
13178                if (object1.second.intValue() != object2.second.intValue()) {
13179                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13180                }
13181                return 0;
13182            }
13183        };
13184
13185        Collections.sort(list, comparator);
13186
13187        final long curRealtime = SystemClock.elapsedRealtime();
13188        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13189        final long curUptime = SystemClock.uptimeMillis();
13190        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13191
13192        for (int i=list.size()-1; i>=0; i--) {
13193            ProcessRecord r = list.get(i).first;
13194            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13195            char schedGroup;
13196            switch (r.setSchedGroup) {
13197                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13198                    schedGroup = 'B';
13199                    break;
13200                case Process.THREAD_GROUP_DEFAULT:
13201                    schedGroup = 'F';
13202                    break;
13203                default:
13204                    schedGroup = '?';
13205                    break;
13206            }
13207            char foreground;
13208            if (r.foregroundActivities) {
13209                foreground = 'A';
13210            } else if (r.foregroundServices) {
13211                foreground = 'S';
13212            } else {
13213                foreground = ' ';
13214            }
13215            String procState = ProcessList.makeProcStateString(r.curProcState);
13216            pw.print(prefix);
13217            pw.print(r.persistent ? persistentLabel : normalLabel);
13218            pw.print(" #");
13219            int num = (origList.size()-1)-list.get(i).second;
13220            if (num < 10) pw.print(' ');
13221            pw.print(num);
13222            pw.print(": ");
13223            pw.print(oomAdj);
13224            pw.print(' ');
13225            pw.print(schedGroup);
13226            pw.print('/');
13227            pw.print(foreground);
13228            pw.print('/');
13229            pw.print(procState);
13230            pw.print(" trm:");
13231            if (r.trimMemoryLevel < 10) pw.print(' ');
13232            pw.print(r.trimMemoryLevel);
13233            pw.print(' ');
13234            pw.print(r.toShortString());
13235            pw.print(" (");
13236            pw.print(r.adjType);
13237            pw.println(')');
13238            if (r.adjSource != null || r.adjTarget != null) {
13239                pw.print(prefix);
13240                pw.print("    ");
13241                if (r.adjTarget instanceof ComponentName) {
13242                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13243                } else if (r.adjTarget != null) {
13244                    pw.print(r.adjTarget.toString());
13245                } else {
13246                    pw.print("{null}");
13247                }
13248                pw.print("<=");
13249                if (r.adjSource instanceof ProcessRecord) {
13250                    pw.print("Proc{");
13251                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13252                    pw.println("}");
13253                } else if (r.adjSource != null) {
13254                    pw.println(r.adjSource.toString());
13255                } else {
13256                    pw.println("{null}");
13257                }
13258            }
13259            if (inclDetails) {
13260                pw.print(prefix);
13261                pw.print("    ");
13262                pw.print("oom: max="); pw.print(r.maxAdj);
13263                pw.print(" curRaw="); pw.print(r.curRawAdj);
13264                pw.print(" setRaw="); pw.print(r.setRawAdj);
13265                pw.print(" cur="); pw.print(r.curAdj);
13266                pw.print(" set="); pw.println(r.setAdj);
13267                pw.print(prefix);
13268                pw.print("    ");
13269                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13270                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13271                pw.print(" lastPss="); pw.print(r.lastPss);
13272                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13273                pw.print(prefix);
13274                pw.print("    ");
13275                pw.print("cached="); pw.print(r.cached);
13276                pw.print(" empty="); pw.print(r.empty);
13277                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13278
13279                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13280                    if (r.lastWakeTime != 0) {
13281                        long wtime;
13282                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13283                        synchronized (stats) {
13284                            wtime = stats.getProcessWakeTime(r.info.uid,
13285                                    r.pid, curRealtime);
13286                        }
13287                        long timeUsed = wtime - r.lastWakeTime;
13288                        pw.print(prefix);
13289                        pw.print("    ");
13290                        pw.print("keep awake over ");
13291                        TimeUtils.formatDuration(realtimeSince, pw);
13292                        pw.print(" used ");
13293                        TimeUtils.formatDuration(timeUsed, pw);
13294                        pw.print(" (");
13295                        pw.print((timeUsed*100)/realtimeSince);
13296                        pw.println("%)");
13297                    }
13298                    if (r.lastCpuTime != 0) {
13299                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13300                        pw.print(prefix);
13301                        pw.print("    ");
13302                        pw.print("run cpu over ");
13303                        TimeUtils.formatDuration(uptimeSince, pw);
13304                        pw.print(" used ");
13305                        TimeUtils.formatDuration(timeUsed, pw);
13306                        pw.print(" (");
13307                        pw.print((timeUsed*100)/uptimeSince);
13308                        pw.println("%)");
13309                    }
13310                }
13311            }
13312        }
13313        return true;
13314    }
13315
13316    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13317        ArrayList<ProcessRecord> procs;
13318        synchronized (this) {
13319            if (args != null && args.length > start
13320                    && args[start].charAt(0) != '-') {
13321                procs = new ArrayList<ProcessRecord>();
13322                int pid = -1;
13323                try {
13324                    pid = Integer.parseInt(args[start]);
13325                } catch (NumberFormatException e) {
13326                }
13327                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13328                    ProcessRecord proc = mLruProcesses.get(i);
13329                    if (proc.pid == pid) {
13330                        procs.add(proc);
13331                    } else if (proc.processName.equals(args[start])) {
13332                        procs.add(proc);
13333                    }
13334                }
13335                if (procs.size() <= 0) {
13336                    return null;
13337                }
13338            } else {
13339                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13340            }
13341        }
13342        return procs;
13343    }
13344
13345    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13346            PrintWriter pw, String[] args) {
13347        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13348        if (procs == null) {
13349            pw.println("No process found for: " + args[0]);
13350            return;
13351        }
13352
13353        long uptime = SystemClock.uptimeMillis();
13354        long realtime = SystemClock.elapsedRealtime();
13355        pw.println("Applications Graphics Acceleration Info:");
13356        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13357
13358        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13359            ProcessRecord r = procs.get(i);
13360            if (r.thread != null) {
13361                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13362                pw.flush();
13363                try {
13364                    TransferPipe tp = new TransferPipe();
13365                    try {
13366                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13367                        tp.go(fd);
13368                    } finally {
13369                        tp.kill();
13370                    }
13371                } catch (IOException e) {
13372                    pw.println("Failure while dumping the app: " + r);
13373                    pw.flush();
13374                } catch (RemoteException e) {
13375                    pw.println("Got a RemoteException while dumping the app " + r);
13376                    pw.flush();
13377                }
13378            }
13379        }
13380    }
13381
13382    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13383        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13384        if (procs == null) {
13385            pw.println("No process found for: " + args[0]);
13386            return;
13387        }
13388
13389        pw.println("Applications Database Info:");
13390
13391        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13392            ProcessRecord r = procs.get(i);
13393            if (r.thread != null) {
13394                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13395                pw.flush();
13396                try {
13397                    TransferPipe tp = new TransferPipe();
13398                    try {
13399                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13400                        tp.go(fd);
13401                    } finally {
13402                        tp.kill();
13403                    }
13404                } catch (IOException e) {
13405                    pw.println("Failure while dumping the app: " + r);
13406                    pw.flush();
13407                } catch (RemoteException e) {
13408                    pw.println("Got a RemoteException while dumping the app " + r);
13409                    pw.flush();
13410                }
13411            }
13412        }
13413    }
13414
13415    final static class MemItem {
13416        final boolean isProc;
13417        final String label;
13418        final String shortLabel;
13419        final long pss;
13420        final int id;
13421        final boolean hasActivities;
13422        ArrayList<MemItem> subitems;
13423
13424        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13425                boolean _hasActivities) {
13426            isProc = true;
13427            label = _label;
13428            shortLabel = _shortLabel;
13429            pss = _pss;
13430            id = _id;
13431            hasActivities = _hasActivities;
13432        }
13433
13434        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13435            isProc = false;
13436            label = _label;
13437            shortLabel = _shortLabel;
13438            pss = _pss;
13439            id = _id;
13440            hasActivities = false;
13441        }
13442    }
13443
13444    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13445            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13446        if (sort && !isCompact) {
13447            Collections.sort(items, new Comparator<MemItem>() {
13448                @Override
13449                public int compare(MemItem lhs, MemItem rhs) {
13450                    if (lhs.pss < rhs.pss) {
13451                        return 1;
13452                    } else if (lhs.pss > rhs.pss) {
13453                        return -1;
13454                    }
13455                    return 0;
13456                }
13457            });
13458        }
13459
13460        for (int i=0; i<items.size(); i++) {
13461            MemItem mi = items.get(i);
13462            if (!isCompact) {
13463                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13464            } else if (mi.isProc) {
13465                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13466                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13467                pw.println(mi.hasActivities ? ",a" : ",e");
13468            } else {
13469                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13470                pw.println(mi.pss);
13471            }
13472            if (mi.subitems != null) {
13473                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13474                        true, isCompact);
13475            }
13476        }
13477    }
13478
13479    // These are in KB.
13480    static final long[] DUMP_MEM_BUCKETS = new long[] {
13481        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13482        120*1024, 160*1024, 200*1024,
13483        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13484        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13485    };
13486
13487    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13488            boolean stackLike) {
13489        int start = label.lastIndexOf('.');
13490        if (start >= 0) start++;
13491        else start = 0;
13492        int end = label.length();
13493        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13494            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13495                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13496                out.append(bucket);
13497                out.append(stackLike ? "MB." : "MB ");
13498                out.append(label, start, end);
13499                return;
13500            }
13501        }
13502        out.append(memKB/1024);
13503        out.append(stackLike ? "MB." : "MB ");
13504        out.append(label, start, end);
13505    }
13506
13507    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13508            ProcessList.NATIVE_ADJ,
13509            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13510            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13511            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13512            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13513            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13514    };
13515    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13516            "Native",
13517            "System", "Persistent", "Foreground",
13518            "Visible", "Perceptible",
13519            "Heavy Weight", "Backup",
13520            "A Services", "Home",
13521            "Previous", "B Services", "Cached"
13522    };
13523    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13524            "native",
13525            "sys", "pers", "fore",
13526            "vis", "percept",
13527            "heavy", "backup",
13528            "servicea", "home",
13529            "prev", "serviceb", "cached"
13530    };
13531
13532    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13533            long realtime, boolean isCheckinRequest, boolean isCompact) {
13534        if (isCheckinRequest || isCompact) {
13535            // short checkin version
13536            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13537        } else {
13538            pw.println("Applications Memory Usage (kB):");
13539            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13540        }
13541    }
13542
13543    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13544            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13545        boolean dumpDetails = false;
13546        boolean dumpFullDetails = false;
13547        boolean dumpDalvik = false;
13548        boolean oomOnly = false;
13549        boolean isCompact = false;
13550        boolean localOnly = false;
13551
13552        int opti = 0;
13553        while (opti < args.length) {
13554            String opt = args[opti];
13555            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13556                break;
13557            }
13558            opti++;
13559            if ("-a".equals(opt)) {
13560                dumpDetails = true;
13561                dumpFullDetails = true;
13562                dumpDalvik = true;
13563            } else if ("-d".equals(opt)) {
13564                dumpDalvik = true;
13565            } else if ("-c".equals(opt)) {
13566                isCompact = true;
13567            } else if ("--oom".equals(opt)) {
13568                oomOnly = true;
13569            } else if ("--local".equals(opt)) {
13570                localOnly = true;
13571            } else if ("-h".equals(opt)) {
13572                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13573                pw.println("  -a: include all available information for each process.");
13574                pw.println("  -d: include dalvik details when dumping process details.");
13575                pw.println("  -c: dump in a compact machine-parseable representation.");
13576                pw.println("  --oom: only show processes organized by oom adj.");
13577                pw.println("  --local: only collect details locally, don't call process.");
13578                pw.println("If [process] is specified it can be the name or ");
13579                pw.println("pid of a specific process to dump.");
13580                return;
13581            } else {
13582                pw.println("Unknown argument: " + opt + "; use -h for help");
13583            }
13584        }
13585
13586        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13587        long uptime = SystemClock.uptimeMillis();
13588        long realtime = SystemClock.elapsedRealtime();
13589        final long[] tmpLong = new long[1];
13590
13591        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13592        if (procs == null) {
13593            // No Java processes.  Maybe they want to print a native process.
13594            if (args != null && args.length > opti
13595                    && args[opti].charAt(0) != '-') {
13596                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13597                        = new ArrayList<ProcessCpuTracker.Stats>();
13598                updateCpuStatsNow();
13599                int findPid = -1;
13600                try {
13601                    findPid = Integer.parseInt(args[opti]);
13602                } catch (NumberFormatException e) {
13603                }
13604                synchronized (mProcessCpuThread) {
13605                    final int N = mProcessCpuTracker.countStats();
13606                    for (int i=0; i<N; i++) {
13607                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13608                        if (st.pid == findPid || (st.baseName != null
13609                                && st.baseName.equals(args[opti]))) {
13610                            nativeProcs.add(st);
13611                        }
13612                    }
13613                }
13614                if (nativeProcs.size() > 0) {
13615                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13616                            isCompact);
13617                    Debug.MemoryInfo mi = null;
13618                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13619                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13620                        final int pid = r.pid;
13621                        if (!isCheckinRequest && dumpDetails) {
13622                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13623                        }
13624                        if (mi == null) {
13625                            mi = new Debug.MemoryInfo();
13626                        }
13627                        if (dumpDetails || (!brief && !oomOnly)) {
13628                            Debug.getMemoryInfo(pid, mi);
13629                        } else {
13630                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13631                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13632                        }
13633                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13634                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13635                        if (isCheckinRequest) {
13636                            pw.println();
13637                        }
13638                    }
13639                    return;
13640                }
13641            }
13642            pw.println("No process found for: " + args[opti]);
13643            return;
13644        }
13645
13646        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13647            dumpDetails = true;
13648        }
13649
13650        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13651
13652        String[] innerArgs = new String[args.length-opti];
13653        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13654
13655        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13656        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13657        long nativePss=0, dalvikPss=0, otherPss=0;
13658        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13659
13660        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13661        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13662                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13663
13664        long totalPss = 0;
13665        long cachedPss = 0;
13666
13667        Debug.MemoryInfo mi = null;
13668        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13669            final ProcessRecord r = procs.get(i);
13670            final IApplicationThread thread;
13671            final int pid;
13672            final int oomAdj;
13673            final boolean hasActivities;
13674            synchronized (this) {
13675                thread = r.thread;
13676                pid = r.pid;
13677                oomAdj = r.getSetAdjWithServices();
13678                hasActivities = r.activities.size() > 0;
13679            }
13680            if (thread != null) {
13681                if (!isCheckinRequest && dumpDetails) {
13682                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13683                }
13684                if (mi == null) {
13685                    mi = new Debug.MemoryInfo();
13686                }
13687                if (dumpDetails || (!brief && !oomOnly)) {
13688                    Debug.getMemoryInfo(pid, mi);
13689                } else {
13690                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13691                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13692                }
13693                if (dumpDetails) {
13694                    if (localOnly) {
13695                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13696                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13697                        if (isCheckinRequest) {
13698                            pw.println();
13699                        }
13700                    } else {
13701                        try {
13702                            pw.flush();
13703                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13704                                    dumpDalvik, innerArgs);
13705                        } catch (RemoteException e) {
13706                            if (!isCheckinRequest) {
13707                                pw.println("Got RemoteException!");
13708                                pw.flush();
13709                            }
13710                        }
13711                    }
13712                }
13713
13714                final long myTotalPss = mi.getTotalPss();
13715                final long myTotalUss = mi.getTotalUss();
13716
13717                synchronized (this) {
13718                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13719                        // Record this for posterity if the process has been stable.
13720                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13721                    }
13722                }
13723
13724                if (!isCheckinRequest && mi != null) {
13725                    totalPss += myTotalPss;
13726                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13727                            (hasActivities ? " / activities)" : ")"),
13728                            r.processName, myTotalPss, pid, hasActivities);
13729                    procMems.add(pssItem);
13730                    procMemsMap.put(pid, pssItem);
13731
13732                    nativePss += mi.nativePss;
13733                    dalvikPss += mi.dalvikPss;
13734                    otherPss += mi.otherPss;
13735                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13736                        long mem = mi.getOtherPss(j);
13737                        miscPss[j] += mem;
13738                        otherPss -= mem;
13739                    }
13740
13741                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13742                        cachedPss += myTotalPss;
13743                    }
13744
13745                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13746                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13747                                || oomIndex == (oomPss.length-1)) {
13748                            oomPss[oomIndex] += myTotalPss;
13749                            if (oomProcs[oomIndex] == null) {
13750                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13751                            }
13752                            oomProcs[oomIndex].add(pssItem);
13753                            break;
13754                        }
13755                    }
13756                }
13757            }
13758        }
13759
13760        long nativeProcTotalPss = 0;
13761
13762        if (!isCheckinRequest && procs.size() > 1) {
13763            // If we are showing aggregations, also look for native processes to
13764            // include so that our aggregations are more accurate.
13765            updateCpuStatsNow();
13766            synchronized (mProcessCpuThread) {
13767                final int N = mProcessCpuTracker.countStats();
13768                for (int i=0; i<N; i++) {
13769                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13770                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13771                        if (mi == null) {
13772                            mi = new Debug.MemoryInfo();
13773                        }
13774                        if (!brief && !oomOnly) {
13775                            Debug.getMemoryInfo(st.pid, mi);
13776                        } else {
13777                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13778                            mi.nativePrivateDirty = (int)tmpLong[0];
13779                        }
13780
13781                        final long myTotalPss = mi.getTotalPss();
13782                        totalPss += myTotalPss;
13783                        nativeProcTotalPss += myTotalPss;
13784
13785                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13786                                st.name, myTotalPss, st.pid, false);
13787                        procMems.add(pssItem);
13788
13789                        nativePss += mi.nativePss;
13790                        dalvikPss += mi.dalvikPss;
13791                        otherPss += mi.otherPss;
13792                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13793                            long mem = mi.getOtherPss(j);
13794                            miscPss[j] += mem;
13795                            otherPss -= mem;
13796                        }
13797                        oomPss[0] += myTotalPss;
13798                        if (oomProcs[0] == null) {
13799                            oomProcs[0] = new ArrayList<MemItem>();
13800                        }
13801                        oomProcs[0].add(pssItem);
13802                    }
13803                }
13804            }
13805
13806            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13807
13808            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13809            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13810            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13811            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13812                String label = Debug.MemoryInfo.getOtherLabel(j);
13813                catMems.add(new MemItem(label, label, miscPss[j], j));
13814            }
13815
13816            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13817            for (int j=0; j<oomPss.length; j++) {
13818                if (oomPss[j] != 0) {
13819                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13820                            : DUMP_MEM_OOM_LABEL[j];
13821                    MemItem item = new MemItem(label, label, oomPss[j],
13822                            DUMP_MEM_OOM_ADJ[j]);
13823                    item.subitems = oomProcs[j];
13824                    oomMems.add(item);
13825                }
13826            }
13827
13828            if (!brief && !oomOnly && !isCompact) {
13829                pw.println();
13830                pw.println("Total PSS by process:");
13831                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13832                pw.println();
13833            }
13834            if (!isCompact) {
13835                pw.println("Total PSS by OOM adjustment:");
13836            }
13837            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13838            if (!brief && !oomOnly) {
13839                PrintWriter out = categoryPw != null ? categoryPw : pw;
13840                if (!isCompact) {
13841                    out.println();
13842                    out.println("Total PSS by category:");
13843                }
13844                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13845            }
13846            if (!isCompact) {
13847                pw.println();
13848            }
13849            MemInfoReader memInfo = new MemInfoReader();
13850            memInfo.readMemInfo();
13851            if (nativeProcTotalPss > 0) {
13852                synchronized (this) {
13853                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13854                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13855                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13856                            nativeProcTotalPss);
13857                }
13858            }
13859            if (!brief) {
13860                if (!isCompact) {
13861                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13862                    pw.print(" kB (status ");
13863                    switch (mLastMemoryLevel) {
13864                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13865                            pw.println("normal)");
13866                            break;
13867                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13868                            pw.println("moderate)");
13869                            break;
13870                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13871                            pw.println("low)");
13872                            break;
13873                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13874                            pw.println("critical)");
13875                            break;
13876                        default:
13877                            pw.print(mLastMemoryLevel);
13878                            pw.println(")");
13879                            break;
13880                    }
13881                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13882                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13883                            pw.print(cachedPss); pw.print(" cached pss + ");
13884                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13885                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13886                } else {
13887                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13888                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13889                            + memInfo.getFreeSizeKb()); pw.print(",");
13890                    pw.println(totalPss - cachedPss);
13891                }
13892            }
13893            if (!isCompact) {
13894                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13895                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13896                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13897                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13898                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13899                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13900                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13901                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13902                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13903                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13904                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13905            }
13906            if (!brief) {
13907                if (memInfo.getZramTotalSizeKb() != 0) {
13908                    if (!isCompact) {
13909                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13910                                pw.print(" kB physical used for ");
13911                                pw.print(memInfo.getSwapTotalSizeKb()
13912                                        - memInfo.getSwapFreeSizeKb());
13913                                pw.print(" kB in swap (");
13914                                pw.print(memInfo.getSwapTotalSizeKb());
13915                                pw.println(" kB total swap)");
13916                    } else {
13917                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13918                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13919                                pw.println(memInfo.getSwapFreeSizeKb());
13920                    }
13921                }
13922                final int[] SINGLE_LONG_FORMAT = new int[] {
13923                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13924                };
13925                long[] longOut = new long[1];
13926                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13927                        SINGLE_LONG_FORMAT, null, longOut, null);
13928                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13929                longOut[0] = 0;
13930                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13931                        SINGLE_LONG_FORMAT, null, longOut, null);
13932                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13933                longOut[0] = 0;
13934                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13935                        SINGLE_LONG_FORMAT, null, longOut, null);
13936                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13937                longOut[0] = 0;
13938                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13939                        SINGLE_LONG_FORMAT, null, longOut, null);
13940                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13941                if (!isCompact) {
13942                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13943                        pw.print("      KSM: "); pw.print(sharing);
13944                                pw.print(" kB saved from shared ");
13945                                pw.print(shared); pw.println(" kB");
13946                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13947                                pw.print(voltile); pw.println(" kB volatile");
13948                    }
13949                    pw.print("   Tuning: ");
13950                    pw.print(ActivityManager.staticGetMemoryClass());
13951                    pw.print(" (large ");
13952                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13953                    pw.print("), oom ");
13954                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13955                    pw.print(" kB");
13956                    pw.print(", restore limit ");
13957                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13958                    pw.print(" kB");
13959                    if (ActivityManager.isLowRamDeviceStatic()) {
13960                        pw.print(" (low-ram)");
13961                    }
13962                    if (ActivityManager.isHighEndGfx()) {
13963                        pw.print(" (high-end-gfx)");
13964                    }
13965                    pw.println();
13966                } else {
13967                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13968                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13969                    pw.println(voltile);
13970                    pw.print("tuning,");
13971                    pw.print(ActivityManager.staticGetMemoryClass());
13972                    pw.print(',');
13973                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13974                    pw.print(',');
13975                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13976                    if (ActivityManager.isLowRamDeviceStatic()) {
13977                        pw.print(",low-ram");
13978                    }
13979                    if (ActivityManager.isHighEndGfx()) {
13980                        pw.print(",high-end-gfx");
13981                    }
13982                    pw.println();
13983                }
13984            }
13985        }
13986    }
13987
13988    /**
13989     * Searches array of arguments for the specified string
13990     * @param args array of argument strings
13991     * @param value value to search for
13992     * @return true if the value is contained in the array
13993     */
13994    private static boolean scanArgs(String[] args, String value) {
13995        if (args != null) {
13996            for (String arg : args) {
13997                if (value.equals(arg)) {
13998                    return true;
13999                }
14000            }
14001        }
14002        return false;
14003    }
14004
14005    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14006            ContentProviderRecord cpr, boolean always) {
14007        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14008
14009        if (!inLaunching || always) {
14010            synchronized (cpr) {
14011                cpr.launchingApp = null;
14012                cpr.notifyAll();
14013            }
14014            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14015            String names[] = cpr.info.authority.split(";");
14016            for (int j = 0; j < names.length; j++) {
14017                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14018            }
14019        }
14020
14021        for (int i=0; i<cpr.connections.size(); i++) {
14022            ContentProviderConnection conn = cpr.connections.get(i);
14023            if (conn.waiting) {
14024                // If this connection is waiting for the provider, then we don't
14025                // need to mess with its process unless we are always removing
14026                // or for some reason the provider is not currently launching.
14027                if (inLaunching && !always) {
14028                    continue;
14029                }
14030            }
14031            ProcessRecord capp = conn.client;
14032            conn.dead = true;
14033            if (conn.stableCount > 0) {
14034                if (!capp.persistent && capp.thread != null
14035                        && capp.pid != 0
14036                        && capp.pid != MY_PID) {
14037                    capp.kill("depends on provider "
14038                            + cpr.name.flattenToShortString()
14039                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14040                }
14041            } else if (capp.thread != null && conn.provider.provider != null) {
14042                try {
14043                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14044                } catch (RemoteException e) {
14045                }
14046                // In the protocol here, we don't expect the client to correctly
14047                // clean up this connection, we'll just remove it.
14048                cpr.connections.remove(i);
14049                conn.client.conProviders.remove(conn);
14050            }
14051        }
14052
14053        if (inLaunching && always) {
14054            mLaunchingProviders.remove(cpr);
14055        }
14056        return inLaunching;
14057    }
14058
14059    /**
14060     * Main code for cleaning up a process when it has gone away.  This is
14061     * called both as a result of the process dying, or directly when stopping
14062     * a process when running in single process mode.
14063     */
14064    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14065            boolean restarting, boolean allowRestart, int index) {
14066        if (index >= 0) {
14067            removeLruProcessLocked(app);
14068            ProcessList.remove(app.pid);
14069        }
14070
14071        mProcessesToGc.remove(app);
14072        mPendingPssProcesses.remove(app);
14073
14074        // Dismiss any open dialogs.
14075        if (app.crashDialog != null && !app.forceCrashReport) {
14076            app.crashDialog.dismiss();
14077            app.crashDialog = null;
14078        }
14079        if (app.anrDialog != null) {
14080            app.anrDialog.dismiss();
14081            app.anrDialog = null;
14082        }
14083        if (app.waitDialog != null) {
14084            app.waitDialog.dismiss();
14085            app.waitDialog = null;
14086        }
14087
14088        app.crashing = false;
14089        app.notResponding = false;
14090
14091        app.resetPackageList(mProcessStats);
14092        app.unlinkDeathRecipient();
14093        app.makeInactive(mProcessStats);
14094        app.waitingToKill = null;
14095        app.forcingToForeground = null;
14096        updateProcessForegroundLocked(app, false, false);
14097        app.foregroundActivities = false;
14098        app.hasShownUi = false;
14099        app.treatLikeActivity = false;
14100        app.hasAboveClient = false;
14101        app.hasClientActivities = false;
14102
14103        mServices.killServicesLocked(app, allowRestart);
14104
14105        boolean restart = false;
14106
14107        // Remove published content providers.
14108        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14109            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14110            final boolean always = app.bad || !allowRestart;
14111            if (removeDyingProviderLocked(app, cpr, always) || always) {
14112                // We left the provider in the launching list, need to
14113                // restart it.
14114                restart = true;
14115            }
14116
14117            cpr.provider = null;
14118            cpr.proc = null;
14119        }
14120        app.pubProviders.clear();
14121
14122        // Take care of any launching providers waiting for this process.
14123        if (checkAppInLaunchingProvidersLocked(app, false)) {
14124            restart = true;
14125        }
14126
14127        // Unregister from connected content providers.
14128        if (!app.conProviders.isEmpty()) {
14129            for (int i=0; i<app.conProviders.size(); i++) {
14130                ContentProviderConnection conn = app.conProviders.get(i);
14131                conn.provider.connections.remove(conn);
14132            }
14133            app.conProviders.clear();
14134        }
14135
14136        // At this point there may be remaining entries in mLaunchingProviders
14137        // where we were the only one waiting, so they are no longer of use.
14138        // Look for these and clean up if found.
14139        // XXX Commented out for now.  Trying to figure out a way to reproduce
14140        // the actual situation to identify what is actually going on.
14141        if (false) {
14142            for (int i=0; i<mLaunchingProviders.size(); i++) {
14143                ContentProviderRecord cpr = (ContentProviderRecord)
14144                        mLaunchingProviders.get(i);
14145                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14146                    synchronized (cpr) {
14147                        cpr.launchingApp = null;
14148                        cpr.notifyAll();
14149                    }
14150                }
14151            }
14152        }
14153
14154        skipCurrentReceiverLocked(app);
14155
14156        // Unregister any receivers.
14157        for (int i=app.receivers.size()-1; i>=0; i--) {
14158            removeReceiverLocked(app.receivers.valueAt(i));
14159        }
14160        app.receivers.clear();
14161
14162        // If the app is undergoing backup, tell the backup manager about it
14163        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14164            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14165                    + mBackupTarget.appInfo + " died during backup");
14166            try {
14167                IBackupManager bm = IBackupManager.Stub.asInterface(
14168                        ServiceManager.getService(Context.BACKUP_SERVICE));
14169                bm.agentDisconnected(app.info.packageName);
14170            } catch (RemoteException e) {
14171                // can't happen; backup manager is local
14172            }
14173        }
14174
14175        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14176            ProcessChangeItem item = mPendingProcessChanges.get(i);
14177            if (item.pid == app.pid) {
14178                mPendingProcessChanges.remove(i);
14179                mAvailProcessChanges.add(item);
14180            }
14181        }
14182        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14183
14184        // If the caller is restarting this app, then leave it in its
14185        // current lists and let the caller take care of it.
14186        if (restarting) {
14187            return;
14188        }
14189
14190        if (!app.persistent || app.isolated) {
14191            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14192                    "Removing non-persistent process during cleanup: " + app);
14193            mProcessNames.remove(app.processName, app.uid);
14194            mIsolatedProcesses.remove(app.uid);
14195            if (mHeavyWeightProcess == app) {
14196                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14197                        mHeavyWeightProcess.userId, 0));
14198                mHeavyWeightProcess = null;
14199            }
14200        } else if (!app.removed) {
14201            // This app is persistent, so we need to keep its record around.
14202            // If it is not already on the pending app list, add it there
14203            // and start a new process for it.
14204            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14205                mPersistentStartingProcesses.add(app);
14206                restart = true;
14207            }
14208        }
14209        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14210                "Clean-up removing on hold: " + app);
14211        mProcessesOnHold.remove(app);
14212
14213        if (app == mHomeProcess) {
14214            mHomeProcess = null;
14215        }
14216        if (app == mPreviousProcess) {
14217            mPreviousProcess = null;
14218        }
14219
14220        if (restart && !app.isolated) {
14221            // We have components that still need to be running in the
14222            // process, so re-launch it.
14223            mProcessNames.put(app.processName, app.uid, app);
14224            startProcessLocked(app, "restart", app.processName);
14225        } else if (app.pid > 0 && app.pid != MY_PID) {
14226            // Goodbye!
14227            boolean removed;
14228            synchronized (mPidsSelfLocked) {
14229                mPidsSelfLocked.remove(app.pid);
14230                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14231            }
14232            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14233            if (app.isolated) {
14234                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14235            }
14236            app.setPid(0);
14237        }
14238    }
14239
14240    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14241        // Look through the content providers we are waiting to have launched,
14242        // and if any run in this process then either schedule a restart of
14243        // the process or kill the client waiting for it if this process has
14244        // gone bad.
14245        int NL = mLaunchingProviders.size();
14246        boolean restart = false;
14247        for (int i=0; i<NL; i++) {
14248            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14249            if (cpr.launchingApp == app) {
14250                if (!alwaysBad && !app.bad) {
14251                    restart = true;
14252                } else {
14253                    removeDyingProviderLocked(app, cpr, true);
14254                    // cpr should have been removed from mLaunchingProviders
14255                    NL = mLaunchingProviders.size();
14256                    i--;
14257                }
14258            }
14259        }
14260        return restart;
14261    }
14262
14263    // =========================================================
14264    // SERVICES
14265    // =========================================================
14266
14267    @Override
14268    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14269            int flags) {
14270        enforceNotIsolatedCaller("getServices");
14271        synchronized (this) {
14272            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14273        }
14274    }
14275
14276    @Override
14277    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14278        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14279        synchronized (this) {
14280            return mServices.getRunningServiceControlPanelLocked(name);
14281        }
14282    }
14283
14284    @Override
14285    public ComponentName startService(IApplicationThread caller, Intent service,
14286            String resolvedType, int userId) {
14287        enforceNotIsolatedCaller("startService");
14288        // Refuse possible leaked file descriptors
14289        if (service != null && service.hasFileDescriptors() == true) {
14290            throw new IllegalArgumentException("File descriptors passed in Intent");
14291        }
14292
14293        if (DEBUG_SERVICE)
14294            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14295        synchronized(this) {
14296            final int callingPid = Binder.getCallingPid();
14297            final int callingUid = Binder.getCallingUid();
14298            final long origId = Binder.clearCallingIdentity();
14299            ComponentName res = mServices.startServiceLocked(caller, service,
14300                    resolvedType, callingPid, callingUid, userId);
14301            Binder.restoreCallingIdentity(origId);
14302            return res;
14303        }
14304    }
14305
14306    ComponentName startServiceInPackage(int uid,
14307            Intent service, String resolvedType, int userId) {
14308        synchronized(this) {
14309            if (DEBUG_SERVICE)
14310                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14311            final long origId = Binder.clearCallingIdentity();
14312            ComponentName res = mServices.startServiceLocked(null, service,
14313                    resolvedType, -1, uid, userId);
14314            Binder.restoreCallingIdentity(origId);
14315            return res;
14316        }
14317    }
14318
14319    @Override
14320    public int stopService(IApplicationThread caller, Intent service,
14321            String resolvedType, int userId) {
14322        enforceNotIsolatedCaller("stopService");
14323        // Refuse possible leaked file descriptors
14324        if (service != null && service.hasFileDescriptors() == true) {
14325            throw new IllegalArgumentException("File descriptors passed in Intent");
14326        }
14327
14328        synchronized(this) {
14329            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14330        }
14331    }
14332
14333    @Override
14334    public IBinder peekService(Intent service, String resolvedType) {
14335        enforceNotIsolatedCaller("peekService");
14336        // Refuse possible leaked file descriptors
14337        if (service != null && service.hasFileDescriptors() == true) {
14338            throw new IllegalArgumentException("File descriptors passed in Intent");
14339        }
14340        synchronized(this) {
14341            return mServices.peekServiceLocked(service, resolvedType);
14342        }
14343    }
14344
14345    @Override
14346    public boolean stopServiceToken(ComponentName className, IBinder token,
14347            int startId) {
14348        synchronized(this) {
14349            return mServices.stopServiceTokenLocked(className, token, startId);
14350        }
14351    }
14352
14353    @Override
14354    public void setServiceForeground(ComponentName className, IBinder token,
14355            int id, Notification notification, boolean removeNotification) {
14356        synchronized(this) {
14357            mServices.setServiceForegroundLocked(className, token, id, notification,
14358                    removeNotification);
14359        }
14360    }
14361
14362    @Override
14363    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14364            boolean requireFull, String name, String callerPackage) {
14365        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14366                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14367    }
14368
14369    int unsafeConvertIncomingUser(int userId) {
14370        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14371                ? mCurrentUserId : userId;
14372    }
14373
14374    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14375            int allowMode, String name, String callerPackage) {
14376        final int callingUserId = UserHandle.getUserId(callingUid);
14377        if (callingUserId == userId) {
14378            return userId;
14379        }
14380
14381        // Note that we may be accessing mCurrentUserId outside of a lock...
14382        // shouldn't be a big deal, if this is being called outside
14383        // of a locked context there is intrinsically a race with
14384        // the value the caller will receive and someone else changing it.
14385        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14386        // we will switch to the calling user if access to the current user fails.
14387        int targetUserId = unsafeConvertIncomingUser(userId);
14388
14389        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14390            final boolean allow;
14391            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14392                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14393                // If the caller has this permission, they always pass go.  And collect $200.
14394                allow = true;
14395            } else if (allowMode == ALLOW_FULL_ONLY) {
14396                // We require full access, sucks to be you.
14397                allow = false;
14398            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14399                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14400                // If the caller does not have either permission, they are always doomed.
14401                allow = false;
14402            } else if (allowMode == ALLOW_NON_FULL) {
14403                // We are blanket allowing non-full access, you lucky caller!
14404                allow = true;
14405            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14406                // We may or may not allow this depending on whether the two users are
14407                // in the same profile.
14408                synchronized (mUserProfileGroupIdsSelfLocked) {
14409                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14410                            UserInfo.NO_PROFILE_GROUP_ID);
14411                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14412                            UserInfo.NO_PROFILE_GROUP_ID);
14413                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14414                            && callingProfile == targetProfile;
14415                }
14416            } else {
14417                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14418            }
14419            if (!allow) {
14420                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14421                    // In this case, they would like to just execute as their
14422                    // owner user instead of failing.
14423                    targetUserId = callingUserId;
14424                } else {
14425                    StringBuilder builder = new StringBuilder(128);
14426                    builder.append("Permission Denial: ");
14427                    builder.append(name);
14428                    if (callerPackage != null) {
14429                        builder.append(" from ");
14430                        builder.append(callerPackage);
14431                    }
14432                    builder.append(" asks to run as user ");
14433                    builder.append(userId);
14434                    builder.append(" but is calling from user ");
14435                    builder.append(UserHandle.getUserId(callingUid));
14436                    builder.append("; this requires ");
14437                    builder.append(INTERACT_ACROSS_USERS_FULL);
14438                    if (allowMode != ALLOW_FULL_ONLY) {
14439                        builder.append(" or ");
14440                        builder.append(INTERACT_ACROSS_USERS);
14441                    }
14442                    String msg = builder.toString();
14443                    Slog.w(TAG, msg);
14444                    throw new SecurityException(msg);
14445                }
14446            }
14447        }
14448        if (!allowAll && targetUserId < 0) {
14449            throw new IllegalArgumentException(
14450                    "Call does not support special user #" + targetUserId);
14451        }
14452        return targetUserId;
14453    }
14454
14455    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14456            String className, int flags) {
14457        boolean result = false;
14458        // For apps that don't have pre-defined UIDs, check for permission
14459        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14460            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14461                if (ActivityManager.checkUidPermission(
14462                        INTERACT_ACROSS_USERS,
14463                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14464                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14465                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14466                            + " requests FLAG_SINGLE_USER, but app does not hold "
14467                            + INTERACT_ACROSS_USERS;
14468                    Slog.w(TAG, msg);
14469                    throw new SecurityException(msg);
14470                }
14471                // Permission passed
14472                result = true;
14473            }
14474        } else if ("system".equals(componentProcessName)) {
14475            result = true;
14476        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14477                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14478            // Phone app is allowed to export singleuser providers.
14479            result = true;
14480        } else {
14481            // App with pre-defined UID, check if it's a persistent app
14482            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14483        }
14484        if (DEBUG_MU) {
14485            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14486                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14487        }
14488        return result;
14489    }
14490
14491    /**
14492     * Checks to see if the caller is in the same app as the singleton
14493     * component, or the component is in a special app. It allows special apps
14494     * to export singleton components but prevents exporting singleton
14495     * components for regular apps.
14496     */
14497    boolean isValidSingletonCall(int callingUid, int componentUid) {
14498        int componentAppId = UserHandle.getAppId(componentUid);
14499        return UserHandle.isSameApp(callingUid, componentUid)
14500                || componentAppId == Process.SYSTEM_UID
14501                || componentAppId == Process.PHONE_UID
14502                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14503                        == PackageManager.PERMISSION_GRANTED;
14504    }
14505
14506    public int bindService(IApplicationThread caller, IBinder token,
14507            Intent service, String resolvedType,
14508            IServiceConnection connection, int flags, int userId) {
14509        enforceNotIsolatedCaller("bindService");
14510        // Refuse possible leaked file descriptors
14511        if (service != null && service.hasFileDescriptors() == true) {
14512            throw new IllegalArgumentException("File descriptors passed in Intent");
14513        }
14514
14515        synchronized(this) {
14516            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14517                    connection, flags, userId);
14518        }
14519    }
14520
14521    public boolean unbindService(IServiceConnection connection) {
14522        synchronized (this) {
14523            return mServices.unbindServiceLocked(connection);
14524        }
14525    }
14526
14527    public void publishService(IBinder token, Intent intent, IBinder service) {
14528        // Refuse possible leaked file descriptors
14529        if (intent != null && intent.hasFileDescriptors() == true) {
14530            throw new IllegalArgumentException("File descriptors passed in Intent");
14531        }
14532
14533        synchronized(this) {
14534            if (!(token instanceof ServiceRecord)) {
14535                throw new IllegalArgumentException("Invalid service token");
14536            }
14537            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14538        }
14539    }
14540
14541    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14542        // Refuse possible leaked file descriptors
14543        if (intent != null && intent.hasFileDescriptors() == true) {
14544            throw new IllegalArgumentException("File descriptors passed in Intent");
14545        }
14546
14547        synchronized(this) {
14548            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14549        }
14550    }
14551
14552    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14553        synchronized(this) {
14554            if (!(token instanceof ServiceRecord)) {
14555                throw new IllegalArgumentException("Invalid service token");
14556            }
14557            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14558        }
14559    }
14560
14561    // =========================================================
14562    // BACKUP AND RESTORE
14563    // =========================================================
14564
14565    // Cause the target app to be launched if necessary and its backup agent
14566    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14567    // activity manager to announce its creation.
14568    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14569        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14570        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14571
14572        synchronized(this) {
14573            // !!! TODO: currently no check here that we're already bound
14574            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14575            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14576            synchronized (stats) {
14577                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14578            }
14579
14580            // Backup agent is now in use, its package can't be stopped.
14581            try {
14582                AppGlobals.getPackageManager().setPackageStoppedState(
14583                        app.packageName, false, UserHandle.getUserId(app.uid));
14584            } catch (RemoteException e) {
14585            } catch (IllegalArgumentException e) {
14586                Slog.w(TAG, "Failed trying to unstop package "
14587                        + app.packageName + ": " + e);
14588            }
14589
14590            BackupRecord r = new BackupRecord(ss, app, backupMode);
14591            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14592                    ? new ComponentName(app.packageName, app.backupAgentName)
14593                    : new ComponentName("android", "FullBackupAgent");
14594            // startProcessLocked() returns existing proc's record if it's already running
14595            ProcessRecord proc = startProcessLocked(app.processName, app,
14596                    false, 0, "backup", hostingName, false, false, false);
14597            if (proc == null) {
14598                Slog.e(TAG, "Unable to start backup agent process " + r);
14599                return false;
14600            }
14601
14602            r.app = proc;
14603            mBackupTarget = r;
14604            mBackupAppName = app.packageName;
14605
14606            // Try not to kill the process during backup
14607            updateOomAdjLocked(proc);
14608
14609            // If the process is already attached, schedule the creation of the backup agent now.
14610            // If it is not yet live, this will be done when it attaches to the framework.
14611            if (proc.thread != null) {
14612                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14613                try {
14614                    proc.thread.scheduleCreateBackupAgent(app,
14615                            compatibilityInfoForPackageLocked(app), backupMode);
14616                } catch (RemoteException e) {
14617                    // Will time out on the backup manager side
14618                }
14619            } else {
14620                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14621            }
14622            // Invariants: at this point, the target app process exists and the application
14623            // is either already running or in the process of coming up.  mBackupTarget and
14624            // mBackupAppName describe the app, so that when it binds back to the AM we
14625            // know that it's scheduled for a backup-agent operation.
14626        }
14627
14628        return true;
14629    }
14630
14631    @Override
14632    public void clearPendingBackup() {
14633        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14634        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14635
14636        synchronized (this) {
14637            mBackupTarget = null;
14638            mBackupAppName = null;
14639        }
14640    }
14641
14642    // A backup agent has just come up
14643    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14644        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14645                + " = " + agent);
14646
14647        synchronized(this) {
14648            if (!agentPackageName.equals(mBackupAppName)) {
14649                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14650                return;
14651            }
14652        }
14653
14654        long oldIdent = Binder.clearCallingIdentity();
14655        try {
14656            IBackupManager bm = IBackupManager.Stub.asInterface(
14657                    ServiceManager.getService(Context.BACKUP_SERVICE));
14658            bm.agentConnected(agentPackageName, agent);
14659        } catch (RemoteException e) {
14660            // can't happen; the backup manager service is local
14661        } catch (Exception e) {
14662            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14663            e.printStackTrace();
14664        } finally {
14665            Binder.restoreCallingIdentity(oldIdent);
14666        }
14667    }
14668
14669    // done with this agent
14670    public void unbindBackupAgent(ApplicationInfo appInfo) {
14671        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14672        if (appInfo == null) {
14673            Slog.w(TAG, "unbind backup agent for null app");
14674            return;
14675        }
14676
14677        synchronized(this) {
14678            try {
14679                if (mBackupAppName == null) {
14680                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14681                    return;
14682                }
14683
14684                if (!mBackupAppName.equals(appInfo.packageName)) {
14685                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14686                    return;
14687                }
14688
14689                // Not backing this app up any more; reset its OOM adjustment
14690                final ProcessRecord proc = mBackupTarget.app;
14691                updateOomAdjLocked(proc);
14692
14693                // If the app crashed during backup, 'thread' will be null here
14694                if (proc.thread != null) {
14695                    try {
14696                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14697                                compatibilityInfoForPackageLocked(appInfo));
14698                    } catch (Exception e) {
14699                        Slog.e(TAG, "Exception when unbinding backup agent:");
14700                        e.printStackTrace();
14701                    }
14702                }
14703            } finally {
14704                mBackupTarget = null;
14705                mBackupAppName = null;
14706            }
14707        }
14708    }
14709    // =========================================================
14710    // BROADCASTS
14711    // =========================================================
14712
14713    private final List getStickiesLocked(String action, IntentFilter filter,
14714            List cur, int userId) {
14715        final ContentResolver resolver = mContext.getContentResolver();
14716        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14717        if (stickies == null) {
14718            return cur;
14719        }
14720        final ArrayList<Intent> list = stickies.get(action);
14721        if (list == null) {
14722            return cur;
14723        }
14724        int N = list.size();
14725        for (int i=0; i<N; i++) {
14726            Intent intent = list.get(i);
14727            if (filter.match(resolver, intent, true, TAG) >= 0) {
14728                if (cur == null) {
14729                    cur = new ArrayList<Intent>();
14730                }
14731                cur.add(intent);
14732            }
14733        }
14734        return cur;
14735    }
14736
14737    boolean isPendingBroadcastProcessLocked(int pid) {
14738        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14739                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14740    }
14741
14742    void skipPendingBroadcastLocked(int pid) {
14743            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14744            for (BroadcastQueue queue : mBroadcastQueues) {
14745                queue.skipPendingBroadcastLocked(pid);
14746            }
14747    }
14748
14749    // The app just attached; send any pending broadcasts that it should receive
14750    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14751        boolean didSomething = false;
14752        for (BroadcastQueue queue : mBroadcastQueues) {
14753            didSomething |= queue.sendPendingBroadcastsLocked(app);
14754        }
14755        return didSomething;
14756    }
14757
14758    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14759            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14760        enforceNotIsolatedCaller("registerReceiver");
14761        int callingUid;
14762        int callingPid;
14763        synchronized(this) {
14764            ProcessRecord callerApp = null;
14765            if (caller != null) {
14766                callerApp = getRecordForAppLocked(caller);
14767                if (callerApp == null) {
14768                    throw new SecurityException(
14769                            "Unable to find app for caller " + caller
14770                            + " (pid=" + Binder.getCallingPid()
14771                            + ") when registering receiver " + receiver);
14772                }
14773                if (callerApp.info.uid != Process.SYSTEM_UID &&
14774                        !callerApp.pkgList.containsKey(callerPackage) &&
14775                        !"android".equals(callerPackage)) {
14776                    throw new SecurityException("Given caller package " + callerPackage
14777                            + " is not running in process " + callerApp);
14778                }
14779                callingUid = callerApp.info.uid;
14780                callingPid = callerApp.pid;
14781            } else {
14782                callerPackage = null;
14783                callingUid = Binder.getCallingUid();
14784                callingPid = Binder.getCallingPid();
14785            }
14786
14787            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14788                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14789
14790            List allSticky = null;
14791
14792            // Look for any matching sticky broadcasts...
14793            Iterator actions = filter.actionsIterator();
14794            if (actions != null) {
14795                while (actions.hasNext()) {
14796                    String action = (String)actions.next();
14797                    allSticky = getStickiesLocked(action, filter, allSticky,
14798                            UserHandle.USER_ALL);
14799                    allSticky = getStickiesLocked(action, filter, allSticky,
14800                            UserHandle.getUserId(callingUid));
14801                }
14802            } else {
14803                allSticky = getStickiesLocked(null, filter, allSticky,
14804                        UserHandle.USER_ALL);
14805                allSticky = getStickiesLocked(null, filter, allSticky,
14806                        UserHandle.getUserId(callingUid));
14807            }
14808
14809            // The first sticky in the list is returned directly back to
14810            // the client.
14811            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14812
14813            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14814                    + ": " + sticky);
14815
14816            if (receiver == null) {
14817                return sticky;
14818            }
14819
14820            ReceiverList rl
14821                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14822            if (rl == null) {
14823                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14824                        userId, receiver);
14825                if (rl.app != null) {
14826                    rl.app.receivers.add(rl);
14827                } else {
14828                    try {
14829                        receiver.asBinder().linkToDeath(rl, 0);
14830                    } catch (RemoteException e) {
14831                        return sticky;
14832                    }
14833                    rl.linkedToDeath = true;
14834                }
14835                mRegisteredReceivers.put(receiver.asBinder(), rl);
14836            } else if (rl.uid != callingUid) {
14837                throw new IllegalArgumentException(
14838                        "Receiver requested to register for uid " + callingUid
14839                        + " was previously registered for uid " + rl.uid);
14840            } else if (rl.pid != callingPid) {
14841                throw new IllegalArgumentException(
14842                        "Receiver requested to register for pid " + callingPid
14843                        + " was previously registered for pid " + rl.pid);
14844            } else if (rl.userId != userId) {
14845                throw new IllegalArgumentException(
14846                        "Receiver requested to register for user " + userId
14847                        + " was previously registered for user " + rl.userId);
14848            }
14849            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14850                    permission, callingUid, userId);
14851            rl.add(bf);
14852            if (!bf.debugCheck()) {
14853                Slog.w(TAG, "==> For Dynamic broadast");
14854            }
14855            mReceiverResolver.addFilter(bf);
14856
14857            // Enqueue broadcasts for all existing stickies that match
14858            // this filter.
14859            if (allSticky != null) {
14860                ArrayList receivers = new ArrayList();
14861                receivers.add(bf);
14862
14863                int N = allSticky.size();
14864                for (int i=0; i<N; i++) {
14865                    Intent intent = (Intent)allSticky.get(i);
14866                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14867                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14868                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14869                            null, null, false, true, true, -1);
14870                    queue.enqueueParallelBroadcastLocked(r);
14871                    queue.scheduleBroadcastsLocked();
14872                }
14873            }
14874
14875            return sticky;
14876        }
14877    }
14878
14879    public void unregisterReceiver(IIntentReceiver receiver) {
14880        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14881
14882        final long origId = Binder.clearCallingIdentity();
14883        try {
14884            boolean doTrim = false;
14885
14886            synchronized(this) {
14887                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14888                if (rl != null) {
14889                    if (rl.curBroadcast != null) {
14890                        BroadcastRecord r = rl.curBroadcast;
14891                        final boolean doNext = finishReceiverLocked(
14892                                receiver.asBinder(), r.resultCode, r.resultData,
14893                                r.resultExtras, r.resultAbort);
14894                        if (doNext) {
14895                            doTrim = true;
14896                            r.queue.processNextBroadcast(false);
14897                        }
14898                    }
14899
14900                    if (rl.app != null) {
14901                        rl.app.receivers.remove(rl);
14902                    }
14903                    removeReceiverLocked(rl);
14904                    if (rl.linkedToDeath) {
14905                        rl.linkedToDeath = false;
14906                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14907                    }
14908                }
14909            }
14910
14911            // If we actually concluded any broadcasts, we might now be able
14912            // to trim the recipients' apps from our working set
14913            if (doTrim) {
14914                trimApplications();
14915                return;
14916            }
14917
14918        } finally {
14919            Binder.restoreCallingIdentity(origId);
14920        }
14921    }
14922
14923    void removeReceiverLocked(ReceiverList rl) {
14924        mRegisteredReceivers.remove(rl.receiver.asBinder());
14925        int N = rl.size();
14926        for (int i=0; i<N; i++) {
14927            mReceiverResolver.removeFilter(rl.get(i));
14928        }
14929    }
14930
14931    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14932        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14933            ProcessRecord r = mLruProcesses.get(i);
14934            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14935                try {
14936                    r.thread.dispatchPackageBroadcast(cmd, packages);
14937                } catch (RemoteException ex) {
14938                }
14939            }
14940        }
14941    }
14942
14943    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14944            int[] users) {
14945        List<ResolveInfo> receivers = null;
14946        try {
14947            HashSet<ComponentName> singleUserReceivers = null;
14948            boolean scannedFirstReceivers = false;
14949            for (int user : users) {
14950                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14951                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14952                if (user != 0 && newReceivers != null) {
14953                    // If this is not the primary user, we need to check for
14954                    // any receivers that should be filtered out.
14955                    for (int i=0; i<newReceivers.size(); i++) {
14956                        ResolveInfo ri = newReceivers.get(i);
14957                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14958                            newReceivers.remove(i);
14959                            i--;
14960                        }
14961                    }
14962                }
14963                if (newReceivers != null && newReceivers.size() == 0) {
14964                    newReceivers = null;
14965                }
14966                if (receivers == null) {
14967                    receivers = newReceivers;
14968                } else if (newReceivers != null) {
14969                    // We need to concatenate the additional receivers
14970                    // found with what we have do far.  This would be easy,
14971                    // but we also need to de-dup any receivers that are
14972                    // singleUser.
14973                    if (!scannedFirstReceivers) {
14974                        // Collect any single user receivers we had already retrieved.
14975                        scannedFirstReceivers = true;
14976                        for (int i=0; i<receivers.size(); i++) {
14977                            ResolveInfo ri = receivers.get(i);
14978                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14979                                ComponentName cn = new ComponentName(
14980                                        ri.activityInfo.packageName, ri.activityInfo.name);
14981                                if (singleUserReceivers == null) {
14982                                    singleUserReceivers = new HashSet<ComponentName>();
14983                                }
14984                                singleUserReceivers.add(cn);
14985                            }
14986                        }
14987                    }
14988                    // Add the new results to the existing results, tracking
14989                    // and de-dupping single user receivers.
14990                    for (int i=0; i<newReceivers.size(); i++) {
14991                        ResolveInfo ri = newReceivers.get(i);
14992                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14993                            ComponentName cn = new ComponentName(
14994                                    ri.activityInfo.packageName, ri.activityInfo.name);
14995                            if (singleUserReceivers == null) {
14996                                singleUserReceivers = new HashSet<ComponentName>();
14997                            }
14998                            if (!singleUserReceivers.contains(cn)) {
14999                                singleUserReceivers.add(cn);
15000                                receivers.add(ri);
15001                            }
15002                        } else {
15003                            receivers.add(ri);
15004                        }
15005                    }
15006                }
15007            }
15008        } catch (RemoteException ex) {
15009            // pm is in same process, this will never happen.
15010        }
15011        return receivers;
15012    }
15013
15014    private final int broadcastIntentLocked(ProcessRecord callerApp,
15015            String callerPackage, Intent intent, String resolvedType,
15016            IIntentReceiver resultTo, int resultCode, String resultData,
15017            Bundle map, String requiredPermission, int appOp,
15018            boolean ordered, boolean sticky, int callingPid, int callingUid,
15019            int userId) {
15020        intent = new Intent(intent);
15021
15022        // By default broadcasts do not go to stopped apps.
15023        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15024
15025        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15026            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15027            + " ordered=" + ordered + " userid=" + userId);
15028        if ((resultTo != null) && !ordered) {
15029            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15030        }
15031
15032        userId = handleIncomingUser(callingPid, callingUid, userId,
15033                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15034
15035        // Make sure that the user who is receiving this broadcast is started.
15036        // If not, we will just skip it.
15037
15038
15039        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15040            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15041                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15042                Slog.w(TAG, "Skipping broadcast of " + intent
15043                        + ": user " + userId + " is stopped");
15044                return ActivityManager.BROADCAST_SUCCESS;
15045            }
15046        }
15047
15048        /*
15049         * Prevent non-system code (defined here to be non-persistent
15050         * processes) from sending protected broadcasts.
15051         */
15052        int callingAppId = UserHandle.getAppId(callingUid);
15053        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15054            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15055            || callingAppId == Process.NFC_UID || callingUid == 0) {
15056            // Always okay.
15057        } else if (callerApp == null || !callerApp.persistent) {
15058            try {
15059                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15060                        intent.getAction())) {
15061                    String msg = "Permission Denial: not allowed to send broadcast "
15062                            + intent.getAction() + " from pid="
15063                            + callingPid + ", uid=" + callingUid;
15064                    Slog.w(TAG, msg);
15065                    throw new SecurityException(msg);
15066                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15067                    // Special case for compatibility: we don't want apps to send this,
15068                    // but historically it has not been protected and apps may be using it
15069                    // to poke their own app widget.  So, instead of making it protected,
15070                    // just limit it to the caller.
15071                    if (callerApp == null) {
15072                        String msg = "Permission Denial: not allowed to send broadcast "
15073                                + intent.getAction() + " from unknown caller.";
15074                        Slog.w(TAG, msg);
15075                        throw new SecurityException(msg);
15076                    } else if (intent.getComponent() != null) {
15077                        // They are good enough to send to an explicit component...  verify
15078                        // it is being sent to the calling app.
15079                        if (!intent.getComponent().getPackageName().equals(
15080                                callerApp.info.packageName)) {
15081                            String msg = "Permission Denial: not allowed to send broadcast "
15082                                    + intent.getAction() + " to "
15083                                    + intent.getComponent().getPackageName() + " from "
15084                                    + callerApp.info.packageName;
15085                            Slog.w(TAG, msg);
15086                            throw new SecurityException(msg);
15087                        }
15088                    } else {
15089                        // Limit broadcast to their own package.
15090                        intent.setPackage(callerApp.info.packageName);
15091                    }
15092                }
15093            } catch (RemoteException e) {
15094                Slog.w(TAG, "Remote exception", e);
15095                return ActivityManager.BROADCAST_SUCCESS;
15096            }
15097        }
15098
15099        // Handle special intents: if this broadcast is from the package
15100        // manager about a package being removed, we need to remove all of
15101        // its activities from the history stack.
15102        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15103                intent.getAction());
15104        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15105                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15106                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15107                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15108                || uidRemoved) {
15109            if (checkComponentPermission(
15110                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15111                    callingPid, callingUid, -1, true)
15112                    == PackageManager.PERMISSION_GRANTED) {
15113                if (uidRemoved) {
15114                    final Bundle intentExtras = intent.getExtras();
15115                    final int uid = intentExtras != null
15116                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15117                    if (uid >= 0) {
15118                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15119                        synchronized (bs) {
15120                            bs.removeUidStatsLocked(uid);
15121                        }
15122                        mAppOpsService.uidRemoved(uid);
15123                    }
15124                } else {
15125                    // If resources are unavailable just force stop all
15126                    // those packages and flush the attribute cache as well.
15127                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15128                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15129                        if (list != null && (list.length > 0)) {
15130                            for (String pkg : list) {
15131                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15132                                        "storage unmount");
15133                            }
15134                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15135                            sendPackageBroadcastLocked(
15136                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15137                        }
15138                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15139                            intent.getAction())) {
15140                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15141                    } else {
15142                        Uri data = intent.getData();
15143                        String ssp;
15144                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15145                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15146                                    intent.getAction());
15147                            boolean fullUninstall = removed &&
15148                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15149                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15150                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15151                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15152                                        false, fullUninstall, userId,
15153                                        removed ? "pkg removed" : "pkg changed");
15154                            }
15155                            if (removed) {
15156                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15157                                        new String[] {ssp}, userId);
15158                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15159                                    mAppOpsService.packageRemoved(
15160                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15161
15162                                    // Remove all permissions granted from/to this package
15163                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15164                                }
15165                            }
15166                        }
15167                    }
15168                }
15169            } else {
15170                String msg = "Permission Denial: " + intent.getAction()
15171                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15172                        + ", uid=" + callingUid + ")"
15173                        + " requires "
15174                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15175                Slog.w(TAG, msg);
15176                throw new SecurityException(msg);
15177            }
15178
15179        // Special case for adding a package: by default turn on compatibility
15180        // mode.
15181        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15182            Uri data = intent.getData();
15183            String ssp;
15184            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15185                mCompatModePackages.handlePackageAddedLocked(ssp,
15186                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15187            }
15188        }
15189
15190        /*
15191         * If this is the time zone changed action, queue up a message that will reset the timezone
15192         * of all currently running processes. This message will get queued up before the broadcast
15193         * happens.
15194         */
15195        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15196            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15197        }
15198
15199        /*
15200         * If the user set the time, let all running processes know.
15201         */
15202        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15203            final int is24Hour = intent.getBooleanExtra(
15204                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15205            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15206            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15207            synchronized (stats) {
15208                stats.noteCurrentTimeChangedLocked();
15209            }
15210        }
15211
15212        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15213            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15214        }
15215
15216        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15217            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15218            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15219        }
15220
15221        // Add to the sticky list if requested.
15222        if (sticky) {
15223            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15224                    callingPid, callingUid)
15225                    != PackageManager.PERMISSION_GRANTED) {
15226                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15227                        + callingPid + ", uid=" + callingUid
15228                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15229                Slog.w(TAG, msg);
15230                throw new SecurityException(msg);
15231            }
15232            if (requiredPermission != null) {
15233                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15234                        + " and enforce permission " + requiredPermission);
15235                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15236            }
15237            if (intent.getComponent() != null) {
15238                throw new SecurityException(
15239                        "Sticky broadcasts can't target a specific component");
15240            }
15241            // We use userId directly here, since the "all" target is maintained
15242            // as a separate set of sticky broadcasts.
15243            if (userId != UserHandle.USER_ALL) {
15244                // But first, if this is not a broadcast to all users, then
15245                // make sure it doesn't conflict with an existing broadcast to
15246                // all users.
15247                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15248                        UserHandle.USER_ALL);
15249                if (stickies != null) {
15250                    ArrayList<Intent> list = stickies.get(intent.getAction());
15251                    if (list != null) {
15252                        int N = list.size();
15253                        int i;
15254                        for (i=0; i<N; i++) {
15255                            if (intent.filterEquals(list.get(i))) {
15256                                throw new IllegalArgumentException(
15257                                        "Sticky broadcast " + intent + " for user "
15258                                        + userId + " conflicts with existing global broadcast");
15259                            }
15260                        }
15261                    }
15262                }
15263            }
15264            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15265            if (stickies == null) {
15266                stickies = new ArrayMap<String, ArrayList<Intent>>();
15267                mStickyBroadcasts.put(userId, stickies);
15268            }
15269            ArrayList<Intent> list = stickies.get(intent.getAction());
15270            if (list == null) {
15271                list = new ArrayList<Intent>();
15272                stickies.put(intent.getAction(), list);
15273            }
15274            int N = list.size();
15275            int i;
15276            for (i=0; i<N; i++) {
15277                if (intent.filterEquals(list.get(i))) {
15278                    // This sticky already exists, replace it.
15279                    list.set(i, new Intent(intent));
15280                    break;
15281                }
15282            }
15283            if (i >= N) {
15284                list.add(new Intent(intent));
15285            }
15286        }
15287
15288        int[] users;
15289        if (userId == UserHandle.USER_ALL) {
15290            // Caller wants broadcast to go to all started users.
15291            users = mStartedUserArray;
15292        } else {
15293            // Caller wants broadcast to go to one specific user.
15294            users = new int[] {userId};
15295        }
15296
15297        // Figure out who all will receive this broadcast.
15298        List receivers = null;
15299        List<BroadcastFilter> registeredReceivers = null;
15300        // Need to resolve the intent to interested receivers...
15301        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15302                 == 0) {
15303            receivers = collectReceiverComponents(intent, resolvedType, users);
15304        }
15305        if (intent.getComponent() == null) {
15306            registeredReceivers = mReceiverResolver.queryIntent(intent,
15307                    resolvedType, false, userId);
15308        }
15309
15310        final boolean replacePending =
15311                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15312
15313        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15314                + " replacePending=" + replacePending);
15315
15316        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15317        if (!ordered && NR > 0) {
15318            // If we are not serializing this broadcast, then send the
15319            // registered receivers separately so they don't wait for the
15320            // components to be launched.
15321            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15322            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15323                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15324                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15325                    ordered, sticky, false, userId);
15326            if (DEBUG_BROADCAST) Slog.v(
15327                    TAG, "Enqueueing parallel broadcast " + r);
15328            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15329            if (!replaced) {
15330                queue.enqueueParallelBroadcastLocked(r);
15331                queue.scheduleBroadcastsLocked();
15332            }
15333            registeredReceivers = null;
15334            NR = 0;
15335        }
15336
15337        // Merge into one list.
15338        int ir = 0;
15339        if (receivers != null) {
15340            // A special case for PACKAGE_ADDED: do not allow the package
15341            // being added to see this broadcast.  This prevents them from
15342            // using this as a back door to get run as soon as they are
15343            // installed.  Maybe in the future we want to have a special install
15344            // broadcast or such for apps, but we'd like to deliberately make
15345            // this decision.
15346            String skipPackages[] = null;
15347            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15348                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15349                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15350                Uri data = intent.getData();
15351                if (data != null) {
15352                    String pkgName = data.getSchemeSpecificPart();
15353                    if (pkgName != null) {
15354                        skipPackages = new String[] { pkgName };
15355                    }
15356                }
15357            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15358                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15359            }
15360            if (skipPackages != null && (skipPackages.length > 0)) {
15361                for (String skipPackage : skipPackages) {
15362                    if (skipPackage != null) {
15363                        int NT = receivers.size();
15364                        for (int it=0; it<NT; it++) {
15365                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15366                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15367                                receivers.remove(it);
15368                                it--;
15369                                NT--;
15370                            }
15371                        }
15372                    }
15373                }
15374            }
15375
15376            int NT = receivers != null ? receivers.size() : 0;
15377            int it = 0;
15378            ResolveInfo curt = null;
15379            BroadcastFilter curr = null;
15380            while (it < NT && ir < NR) {
15381                if (curt == null) {
15382                    curt = (ResolveInfo)receivers.get(it);
15383                }
15384                if (curr == null) {
15385                    curr = registeredReceivers.get(ir);
15386                }
15387                if (curr.getPriority() >= curt.priority) {
15388                    // Insert this broadcast record into the final list.
15389                    receivers.add(it, curr);
15390                    ir++;
15391                    curr = null;
15392                    it++;
15393                    NT++;
15394                } else {
15395                    // Skip to the next ResolveInfo in the final list.
15396                    it++;
15397                    curt = null;
15398                }
15399            }
15400        }
15401        while (ir < NR) {
15402            if (receivers == null) {
15403                receivers = new ArrayList();
15404            }
15405            receivers.add(registeredReceivers.get(ir));
15406            ir++;
15407        }
15408
15409        if ((receivers != null && receivers.size() > 0)
15410                || resultTo != null) {
15411            BroadcastQueue queue = broadcastQueueForIntent(intent);
15412            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15413                    callerPackage, callingPid, callingUid, resolvedType,
15414                    requiredPermission, appOp, receivers, resultTo, resultCode,
15415                    resultData, map, ordered, sticky, false, userId);
15416            if (DEBUG_BROADCAST) Slog.v(
15417                    TAG, "Enqueueing ordered broadcast " + r
15418                    + ": prev had " + queue.mOrderedBroadcasts.size());
15419            if (DEBUG_BROADCAST) {
15420                int seq = r.intent.getIntExtra("seq", -1);
15421                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15422            }
15423            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15424            if (!replaced) {
15425                queue.enqueueOrderedBroadcastLocked(r);
15426                queue.scheduleBroadcastsLocked();
15427            }
15428        }
15429
15430        return ActivityManager.BROADCAST_SUCCESS;
15431    }
15432
15433    final Intent verifyBroadcastLocked(Intent intent) {
15434        // Refuse possible leaked file descriptors
15435        if (intent != null && intent.hasFileDescriptors() == true) {
15436            throw new IllegalArgumentException("File descriptors passed in Intent");
15437        }
15438
15439        int flags = intent.getFlags();
15440
15441        if (!mProcessesReady) {
15442            // if the caller really truly claims to know what they're doing, go
15443            // ahead and allow the broadcast without launching any receivers
15444            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15445                intent = new Intent(intent);
15446                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15447            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15448                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15449                        + " before boot completion");
15450                throw new IllegalStateException("Cannot broadcast before boot completed");
15451            }
15452        }
15453
15454        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15455            throw new IllegalArgumentException(
15456                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15457        }
15458
15459        return intent;
15460    }
15461
15462    public final int broadcastIntent(IApplicationThread caller,
15463            Intent intent, String resolvedType, IIntentReceiver resultTo,
15464            int resultCode, String resultData, Bundle map,
15465            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15466        enforceNotIsolatedCaller("broadcastIntent");
15467        synchronized(this) {
15468            intent = verifyBroadcastLocked(intent);
15469
15470            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15471            final int callingPid = Binder.getCallingPid();
15472            final int callingUid = Binder.getCallingUid();
15473            final long origId = Binder.clearCallingIdentity();
15474            int res = broadcastIntentLocked(callerApp,
15475                    callerApp != null ? callerApp.info.packageName : null,
15476                    intent, resolvedType, resultTo,
15477                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15478                    callingPid, callingUid, userId);
15479            Binder.restoreCallingIdentity(origId);
15480            return res;
15481        }
15482    }
15483
15484    int broadcastIntentInPackage(String packageName, int uid,
15485            Intent intent, String resolvedType, IIntentReceiver resultTo,
15486            int resultCode, String resultData, Bundle map,
15487            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15488        synchronized(this) {
15489            intent = verifyBroadcastLocked(intent);
15490
15491            final long origId = Binder.clearCallingIdentity();
15492            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15493                    resultTo, resultCode, resultData, map, requiredPermission,
15494                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15495            Binder.restoreCallingIdentity(origId);
15496            return res;
15497        }
15498    }
15499
15500    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15501        // Refuse possible leaked file descriptors
15502        if (intent != null && intent.hasFileDescriptors() == true) {
15503            throw new IllegalArgumentException("File descriptors passed in Intent");
15504        }
15505
15506        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15507                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15508
15509        synchronized(this) {
15510            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15511                    != PackageManager.PERMISSION_GRANTED) {
15512                String msg = "Permission Denial: unbroadcastIntent() from pid="
15513                        + Binder.getCallingPid()
15514                        + ", uid=" + Binder.getCallingUid()
15515                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15516                Slog.w(TAG, msg);
15517                throw new SecurityException(msg);
15518            }
15519            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15520            if (stickies != null) {
15521                ArrayList<Intent> list = stickies.get(intent.getAction());
15522                if (list != null) {
15523                    int N = list.size();
15524                    int i;
15525                    for (i=0; i<N; i++) {
15526                        if (intent.filterEquals(list.get(i))) {
15527                            list.remove(i);
15528                            break;
15529                        }
15530                    }
15531                    if (list.size() <= 0) {
15532                        stickies.remove(intent.getAction());
15533                    }
15534                }
15535                if (stickies.size() <= 0) {
15536                    mStickyBroadcasts.remove(userId);
15537                }
15538            }
15539        }
15540    }
15541
15542    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15543            String resultData, Bundle resultExtras, boolean resultAbort) {
15544        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15545        if (r == null) {
15546            Slog.w(TAG, "finishReceiver called but not found on queue");
15547            return false;
15548        }
15549
15550        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15551    }
15552
15553    void backgroundServicesFinishedLocked(int userId) {
15554        for (BroadcastQueue queue : mBroadcastQueues) {
15555            queue.backgroundServicesFinishedLocked(userId);
15556        }
15557    }
15558
15559    public void finishReceiver(IBinder who, int resultCode, String resultData,
15560            Bundle resultExtras, boolean resultAbort) {
15561        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15562
15563        // Refuse possible leaked file descriptors
15564        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15565            throw new IllegalArgumentException("File descriptors passed in Bundle");
15566        }
15567
15568        final long origId = Binder.clearCallingIdentity();
15569        try {
15570            boolean doNext = false;
15571            BroadcastRecord r;
15572
15573            synchronized(this) {
15574                r = broadcastRecordForReceiverLocked(who);
15575                if (r != null) {
15576                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15577                        resultData, resultExtras, resultAbort, true);
15578                }
15579            }
15580
15581            if (doNext) {
15582                r.queue.processNextBroadcast(false);
15583            }
15584            trimApplications();
15585        } finally {
15586            Binder.restoreCallingIdentity(origId);
15587        }
15588    }
15589
15590    // =========================================================
15591    // INSTRUMENTATION
15592    // =========================================================
15593
15594    public boolean startInstrumentation(ComponentName className,
15595            String profileFile, int flags, Bundle arguments,
15596            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15597            int userId, String abiOverride) {
15598        enforceNotIsolatedCaller("startInstrumentation");
15599        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15600                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15601        // Refuse possible leaked file descriptors
15602        if (arguments != null && arguments.hasFileDescriptors()) {
15603            throw new IllegalArgumentException("File descriptors passed in Bundle");
15604        }
15605
15606        synchronized(this) {
15607            InstrumentationInfo ii = null;
15608            ApplicationInfo ai = null;
15609            try {
15610                ii = mContext.getPackageManager().getInstrumentationInfo(
15611                    className, STOCK_PM_FLAGS);
15612                ai = AppGlobals.getPackageManager().getApplicationInfo(
15613                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15614            } catch (PackageManager.NameNotFoundException e) {
15615            } catch (RemoteException e) {
15616            }
15617            if (ii == null) {
15618                reportStartInstrumentationFailure(watcher, className,
15619                        "Unable to find instrumentation info for: " + className);
15620                return false;
15621            }
15622            if (ai == null) {
15623                reportStartInstrumentationFailure(watcher, className,
15624                        "Unable to find instrumentation target package: " + ii.targetPackage);
15625                return false;
15626            }
15627
15628            int match = mContext.getPackageManager().checkSignatures(
15629                    ii.targetPackage, ii.packageName);
15630            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15631                String msg = "Permission Denial: starting instrumentation "
15632                        + className + " from pid="
15633                        + Binder.getCallingPid()
15634                        + ", uid=" + Binder.getCallingPid()
15635                        + " not allowed because package " + ii.packageName
15636                        + " does not have a signature matching the target "
15637                        + ii.targetPackage;
15638                reportStartInstrumentationFailure(watcher, className, msg);
15639                throw new SecurityException(msg);
15640            }
15641
15642            final long origId = Binder.clearCallingIdentity();
15643            // Instrumentation can kill and relaunch even persistent processes
15644            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15645                    "start instr");
15646            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15647            app.instrumentationClass = className;
15648            app.instrumentationInfo = ai;
15649            app.instrumentationProfileFile = profileFile;
15650            app.instrumentationArguments = arguments;
15651            app.instrumentationWatcher = watcher;
15652            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15653            app.instrumentationResultClass = className;
15654            Binder.restoreCallingIdentity(origId);
15655        }
15656
15657        return true;
15658    }
15659
15660    /**
15661     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15662     * error to the logs, but if somebody is watching, send the report there too.  This enables
15663     * the "am" command to report errors with more information.
15664     *
15665     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15666     * @param cn The component name of the instrumentation.
15667     * @param report The error report.
15668     */
15669    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15670            ComponentName cn, String report) {
15671        Slog.w(TAG, report);
15672        try {
15673            if (watcher != null) {
15674                Bundle results = new Bundle();
15675                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15676                results.putString("Error", report);
15677                watcher.instrumentationStatus(cn, -1, results);
15678            }
15679        } catch (RemoteException e) {
15680            Slog.w(TAG, e);
15681        }
15682    }
15683
15684    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15685        if (app.instrumentationWatcher != null) {
15686            try {
15687                // NOTE:  IInstrumentationWatcher *must* be oneway here
15688                app.instrumentationWatcher.instrumentationFinished(
15689                    app.instrumentationClass,
15690                    resultCode,
15691                    results);
15692            } catch (RemoteException e) {
15693            }
15694        }
15695        if (app.instrumentationUiAutomationConnection != null) {
15696            try {
15697                app.instrumentationUiAutomationConnection.shutdown();
15698            } catch (RemoteException re) {
15699                /* ignore */
15700            }
15701            // Only a UiAutomation can set this flag and now that
15702            // it is finished we make sure it is reset to its default.
15703            mUserIsMonkey = false;
15704        }
15705        app.instrumentationWatcher = null;
15706        app.instrumentationUiAutomationConnection = null;
15707        app.instrumentationClass = null;
15708        app.instrumentationInfo = null;
15709        app.instrumentationProfileFile = null;
15710        app.instrumentationArguments = null;
15711
15712        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15713                "finished inst");
15714    }
15715
15716    public void finishInstrumentation(IApplicationThread target,
15717            int resultCode, Bundle results) {
15718        int userId = UserHandle.getCallingUserId();
15719        // Refuse possible leaked file descriptors
15720        if (results != null && results.hasFileDescriptors()) {
15721            throw new IllegalArgumentException("File descriptors passed in Intent");
15722        }
15723
15724        synchronized(this) {
15725            ProcessRecord app = getRecordForAppLocked(target);
15726            if (app == null) {
15727                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15728                return;
15729            }
15730            final long origId = Binder.clearCallingIdentity();
15731            finishInstrumentationLocked(app, resultCode, results);
15732            Binder.restoreCallingIdentity(origId);
15733        }
15734    }
15735
15736    // =========================================================
15737    // CONFIGURATION
15738    // =========================================================
15739
15740    public ConfigurationInfo getDeviceConfigurationInfo() {
15741        ConfigurationInfo config = new ConfigurationInfo();
15742        synchronized (this) {
15743            config.reqTouchScreen = mConfiguration.touchscreen;
15744            config.reqKeyboardType = mConfiguration.keyboard;
15745            config.reqNavigation = mConfiguration.navigation;
15746            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15747                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15748                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15749            }
15750            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15751                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15752                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15753            }
15754            config.reqGlEsVersion = GL_ES_VERSION;
15755        }
15756        return config;
15757    }
15758
15759    ActivityStack getFocusedStack() {
15760        return mStackSupervisor.getFocusedStack();
15761    }
15762
15763    public Configuration getConfiguration() {
15764        Configuration ci;
15765        synchronized(this) {
15766            ci = new Configuration(mConfiguration);
15767        }
15768        return ci;
15769    }
15770
15771    public void updatePersistentConfiguration(Configuration values) {
15772        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15773                "updateConfiguration()");
15774        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15775                "updateConfiguration()");
15776        if (values == null) {
15777            throw new NullPointerException("Configuration must not be null");
15778        }
15779
15780        synchronized(this) {
15781            final long origId = Binder.clearCallingIdentity();
15782            updateConfigurationLocked(values, null, true, false);
15783            Binder.restoreCallingIdentity(origId);
15784        }
15785    }
15786
15787    public void updateConfiguration(Configuration values) {
15788        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15789                "updateConfiguration()");
15790
15791        synchronized(this) {
15792            if (values == null && mWindowManager != null) {
15793                // sentinel: fetch the current configuration from the window manager
15794                values = mWindowManager.computeNewConfiguration();
15795            }
15796
15797            if (mWindowManager != null) {
15798                mProcessList.applyDisplaySize(mWindowManager);
15799            }
15800
15801            final long origId = Binder.clearCallingIdentity();
15802            if (values != null) {
15803                Settings.System.clearConfiguration(values);
15804            }
15805            updateConfigurationLocked(values, null, false, false);
15806            Binder.restoreCallingIdentity(origId);
15807        }
15808    }
15809
15810    /**
15811     * Do either or both things: (1) change the current configuration, and (2)
15812     * make sure the given activity is running with the (now) current
15813     * configuration.  Returns true if the activity has been left running, or
15814     * false if <var>starting</var> is being destroyed to match the new
15815     * configuration.
15816     * @param persistent TODO
15817     */
15818    boolean updateConfigurationLocked(Configuration values,
15819            ActivityRecord starting, boolean persistent, boolean initLocale) {
15820        int changes = 0;
15821
15822        if (values != null) {
15823            Configuration newConfig = new Configuration(mConfiguration);
15824            changes = newConfig.updateFrom(values);
15825            if (changes != 0) {
15826                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15827                    Slog.i(TAG, "Updating configuration to: " + values);
15828                }
15829
15830                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15831
15832                if (values.locale != null && !initLocale) {
15833                    saveLocaleLocked(values.locale,
15834                                     !values.locale.equals(mConfiguration.locale),
15835                                     values.userSetLocale);
15836                }
15837
15838                mConfigurationSeq++;
15839                if (mConfigurationSeq <= 0) {
15840                    mConfigurationSeq = 1;
15841                }
15842                newConfig.seq = mConfigurationSeq;
15843                mConfiguration = newConfig;
15844                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15845                //mUsageStatsService.noteStartConfig(newConfig);
15846
15847                final Configuration configCopy = new Configuration(mConfiguration);
15848
15849                // TODO: If our config changes, should we auto dismiss any currently
15850                // showing dialogs?
15851                mShowDialogs = shouldShowDialogs(newConfig);
15852
15853                AttributeCache ac = AttributeCache.instance();
15854                if (ac != null) {
15855                    ac.updateConfiguration(configCopy);
15856                }
15857
15858                // Make sure all resources in our process are updated
15859                // right now, so that anyone who is going to retrieve
15860                // resource values after we return will be sure to get
15861                // the new ones.  This is especially important during
15862                // boot, where the first config change needs to guarantee
15863                // all resources have that config before following boot
15864                // code is executed.
15865                mSystemThread.applyConfigurationToResources(configCopy);
15866
15867                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15868                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15869                    msg.obj = new Configuration(configCopy);
15870                    mHandler.sendMessage(msg);
15871                }
15872
15873                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15874                    ProcessRecord app = mLruProcesses.get(i);
15875                    try {
15876                        if (app.thread != null) {
15877                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15878                                    + app.processName + " new config " + mConfiguration);
15879                            app.thread.scheduleConfigurationChanged(configCopy);
15880                        }
15881                    } catch (Exception e) {
15882                    }
15883                }
15884                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15885                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15886                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15887                        | Intent.FLAG_RECEIVER_FOREGROUND);
15888                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15889                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15890                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15891                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15892                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15893                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15894                    broadcastIntentLocked(null, null, intent,
15895                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15896                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15897                }
15898            }
15899        }
15900
15901        boolean kept = true;
15902        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15903        // mainStack is null during startup.
15904        if (mainStack != null) {
15905            if (changes != 0 && starting == null) {
15906                // If the configuration changed, and the caller is not already
15907                // in the process of starting an activity, then find the top
15908                // activity to check if its configuration needs to change.
15909                starting = mainStack.topRunningActivityLocked(null);
15910            }
15911
15912            if (starting != null) {
15913                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15914                // And we need to make sure at this point that all other activities
15915                // are made visible with the correct configuration.
15916                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15917            }
15918        }
15919
15920        if (values != null && mWindowManager != null) {
15921            mWindowManager.setNewConfiguration(mConfiguration);
15922        }
15923
15924        return kept;
15925    }
15926
15927    /**
15928     * Decide based on the configuration whether we should shouw the ANR,
15929     * crash, etc dialogs.  The idea is that if there is no affordnace to
15930     * press the on-screen buttons, we shouldn't show the dialog.
15931     *
15932     * A thought: SystemUI might also want to get told about this, the Power
15933     * dialog / global actions also might want different behaviors.
15934     */
15935    private static final boolean shouldShowDialogs(Configuration config) {
15936        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15937                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15938    }
15939
15940    /**
15941     * Save the locale.  You must be inside a synchronized (this) block.
15942     */
15943    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15944        if(isDiff) {
15945            SystemProperties.set("user.language", l.getLanguage());
15946            SystemProperties.set("user.region", l.getCountry());
15947        }
15948
15949        if(isPersist) {
15950            SystemProperties.set("persist.sys.language", l.getLanguage());
15951            SystemProperties.set("persist.sys.country", l.getCountry());
15952            SystemProperties.set("persist.sys.localevar", l.getVariant());
15953        }
15954    }
15955
15956    @Override
15957    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
15958        synchronized (this) {
15959            ActivityRecord srec = ActivityRecord.forToken(token);
15960            if (srec.task != null && srec.task.stack != null) {
15961                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
15962            }
15963        }
15964        return false;
15965    }
15966
15967    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15968            Intent resultData) {
15969
15970        synchronized (this) {
15971            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15972            if (stack != null) {
15973                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15974            }
15975            return false;
15976        }
15977    }
15978
15979    public int getLaunchedFromUid(IBinder activityToken) {
15980        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15981        if (srec == null) {
15982            return -1;
15983        }
15984        return srec.launchedFromUid;
15985    }
15986
15987    public String getLaunchedFromPackage(IBinder activityToken) {
15988        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15989        if (srec == null) {
15990            return null;
15991        }
15992        return srec.launchedFromPackage;
15993    }
15994
15995    // =========================================================
15996    // LIFETIME MANAGEMENT
15997    // =========================================================
15998
15999    // Returns which broadcast queue the app is the current [or imminent] receiver
16000    // on, or 'null' if the app is not an active broadcast recipient.
16001    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16002        BroadcastRecord r = app.curReceiver;
16003        if (r != null) {
16004            return r.queue;
16005        }
16006
16007        // It's not the current receiver, but it might be starting up to become one
16008        synchronized (this) {
16009            for (BroadcastQueue queue : mBroadcastQueues) {
16010                r = queue.mPendingBroadcast;
16011                if (r != null && r.curApp == app) {
16012                    // found it; report which queue it's in
16013                    return queue;
16014                }
16015            }
16016        }
16017
16018        return null;
16019    }
16020
16021    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16022            boolean doingAll, long now) {
16023        if (mAdjSeq == app.adjSeq) {
16024            // This adjustment has already been computed.
16025            return app.curRawAdj;
16026        }
16027
16028        if (app.thread == null) {
16029            app.adjSeq = mAdjSeq;
16030            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16031            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16032            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16033        }
16034
16035        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16036        app.adjSource = null;
16037        app.adjTarget = null;
16038        app.empty = false;
16039        app.cached = false;
16040
16041        final int activitiesSize = app.activities.size();
16042
16043        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16044            // The max adjustment doesn't allow this app to be anything
16045            // below foreground, so it is not worth doing work for it.
16046            app.adjType = "fixed";
16047            app.adjSeq = mAdjSeq;
16048            app.curRawAdj = app.maxAdj;
16049            app.foregroundActivities = false;
16050            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16051            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16052            // System processes can do UI, and when they do we want to have
16053            // them trim their memory after the user leaves the UI.  To
16054            // facilitate this, here we need to determine whether or not it
16055            // is currently showing UI.
16056            app.systemNoUi = true;
16057            if (app == TOP_APP) {
16058                app.systemNoUi = false;
16059            } else if (activitiesSize > 0) {
16060                for (int j = 0; j < activitiesSize; j++) {
16061                    final ActivityRecord r = app.activities.get(j);
16062                    if (r.visible) {
16063                        app.systemNoUi = false;
16064                    }
16065                }
16066            }
16067            if (!app.systemNoUi) {
16068                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16069            }
16070            return (app.curAdj=app.maxAdj);
16071        }
16072
16073        app.systemNoUi = false;
16074
16075        // Determine the importance of the process, starting with most
16076        // important to least, and assign an appropriate OOM adjustment.
16077        int adj;
16078        int schedGroup;
16079        int procState;
16080        boolean foregroundActivities = false;
16081        BroadcastQueue queue;
16082        if (app == TOP_APP) {
16083            // The last app on the list is the foreground app.
16084            adj = ProcessList.FOREGROUND_APP_ADJ;
16085            schedGroup = Process.THREAD_GROUP_DEFAULT;
16086            app.adjType = "top-activity";
16087            foregroundActivities = true;
16088            procState = ActivityManager.PROCESS_STATE_TOP;
16089        } else if (app.instrumentationClass != null) {
16090            // Don't want to kill running instrumentation.
16091            adj = ProcessList.FOREGROUND_APP_ADJ;
16092            schedGroup = Process.THREAD_GROUP_DEFAULT;
16093            app.adjType = "instrumentation";
16094            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16095        } else if ((queue = isReceivingBroadcast(app)) != null) {
16096            // An app that is currently receiving a broadcast also
16097            // counts as being in the foreground for OOM killer purposes.
16098            // It's placed in a sched group based on the nature of the
16099            // broadcast as reflected by which queue it's active in.
16100            adj = ProcessList.FOREGROUND_APP_ADJ;
16101            schedGroup = (queue == mFgBroadcastQueue)
16102                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16103            app.adjType = "broadcast";
16104            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16105        } else if (app.executingServices.size() > 0) {
16106            // An app that is currently executing a service callback also
16107            // counts as being in the foreground.
16108            adj = ProcessList.FOREGROUND_APP_ADJ;
16109            schedGroup = app.execServicesFg ?
16110                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16111            app.adjType = "exec-service";
16112            procState = ActivityManager.PROCESS_STATE_SERVICE;
16113            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16114        } else {
16115            // As far as we know the process is empty.  We may change our mind later.
16116            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16117            // At this point we don't actually know the adjustment.  Use the cached adj
16118            // value that the caller wants us to.
16119            adj = cachedAdj;
16120            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16121            app.cached = true;
16122            app.empty = true;
16123            app.adjType = "cch-empty";
16124        }
16125
16126        // Examine all activities if not already foreground.
16127        if (!foregroundActivities && activitiesSize > 0) {
16128            for (int j = 0; j < activitiesSize; j++) {
16129                final ActivityRecord r = app.activities.get(j);
16130                if (r.app != app) {
16131                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16132                            + app + "?!?");
16133                    continue;
16134                }
16135                if (r.visible) {
16136                    // App has a visible activity; only upgrade adjustment.
16137                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16138                        adj = ProcessList.VISIBLE_APP_ADJ;
16139                        app.adjType = "visible";
16140                    }
16141                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16142                        procState = ActivityManager.PROCESS_STATE_TOP;
16143                    }
16144                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16145                    app.cached = false;
16146                    app.empty = false;
16147                    foregroundActivities = true;
16148                    break;
16149                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16150                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16151                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16152                        app.adjType = "pausing";
16153                    }
16154                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16155                        procState = ActivityManager.PROCESS_STATE_TOP;
16156                    }
16157                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16158                    app.cached = false;
16159                    app.empty = false;
16160                    foregroundActivities = true;
16161                } else if (r.state == ActivityState.STOPPING) {
16162                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16163                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16164                        app.adjType = "stopping";
16165                    }
16166                    // For the process state, we will at this point consider the
16167                    // process to be cached.  It will be cached either as an activity
16168                    // or empty depending on whether the activity is finishing.  We do
16169                    // this so that we can treat the process as cached for purposes of
16170                    // memory trimming (determing current memory level, trim command to
16171                    // send to process) since there can be an arbitrary number of stopping
16172                    // processes and they should soon all go into the cached state.
16173                    if (!r.finishing) {
16174                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16175                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16176                        }
16177                    }
16178                    app.cached = false;
16179                    app.empty = false;
16180                    foregroundActivities = true;
16181                } else {
16182                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16183                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16184                        app.adjType = "cch-act";
16185                    }
16186                }
16187            }
16188        }
16189
16190        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16191            if (app.foregroundServices) {
16192                // The user is aware of this app, so make it visible.
16193                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16194                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16195                app.cached = false;
16196                app.adjType = "fg-service";
16197                schedGroup = Process.THREAD_GROUP_DEFAULT;
16198            } else if (app.forcingToForeground != null) {
16199                // The user is aware of this app, so make it visible.
16200                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16201                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16202                app.cached = false;
16203                app.adjType = "force-fg";
16204                app.adjSource = app.forcingToForeground;
16205                schedGroup = Process.THREAD_GROUP_DEFAULT;
16206            }
16207        }
16208
16209        if (app == mHeavyWeightProcess) {
16210            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16211                // We don't want to kill the current heavy-weight process.
16212                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16213                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16214                app.cached = false;
16215                app.adjType = "heavy";
16216            }
16217            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16218                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16219            }
16220        }
16221
16222        if (app == mHomeProcess) {
16223            if (adj > ProcessList.HOME_APP_ADJ) {
16224                // This process is hosting what we currently consider to be the
16225                // home app, so we don't want to let it go into the background.
16226                adj = ProcessList.HOME_APP_ADJ;
16227                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16228                app.cached = false;
16229                app.adjType = "home";
16230            }
16231            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16232                procState = ActivityManager.PROCESS_STATE_HOME;
16233            }
16234        }
16235
16236        if (app == mPreviousProcess && app.activities.size() > 0) {
16237            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16238                // This was the previous process that showed UI to the user.
16239                // We want to try to keep it around more aggressively, to give
16240                // a good experience around switching between two apps.
16241                adj = ProcessList.PREVIOUS_APP_ADJ;
16242                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16243                app.cached = false;
16244                app.adjType = "previous";
16245            }
16246            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16247                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16248            }
16249        }
16250
16251        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16252                + " reason=" + app.adjType);
16253
16254        // By default, we use the computed adjustment.  It may be changed if
16255        // there are applications dependent on our services or providers, but
16256        // this gives us a baseline and makes sure we don't get into an
16257        // infinite recursion.
16258        app.adjSeq = mAdjSeq;
16259        app.curRawAdj = adj;
16260        app.hasStartedServices = false;
16261
16262        if (mBackupTarget != null && app == mBackupTarget.app) {
16263            // If possible we want to avoid killing apps while they're being backed up
16264            if (adj > ProcessList.BACKUP_APP_ADJ) {
16265                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16266                adj = ProcessList.BACKUP_APP_ADJ;
16267                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16268                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16269                }
16270                app.adjType = "backup";
16271                app.cached = false;
16272            }
16273            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16274                procState = ActivityManager.PROCESS_STATE_BACKUP;
16275            }
16276        }
16277
16278        boolean mayBeTop = false;
16279
16280        for (int is = app.services.size()-1;
16281                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16282                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16283                        || procState > ActivityManager.PROCESS_STATE_TOP);
16284                is--) {
16285            ServiceRecord s = app.services.valueAt(is);
16286            if (s.startRequested) {
16287                app.hasStartedServices = true;
16288                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16289                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16290                }
16291                if (app.hasShownUi && app != mHomeProcess) {
16292                    // If this process has shown some UI, let it immediately
16293                    // go to the LRU list because it may be pretty heavy with
16294                    // UI stuff.  We'll tag it with a label just to help
16295                    // debug and understand what is going on.
16296                    if (adj > ProcessList.SERVICE_ADJ) {
16297                        app.adjType = "cch-started-ui-services";
16298                    }
16299                } else {
16300                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16301                        // This service has seen some activity within
16302                        // recent memory, so we will keep its process ahead
16303                        // of the background processes.
16304                        if (adj > ProcessList.SERVICE_ADJ) {
16305                            adj = ProcessList.SERVICE_ADJ;
16306                            app.adjType = "started-services";
16307                            app.cached = false;
16308                        }
16309                    }
16310                    // If we have let the service slide into the background
16311                    // state, still have some text describing what it is doing
16312                    // even though the service no longer has an impact.
16313                    if (adj > ProcessList.SERVICE_ADJ) {
16314                        app.adjType = "cch-started-services";
16315                    }
16316                }
16317            }
16318            for (int conni = s.connections.size()-1;
16319                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16320                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16321                            || procState > ActivityManager.PROCESS_STATE_TOP);
16322                    conni--) {
16323                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16324                for (int i = 0;
16325                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16326                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16327                                || procState > ActivityManager.PROCESS_STATE_TOP);
16328                        i++) {
16329                    // XXX should compute this based on the max of
16330                    // all connected clients.
16331                    ConnectionRecord cr = clist.get(i);
16332                    if (cr.binding.client == app) {
16333                        // Binding to ourself is not interesting.
16334                        continue;
16335                    }
16336                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16337                        ProcessRecord client = cr.binding.client;
16338                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16339                                TOP_APP, doingAll, now);
16340                        int clientProcState = client.curProcState;
16341                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16342                            // If the other app is cached for any reason, for purposes here
16343                            // we are going to consider it empty.  The specific cached state
16344                            // doesn't propagate except under certain conditions.
16345                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16346                        }
16347                        String adjType = null;
16348                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16349                            // Not doing bind OOM management, so treat
16350                            // this guy more like a started service.
16351                            if (app.hasShownUi && app != mHomeProcess) {
16352                                // If this process has shown some UI, let it immediately
16353                                // go to the LRU list because it may be pretty heavy with
16354                                // UI stuff.  We'll tag it with a label just to help
16355                                // debug and understand what is going on.
16356                                if (adj > clientAdj) {
16357                                    adjType = "cch-bound-ui-services";
16358                                }
16359                                app.cached = false;
16360                                clientAdj = adj;
16361                                clientProcState = procState;
16362                            } else {
16363                                if (now >= (s.lastActivity
16364                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16365                                    // This service has not seen activity within
16366                                    // recent memory, so allow it to drop to the
16367                                    // LRU list if there is no other reason to keep
16368                                    // it around.  We'll also tag it with a label just
16369                                    // to help debug and undertand what is going on.
16370                                    if (adj > clientAdj) {
16371                                        adjType = "cch-bound-services";
16372                                    }
16373                                    clientAdj = adj;
16374                                }
16375                            }
16376                        }
16377                        if (adj > clientAdj) {
16378                            // If this process has recently shown UI, and
16379                            // the process that is binding to it is less
16380                            // important than being visible, then we don't
16381                            // care about the binding as much as we care
16382                            // about letting this process get into the LRU
16383                            // list to be killed and restarted if needed for
16384                            // memory.
16385                            if (app.hasShownUi && app != mHomeProcess
16386                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16387                                adjType = "cch-bound-ui-services";
16388                            } else {
16389                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16390                                        |Context.BIND_IMPORTANT)) != 0) {
16391                                    adj = clientAdj;
16392                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16393                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16394                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16395                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16396                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16397                                    adj = clientAdj;
16398                                } else {
16399                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16400                                        adj = ProcessList.VISIBLE_APP_ADJ;
16401                                    }
16402                                }
16403                                if (!client.cached) {
16404                                    app.cached = false;
16405                                }
16406                                adjType = "service";
16407                            }
16408                        }
16409                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16410                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16411                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16412                            }
16413                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16414                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16415                                    // Special handling of clients who are in the top state.
16416                                    // We *may* want to consider this process to be in the
16417                                    // top state as well, but only if there is not another
16418                                    // reason for it to be running.  Being on the top is a
16419                                    // special state, meaning you are specifically running
16420                                    // for the current top app.  If the process is already
16421                                    // running in the background for some other reason, it
16422                                    // is more important to continue considering it to be
16423                                    // in the background state.
16424                                    mayBeTop = true;
16425                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16426                                } else {
16427                                    // Special handling for above-top states (persistent
16428                                    // processes).  These should not bring the current process
16429                                    // into the top state, since they are not on top.  Instead
16430                                    // give them the best state after that.
16431                                    clientProcState =
16432                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16433                                }
16434                            }
16435                        } else {
16436                            if (clientProcState <
16437                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16438                                clientProcState =
16439                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16440                            }
16441                        }
16442                        if (procState > clientProcState) {
16443                            procState = clientProcState;
16444                        }
16445                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16446                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16447                            app.pendingUiClean = true;
16448                        }
16449                        if (adjType != null) {
16450                            app.adjType = adjType;
16451                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16452                                    .REASON_SERVICE_IN_USE;
16453                            app.adjSource = cr.binding.client;
16454                            app.adjSourceProcState = clientProcState;
16455                            app.adjTarget = s.name;
16456                        }
16457                    }
16458                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16459                        app.treatLikeActivity = true;
16460                    }
16461                    final ActivityRecord a = cr.activity;
16462                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16463                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16464                                (a.visible || a.state == ActivityState.RESUMED
16465                                 || a.state == ActivityState.PAUSING)) {
16466                            adj = ProcessList.FOREGROUND_APP_ADJ;
16467                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16468                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16469                            }
16470                            app.cached = false;
16471                            app.adjType = "service";
16472                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16473                                    .REASON_SERVICE_IN_USE;
16474                            app.adjSource = a;
16475                            app.adjSourceProcState = procState;
16476                            app.adjTarget = s.name;
16477                        }
16478                    }
16479                }
16480            }
16481        }
16482
16483        for (int provi = app.pubProviders.size()-1;
16484                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16485                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16486                        || procState > ActivityManager.PROCESS_STATE_TOP);
16487                provi--) {
16488            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16489            for (int i = cpr.connections.size()-1;
16490                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16491                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16492                            || procState > ActivityManager.PROCESS_STATE_TOP);
16493                    i--) {
16494                ContentProviderConnection conn = cpr.connections.get(i);
16495                ProcessRecord client = conn.client;
16496                if (client == app) {
16497                    // Being our own client is not interesting.
16498                    continue;
16499                }
16500                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16501                int clientProcState = client.curProcState;
16502                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16503                    // If the other app is cached for any reason, for purposes here
16504                    // we are going to consider it empty.
16505                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16506                }
16507                if (adj > clientAdj) {
16508                    if (app.hasShownUi && app != mHomeProcess
16509                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16510                        app.adjType = "cch-ui-provider";
16511                    } else {
16512                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16513                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16514                        app.adjType = "provider";
16515                    }
16516                    app.cached &= client.cached;
16517                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16518                            .REASON_PROVIDER_IN_USE;
16519                    app.adjSource = client;
16520                    app.adjSourceProcState = clientProcState;
16521                    app.adjTarget = cpr.name;
16522                }
16523                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16524                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16525                        // Special handling of clients who are in the top state.
16526                        // We *may* want to consider this process to be in the
16527                        // top state as well, but only if there is not another
16528                        // reason for it to be running.  Being on the top is a
16529                        // special state, meaning you are specifically running
16530                        // for the current top app.  If the process is already
16531                        // running in the background for some other reason, it
16532                        // is more important to continue considering it to be
16533                        // in the background state.
16534                        mayBeTop = true;
16535                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16536                    } else {
16537                        // Special handling for above-top states (persistent
16538                        // processes).  These should not bring the current process
16539                        // into the top state, since they are not on top.  Instead
16540                        // give them the best state after that.
16541                        clientProcState =
16542                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16543                    }
16544                }
16545                if (procState > clientProcState) {
16546                    procState = clientProcState;
16547                }
16548                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16549                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16550                }
16551            }
16552            // If the provider has external (non-framework) process
16553            // dependencies, ensure that its adjustment is at least
16554            // FOREGROUND_APP_ADJ.
16555            if (cpr.hasExternalProcessHandles()) {
16556                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16557                    adj = ProcessList.FOREGROUND_APP_ADJ;
16558                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16559                    app.cached = false;
16560                    app.adjType = "provider";
16561                    app.adjTarget = cpr.name;
16562                }
16563                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16564                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16565                }
16566            }
16567        }
16568
16569        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16570            // A client of one of our services or providers is in the top state.  We
16571            // *may* want to be in the top state, but not if we are already running in
16572            // the background for some other reason.  For the decision here, we are going
16573            // to pick out a few specific states that we want to remain in when a client
16574            // is top (states that tend to be longer-term) and otherwise allow it to go
16575            // to the top state.
16576            switch (procState) {
16577                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16578                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16579                case ActivityManager.PROCESS_STATE_SERVICE:
16580                    // These all are longer-term states, so pull them up to the top
16581                    // of the background states, but not all the way to the top state.
16582                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16583                    break;
16584                default:
16585                    // Otherwise, top is a better choice, so take it.
16586                    procState = ActivityManager.PROCESS_STATE_TOP;
16587                    break;
16588            }
16589        }
16590
16591        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16592            if (app.hasClientActivities) {
16593                // This is a cached process, but with client activities.  Mark it so.
16594                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16595                app.adjType = "cch-client-act";
16596            } else if (app.treatLikeActivity) {
16597                // This is a cached process, but somebody wants us to treat it like it has
16598                // an activity, okay!
16599                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16600                app.adjType = "cch-as-act";
16601            }
16602        }
16603
16604        if (adj == ProcessList.SERVICE_ADJ) {
16605            if (doingAll) {
16606                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16607                mNewNumServiceProcs++;
16608                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16609                if (!app.serviceb) {
16610                    // This service isn't far enough down on the LRU list to
16611                    // normally be a B service, but if we are low on RAM and it
16612                    // is large we want to force it down since we would prefer to
16613                    // keep launcher over it.
16614                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16615                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16616                        app.serviceHighRam = true;
16617                        app.serviceb = true;
16618                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16619                    } else {
16620                        mNewNumAServiceProcs++;
16621                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16622                    }
16623                } else {
16624                    app.serviceHighRam = false;
16625                }
16626            }
16627            if (app.serviceb) {
16628                adj = ProcessList.SERVICE_B_ADJ;
16629            }
16630        }
16631
16632        app.curRawAdj = adj;
16633
16634        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16635        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16636        if (adj > app.maxAdj) {
16637            adj = app.maxAdj;
16638            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16639                schedGroup = Process.THREAD_GROUP_DEFAULT;
16640            }
16641        }
16642
16643        // Do final modification to adj.  Everything we do between here and applying
16644        // the final setAdj must be done in this function, because we will also use
16645        // it when computing the final cached adj later.  Note that we don't need to
16646        // worry about this for max adj above, since max adj will always be used to
16647        // keep it out of the cached vaues.
16648        app.curAdj = app.modifyRawOomAdj(adj);
16649        app.curSchedGroup = schedGroup;
16650        app.curProcState = procState;
16651        app.foregroundActivities = foregroundActivities;
16652
16653        return app.curRawAdj;
16654    }
16655
16656    /**
16657     * Schedule PSS collection of a process.
16658     */
16659    void requestPssLocked(ProcessRecord proc, int procState) {
16660        if (mPendingPssProcesses.contains(proc)) {
16661            return;
16662        }
16663        if (mPendingPssProcesses.size() == 0) {
16664            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16665        }
16666        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16667        proc.pssProcState = procState;
16668        mPendingPssProcesses.add(proc);
16669    }
16670
16671    /**
16672     * Schedule PSS collection of all processes.
16673     */
16674    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16675        if (!always) {
16676            if (now < (mLastFullPssTime +
16677                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16678                return;
16679            }
16680        }
16681        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16682        mLastFullPssTime = now;
16683        mFullPssPending = true;
16684        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16685        mPendingPssProcesses.clear();
16686        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16687            ProcessRecord app = mLruProcesses.get(i);
16688            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16689                app.pssProcState = app.setProcState;
16690                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16691                        isSleeping(), now);
16692                mPendingPssProcesses.add(app);
16693            }
16694        }
16695        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16696    }
16697
16698    /**
16699     * Ask a given process to GC right now.
16700     */
16701    final void performAppGcLocked(ProcessRecord app) {
16702        try {
16703            app.lastRequestedGc = SystemClock.uptimeMillis();
16704            if (app.thread != null) {
16705                if (app.reportLowMemory) {
16706                    app.reportLowMemory = false;
16707                    app.thread.scheduleLowMemory();
16708                } else {
16709                    app.thread.processInBackground();
16710                }
16711            }
16712        } catch (Exception e) {
16713            // whatever.
16714        }
16715    }
16716
16717    /**
16718     * Returns true if things are idle enough to perform GCs.
16719     */
16720    private final boolean canGcNowLocked() {
16721        boolean processingBroadcasts = false;
16722        for (BroadcastQueue q : mBroadcastQueues) {
16723            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16724                processingBroadcasts = true;
16725            }
16726        }
16727        return !processingBroadcasts
16728                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16729    }
16730
16731    /**
16732     * Perform GCs on all processes that are waiting for it, but only
16733     * if things are idle.
16734     */
16735    final void performAppGcsLocked() {
16736        final int N = mProcessesToGc.size();
16737        if (N <= 0) {
16738            return;
16739        }
16740        if (canGcNowLocked()) {
16741            while (mProcessesToGc.size() > 0) {
16742                ProcessRecord proc = mProcessesToGc.remove(0);
16743                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16744                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16745                            <= SystemClock.uptimeMillis()) {
16746                        // To avoid spamming the system, we will GC processes one
16747                        // at a time, waiting a few seconds between each.
16748                        performAppGcLocked(proc);
16749                        scheduleAppGcsLocked();
16750                        return;
16751                    } else {
16752                        // It hasn't been long enough since we last GCed this
16753                        // process...  put it in the list to wait for its time.
16754                        addProcessToGcListLocked(proc);
16755                        break;
16756                    }
16757                }
16758            }
16759
16760            scheduleAppGcsLocked();
16761        }
16762    }
16763
16764    /**
16765     * If all looks good, perform GCs on all processes waiting for them.
16766     */
16767    final void performAppGcsIfAppropriateLocked() {
16768        if (canGcNowLocked()) {
16769            performAppGcsLocked();
16770            return;
16771        }
16772        // Still not idle, wait some more.
16773        scheduleAppGcsLocked();
16774    }
16775
16776    /**
16777     * Schedule the execution of all pending app GCs.
16778     */
16779    final void scheduleAppGcsLocked() {
16780        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16781
16782        if (mProcessesToGc.size() > 0) {
16783            // Schedule a GC for the time to the next process.
16784            ProcessRecord proc = mProcessesToGc.get(0);
16785            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16786
16787            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16788            long now = SystemClock.uptimeMillis();
16789            if (when < (now+GC_TIMEOUT)) {
16790                when = now + GC_TIMEOUT;
16791            }
16792            mHandler.sendMessageAtTime(msg, when);
16793        }
16794    }
16795
16796    /**
16797     * Add a process to the array of processes waiting to be GCed.  Keeps the
16798     * list in sorted order by the last GC time.  The process can't already be
16799     * on the list.
16800     */
16801    final void addProcessToGcListLocked(ProcessRecord proc) {
16802        boolean added = false;
16803        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16804            if (mProcessesToGc.get(i).lastRequestedGc <
16805                    proc.lastRequestedGc) {
16806                added = true;
16807                mProcessesToGc.add(i+1, proc);
16808                break;
16809            }
16810        }
16811        if (!added) {
16812            mProcessesToGc.add(0, proc);
16813        }
16814    }
16815
16816    /**
16817     * Set up to ask a process to GC itself.  This will either do it
16818     * immediately, or put it on the list of processes to gc the next
16819     * time things are idle.
16820     */
16821    final void scheduleAppGcLocked(ProcessRecord app) {
16822        long now = SystemClock.uptimeMillis();
16823        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16824            return;
16825        }
16826        if (!mProcessesToGc.contains(app)) {
16827            addProcessToGcListLocked(app);
16828            scheduleAppGcsLocked();
16829        }
16830    }
16831
16832    final void checkExcessivePowerUsageLocked(boolean doKills) {
16833        updateCpuStatsNow();
16834
16835        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16836        boolean doWakeKills = doKills;
16837        boolean doCpuKills = doKills;
16838        if (mLastPowerCheckRealtime == 0) {
16839            doWakeKills = false;
16840        }
16841        if (mLastPowerCheckUptime == 0) {
16842            doCpuKills = false;
16843        }
16844        if (stats.isScreenOn()) {
16845            doWakeKills = false;
16846        }
16847        final long curRealtime = SystemClock.elapsedRealtime();
16848        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16849        final long curUptime = SystemClock.uptimeMillis();
16850        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16851        mLastPowerCheckRealtime = curRealtime;
16852        mLastPowerCheckUptime = curUptime;
16853        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16854            doWakeKills = false;
16855        }
16856        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16857            doCpuKills = false;
16858        }
16859        int i = mLruProcesses.size();
16860        while (i > 0) {
16861            i--;
16862            ProcessRecord app = mLruProcesses.get(i);
16863            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16864                long wtime;
16865                synchronized (stats) {
16866                    wtime = stats.getProcessWakeTime(app.info.uid,
16867                            app.pid, curRealtime);
16868                }
16869                long wtimeUsed = wtime - app.lastWakeTime;
16870                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16871                if (DEBUG_POWER) {
16872                    StringBuilder sb = new StringBuilder(128);
16873                    sb.append("Wake for ");
16874                    app.toShortString(sb);
16875                    sb.append(": over ");
16876                    TimeUtils.formatDuration(realtimeSince, sb);
16877                    sb.append(" used ");
16878                    TimeUtils.formatDuration(wtimeUsed, sb);
16879                    sb.append(" (");
16880                    sb.append((wtimeUsed*100)/realtimeSince);
16881                    sb.append("%)");
16882                    Slog.i(TAG, sb.toString());
16883                    sb.setLength(0);
16884                    sb.append("CPU for ");
16885                    app.toShortString(sb);
16886                    sb.append(": over ");
16887                    TimeUtils.formatDuration(uptimeSince, sb);
16888                    sb.append(" used ");
16889                    TimeUtils.formatDuration(cputimeUsed, sb);
16890                    sb.append(" (");
16891                    sb.append((cputimeUsed*100)/uptimeSince);
16892                    sb.append("%)");
16893                    Slog.i(TAG, sb.toString());
16894                }
16895                // If a process has held a wake lock for more
16896                // than 50% of the time during this period,
16897                // that sounds bad.  Kill!
16898                if (doWakeKills && realtimeSince > 0
16899                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16900                    synchronized (stats) {
16901                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16902                                realtimeSince, wtimeUsed);
16903                    }
16904                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16905                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16906                } else if (doCpuKills && uptimeSince > 0
16907                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16908                    synchronized (stats) {
16909                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16910                                uptimeSince, cputimeUsed);
16911                    }
16912                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16913                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16914                } else {
16915                    app.lastWakeTime = wtime;
16916                    app.lastCpuTime = app.curCpuTime;
16917                }
16918            }
16919        }
16920    }
16921
16922    private final boolean applyOomAdjLocked(ProcessRecord app,
16923            ProcessRecord TOP_APP, boolean doingAll, long now) {
16924        boolean success = true;
16925
16926        if (app.curRawAdj != app.setRawAdj) {
16927            app.setRawAdj = app.curRawAdj;
16928        }
16929
16930        int changes = 0;
16931
16932        if (app.curAdj != app.setAdj) {
16933            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16934            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16935                TAG, "Set " + app.pid + " " + app.processName +
16936                " adj " + app.curAdj + ": " + app.adjType);
16937            app.setAdj = app.curAdj;
16938        }
16939
16940        if (app.setSchedGroup != app.curSchedGroup) {
16941            app.setSchedGroup = app.curSchedGroup;
16942            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16943                    "Setting process group of " + app.processName
16944                    + " to " + app.curSchedGroup);
16945            if (app.waitingToKill != null &&
16946                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16947                app.kill(app.waitingToKill, true);
16948                success = false;
16949            } else {
16950                if (true) {
16951                    long oldId = Binder.clearCallingIdentity();
16952                    try {
16953                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16954                    } catch (Exception e) {
16955                        Slog.w(TAG, "Failed setting process group of " + app.pid
16956                                + " to " + app.curSchedGroup);
16957                        e.printStackTrace();
16958                    } finally {
16959                        Binder.restoreCallingIdentity(oldId);
16960                    }
16961                } else {
16962                    if (app.thread != null) {
16963                        try {
16964                            app.thread.setSchedulingGroup(app.curSchedGroup);
16965                        } catch (RemoteException e) {
16966                        }
16967                    }
16968                }
16969                Process.setSwappiness(app.pid,
16970                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16971            }
16972        }
16973        if (app.repForegroundActivities != app.foregroundActivities) {
16974            app.repForegroundActivities = app.foregroundActivities;
16975            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16976        }
16977        if (app.repProcState != app.curProcState) {
16978            app.repProcState = app.curProcState;
16979            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16980            if (app.thread != null) {
16981                try {
16982                    if (false) {
16983                        //RuntimeException h = new RuntimeException("here");
16984                        Slog.i(TAG, "Sending new process state " + app.repProcState
16985                                + " to " + app /*, h*/);
16986                    }
16987                    app.thread.setProcessState(app.repProcState);
16988                } catch (RemoteException e) {
16989                }
16990            }
16991        }
16992        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16993                app.setProcState)) {
16994            app.lastStateTime = now;
16995            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16996                    isSleeping(), now);
16997            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16998                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16999                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17000                    + (app.nextPssTime-now) + ": " + app);
17001        } else {
17002            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17003                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17004                requestPssLocked(app, app.setProcState);
17005                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17006                        isSleeping(), now);
17007            } else if (false && DEBUG_PSS) {
17008                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17009            }
17010        }
17011        if (app.setProcState != app.curProcState) {
17012            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17013                    "Proc state change of " + app.processName
17014                    + " to " + app.curProcState);
17015            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17016            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17017            if (setImportant && !curImportant) {
17018                // This app is no longer something we consider important enough to allow to
17019                // use arbitrary amounts of battery power.  Note
17020                // its current wake lock time to later know to kill it if
17021                // it is not behaving well.
17022                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17023                synchronized (stats) {
17024                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17025                            app.pid, SystemClock.elapsedRealtime());
17026                }
17027                app.lastCpuTime = app.curCpuTime;
17028
17029            }
17030            app.setProcState = app.curProcState;
17031            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17032                app.notCachedSinceIdle = false;
17033            }
17034            if (!doingAll) {
17035                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17036            } else {
17037                app.procStateChanged = true;
17038            }
17039        }
17040
17041        if (changes != 0) {
17042            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17043            int i = mPendingProcessChanges.size()-1;
17044            ProcessChangeItem item = null;
17045            while (i >= 0) {
17046                item = mPendingProcessChanges.get(i);
17047                if (item.pid == app.pid) {
17048                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17049                    break;
17050                }
17051                i--;
17052            }
17053            if (i < 0) {
17054                // No existing item in pending changes; need a new one.
17055                final int NA = mAvailProcessChanges.size();
17056                if (NA > 0) {
17057                    item = mAvailProcessChanges.remove(NA-1);
17058                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17059                } else {
17060                    item = new ProcessChangeItem();
17061                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17062                }
17063                item.changes = 0;
17064                item.pid = app.pid;
17065                item.uid = app.info.uid;
17066                if (mPendingProcessChanges.size() == 0) {
17067                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17068                            "*** Enqueueing dispatch processes changed!");
17069                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17070                }
17071                mPendingProcessChanges.add(item);
17072            }
17073            item.changes |= changes;
17074            item.processState = app.repProcState;
17075            item.foregroundActivities = app.repForegroundActivities;
17076            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17077                    + Integer.toHexString(System.identityHashCode(item))
17078                    + " " + app.toShortString() + ": changes=" + item.changes
17079                    + " procState=" + item.processState
17080                    + " foreground=" + item.foregroundActivities
17081                    + " type=" + app.adjType + " source=" + app.adjSource
17082                    + " target=" + app.adjTarget);
17083        }
17084
17085        return success;
17086    }
17087
17088    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17089        if (proc.thread != null) {
17090            if (proc.baseProcessTracker != null) {
17091                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17092            }
17093            if (proc.repProcState >= 0) {
17094                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17095                        proc.repProcState);
17096            }
17097        }
17098    }
17099
17100    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17101            ProcessRecord TOP_APP, boolean doingAll, long now) {
17102        if (app.thread == null) {
17103            return false;
17104        }
17105
17106        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17107
17108        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17109    }
17110
17111    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17112            boolean oomAdj) {
17113        if (isForeground != proc.foregroundServices) {
17114            proc.foregroundServices = isForeground;
17115            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17116                    proc.info.uid);
17117            if (isForeground) {
17118                if (curProcs == null) {
17119                    curProcs = new ArrayList<ProcessRecord>();
17120                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17121                }
17122                if (!curProcs.contains(proc)) {
17123                    curProcs.add(proc);
17124                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17125                            proc.info.packageName, proc.info.uid);
17126                }
17127            } else {
17128                if (curProcs != null) {
17129                    if (curProcs.remove(proc)) {
17130                        mBatteryStatsService.noteEvent(
17131                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17132                                proc.info.packageName, proc.info.uid);
17133                        if (curProcs.size() <= 0) {
17134                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17135                        }
17136                    }
17137                }
17138            }
17139            if (oomAdj) {
17140                updateOomAdjLocked();
17141            }
17142        }
17143    }
17144
17145    private final ActivityRecord resumedAppLocked() {
17146        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17147        String pkg;
17148        int uid;
17149        if (act != null) {
17150            pkg = act.packageName;
17151            uid = act.info.applicationInfo.uid;
17152        } else {
17153            pkg = null;
17154            uid = -1;
17155        }
17156        // Has the UID or resumed package name changed?
17157        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17158                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17159            if (mCurResumedPackage != null) {
17160                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17161                        mCurResumedPackage, mCurResumedUid);
17162            }
17163            mCurResumedPackage = pkg;
17164            mCurResumedUid = uid;
17165            if (mCurResumedPackage != null) {
17166                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17167                        mCurResumedPackage, mCurResumedUid);
17168            }
17169        }
17170        return act;
17171    }
17172
17173    final boolean updateOomAdjLocked(ProcessRecord app) {
17174        final ActivityRecord TOP_ACT = resumedAppLocked();
17175        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17176        final boolean wasCached = app.cached;
17177
17178        mAdjSeq++;
17179
17180        // This is the desired cached adjusment we want to tell it to use.
17181        // If our app is currently cached, we know it, and that is it.  Otherwise,
17182        // we don't know it yet, and it needs to now be cached we will then
17183        // need to do a complete oom adj.
17184        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17185                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17186        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17187                SystemClock.uptimeMillis());
17188        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17189            // Changed to/from cached state, so apps after it in the LRU
17190            // list may also be changed.
17191            updateOomAdjLocked();
17192        }
17193        return success;
17194    }
17195
17196    final void updateOomAdjLocked() {
17197        final ActivityRecord TOP_ACT = resumedAppLocked();
17198        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17199        final long now = SystemClock.uptimeMillis();
17200        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17201        final int N = mLruProcesses.size();
17202
17203        if (false) {
17204            RuntimeException e = new RuntimeException();
17205            e.fillInStackTrace();
17206            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17207        }
17208
17209        mAdjSeq++;
17210        mNewNumServiceProcs = 0;
17211        mNewNumAServiceProcs = 0;
17212
17213        final int emptyProcessLimit;
17214        final int cachedProcessLimit;
17215        if (mProcessLimit <= 0) {
17216            emptyProcessLimit = cachedProcessLimit = 0;
17217        } else if (mProcessLimit == 1) {
17218            emptyProcessLimit = 1;
17219            cachedProcessLimit = 0;
17220        } else {
17221            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17222            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17223        }
17224
17225        // Let's determine how many processes we have running vs.
17226        // how many slots we have for background processes; we may want
17227        // to put multiple processes in a slot of there are enough of
17228        // them.
17229        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17230                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17231        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17232        if (numEmptyProcs > cachedProcessLimit) {
17233            // If there are more empty processes than our limit on cached
17234            // processes, then use the cached process limit for the factor.
17235            // This ensures that the really old empty processes get pushed
17236            // down to the bottom, so if we are running low on memory we will
17237            // have a better chance at keeping around more cached processes
17238            // instead of a gazillion empty processes.
17239            numEmptyProcs = cachedProcessLimit;
17240        }
17241        int emptyFactor = numEmptyProcs/numSlots;
17242        if (emptyFactor < 1) emptyFactor = 1;
17243        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17244        if (cachedFactor < 1) cachedFactor = 1;
17245        int stepCached = 0;
17246        int stepEmpty = 0;
17247        int numCached = 0;
17248        int numEmpty = 0;
17249        int numTrimming = 0;
17250
17251        mNumNonCachedProcs = 0;
17252        mNumCachedHiddenProcs = 0;
17253
17254        // First update the OOM adjustment for each of the
17255        // application processes based on their current state.
17256        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17257        int nextCachedAdj = curCachedAdj+1;
17258        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17259        int nextEmptyAdj = curEmptyAdj+2;
17260        for (int i=N-1; i>=0; i--) {
17261            ProcessRecord app = mLruProcesses.get(i);
17262            if (!app.killedByAm && app.thread != null) {
17263                app.procStateChanged = false;
17264                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17265
17266                // If we haven't yet assigned the final cached adj
17267                // to the process, do that now.
17268                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17269                    switch (app.curProcState) {
17270                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17271                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17272                            // This process is a cached process holding activities...
17273                            // assign it the next cached value for that type, and then
17274                            // step that cached level.
17275                            app.curRawAdj = curCachedAdj;
17276                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17277                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17278                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17279                                    + ")");
17280                            if (curCachedAdj != nextCachedAdj) {
17281                                stepCached++;
17282                                if (stepCached >= cachedFactor) {
17283                                    stepCached = 0;
17284                                    curCachedAdj = nextCachedAdj;
17285                                    nextCachedAdj += 2;
17286                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17287                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17288                                    }
17289                                }
17290                            }
17291                            break;
17292                        default:
17293                            // For everything else, assign next empty cached process
17294                            // level and bump that up.  Note that this means that
17295                            // long-running services that have dropped down to the
17296                            // cached level will be treated as empty (since their process
17297                            // state is still as a service), which is what we want.
17298                            app.curRawAdj = curEmptyAdj;
17299                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17300                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17301                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17302                                    + ")");
17303                            if (curEmptyAdj != nextEmptyAdj) {
17304                                stepEmpty++;
17305                                if (stepEmpty >= emptyFactor) {
17306                                    stepEmpty = 0;
17307                                    curEmptyAdj = nextEmptyAdj;
17308                                    nextEmptyAdj += 2;
17309                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17310                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17311                                    }
17312                                }
17313                            }
17314                            break;
17315                    }
17316                }
17317
17318                applyOomAdjLocked(app, TOP_APP, true, now);
17319
17320                // Count the number of process types.
17321                switch (app.curProcState) {
17322                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17323                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17324                        mNumCachedHiddenProcs++;
17325                        numCached++;
17326                        if (numCached > cachedProcessLimit) {
17327                            app.kill("cached #" + numCached, true);
17328                        }
17329                        break;
17330                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17331                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17332                                && app.lastActivityTime < oldTime) {
17333                            app.kill("empty for "
17334                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17335                                    / 1000) + "s", true);
17336                        } else {
17337                            numEmpty++;
17338                            if (numEmpty > emptyProcessLimit) {
17339                                app.kill("empty #" + numEmpty, true);
17340                            }
17341                        }
17342                        break;
17343                    default:
17344                        mNumNonCachedProcs++;
17345                        break;
17346                }
17347
17348                if (app.isolated && app.services.size() <= 0) {
17349                    // If this is an isolated process, and there are no
17350                    // services running in it, then the process is no longer
17351                    // needed.  We agressively kill these because we can by
17352                    // definition not re-use the same process again, and it is
17353                    // good to avoid having whatever code was running in them
17354                    // left sitting around after no longer needed.
17355                    app.kill("isolated not needed", true);
17356                }
17357
17358                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17359                        && !app.killedByAm) {
17360                    numTrimming++;
17361                }
17362            }
17363        }
17364
17365        mNumServiceProcs = mNewNumServiceProcs;
17366
17367        // Now determine the memory trimming level of background processes.
17368        // Unfortunately we need to start at the back of the list to do this
17369        // properly.  We only do this if the number of background apps we
17370        // are managing to keep around is less than half the maximum we desire;
17371        // if we are keeping a good number around, we'll let them use whatever
17372        // memory they want.
17373        final int numCachedAndEmpty = numCached + numEmpty;
17374        int memFactor;
17375        if (numCached <= ProcessList.TRIM_CACHED_APPS
17376                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17377            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17378                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17379            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17380                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17381            } else {
17382                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17383            }
17384        } else {
17385            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17386        }
17387        // We always allow the memory level to go up (better).  We only allow it to go
17388        // down if we are in a state where that is allowed, *and* the total number of processes
17389        // has gone down since last time.
17390        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17391                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17392                + " last=" + mLastNumProcesses);
17393        if (memFactor > mLastMemoryLevel) {
17394            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17395                memFactor = mLastMemoryLevel;
17396                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17397            }
17398        }
17399        mLastMemoryLevel = memFactor;
17400        mLastNumProcesses = mLruProcesses.size();
17401        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17402        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17403        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17404            if (mLowRamStartTime == 0) {
17405                mLowRamStartTime = now;
17406            }
17407            int step = 0;
17408            int fgTrimLevel;
17409            switch (memFactor) {
17410                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17411                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17412                    break;
17413                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17414                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17415                    break;
17416                default:
17417                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17418                    break;
17419            }
17420            int factor = numTrimming/3;
17421            int minFactor = 2;
17422            if (mHomeProcess != null) minFactor++;
17423            if (mPreviousProcess != null) minFactor++;
17424            if (factor < minFactor) factor = minFactor;
17425            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17426            for (int i=N-1; i>=0; i--) {
17427                ProcessRecord app = mLruProcesses.get(i);
17428                if (allChanged || app.procStateChanged) {
17429                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17430                    app.procStateChanged = false;
17431                }
17432                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17433                        && !app.killedByAm) {
17434                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17435                        try {
17436                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17437                                    "Trimming memory of " + app.processName
17438                                    + " to " + curLevel);
17439                            app.thread.scheduleTrimMemory(curLevel);
17440                        } catch (RemoteException e) {
17441                        }
17442                        if (false) {
17443                            // For now we won't do this; our memory trimming seems
17444                            // to be good enough at this point that destroying
17445                            // activities causes more harm than good.
17446                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17447                                    && app != mHomeProcess && app != mPreviousProcess) {
17448                                // Need to do this on its own message because the stack may not
17449                                // be in a consistent state at this point.
17450                                // For these apps we will also finish their activities
17451                                // to help them free memory.
17452                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17453                            }
17454                        }
17455                    }
17456                    app.trimMemoryLevel = curLevel;
17457                    step++;
17458                    if (step >= factor) {
17459                        step = 0;
17460                        switch (curLevel) {
17461                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17462                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17463                                break;
17464                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17465                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17466                                break;
17467                        }
17468                    }
17469                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17470                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17471                            && app.thread != null) {
17472                        try {
17473                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17474                                    "Trimming memory of heavy-weight " + app.processName
17475                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17476                            app.thread.scheduleTrimMemory(
17477                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17478                        } catch (RemoteException e) {
17479                        }
17480                    }
17481                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17482                } else {
17483                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17484                            || app.systemNoUi) && app.pendingUiClean) {
17485                        // If this application is now in the background and it
17486                        // had done UI, then give it the special trim level to
17487                        // have it free UI resources.
17488                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17489                        if (app.trimMemoryLevel < level && app.thread != null) {
17490                            try {
17491                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17492                                        "Trimming memory of bg-ui " + app.processName
17493                                        + " to " + level);
17494                                app.thread.scheduleTrimMemory(level);
17495                            } catch (RemoteException e) {
17496                            }
17497                        }
17498                        app.pendingUiClean = false;
17499                    }
17500                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17501                        try {
17502                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17503                                    "Trimming memory of fg " + app.processName
17504                                    + " to " + fgTrimLevel);
17505                            app.thread.scheduleTrimMemory(fgTrimLevel);
17506                        } catch (RemoteException e) {
17507                        }
17508                    }
17509                    app.trimMemoryLevel = fgTrimLevel;
17510                }
17511            }
17512        } else {
17513            if (mLowRamStartTime != 0) {
17514                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17515                mLowRamStartTime = 0;
17516            }
17517            for (int i=N-1; i>=0; i--) {
17518                ProcessRecord app = mLruProcesses.get(i);
17519                if (allChanged || app.procStateChanged) {
17520                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17521                    app.procStateChanged = false;
17522                }
17523                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17524                        || app.systemNoUi) && app.pendingUiClean) {
17525                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17526                            && app.thread != null) {
17527                        try {
17528                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17529                                    "Trimming memory of ui hidden " + app.processName
17530                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17531                            app.thread.scheduleTrimMemory(
17532                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17533                        } catch (RemoteException e) {
17534                        }
17535                    }
17536                    app.pendingUiClean = false;
17537                }
17538                app.trimMemoryLevel = 0;
17539            }
17540        }
17541
17542        if (mAlwaysFinishActivities) {
17543            // Need to do this on its own message because the stack may not
17544            // be in a consistent state at this point.
17545            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17546        }
17547
17548        if (allChanged) {
17549            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17550        }
17551
17552        if (mProcessStats.shouldWriteNowLocked(now)) {
17553            mHandler.post(new Runnable() {
17554                @Override public void run() {
17555                    synchronized (ActivityManagerService.this) {
17556                        mProcessStats.writeStateAsyncLocked();
17557                    }
17558                }
17559            });
17560        }
17561
17562        if (DEBUG_OOM_ADJ) {
17563            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17564        }
17565    }
17566
17567    final void trimApplications() {
17568        synchronized (this) {
17569            int i;
17570
17571            // First remove any unused application processes whose package
17572            // has been removed.
17573            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17574                final ProcessRecord app = mRemovedProcesses.get(i);
17575                if (app.activities.size() == 0
17576                        && app.curReceiver == null && app.services.size() == 0) {
17577                    Slog.i(
17578                        TAG, "Exiting empty application process "
17579                        + app.processName + " ("
17580                        + (app.thread != null ? app.thread.asBinder() : null)
17581                        + ")\n");
17582                    if (app.pid > 0 && app.pid != MY_PID) {
17583                        app.kill("empty", false);
17584                    } else {
17585                        try {
17586                            app.thread.scheduleExit();
17587                        } catch (Exception e) {
17588                            // Ignore exceptions.
17589                        }
17590                    }
17591                    cleanUpApplicationRecordLocked(app, false, true, -1);
17592                    mRemovedProcesses.remove(i);
17593
17594                    if (app.persistent) {
17595                        addAppLocked(app.info, false, null /* ABI override */);
17596                    }
17597                }
17598            }
17599
17600            // Now update the oom adj for all processes.
17601            updateOomAdjLocked();
17602        }
17603    }
17604
17605    /** This method sends the specified signal to each of the persistent apps */
17606    public void signalPersistentProcesses(int sig) throws RemoteException {
17607        if (sig != Process.SIGNAL_USR1) {
17608            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17609        }
17610
17611        synchronized (this) {
17612            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17613                    != PackageManager.PERMISSION_GRANTED) {
17614                throw new SecurityException("Requires permission "
17615                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17616            }
17617
17618            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17619                ProcessRecord r = mLruProcesses.get(i);
17620                if (r.thread != null && r.persistent) {
17621                    Process.sendSignal(r.pid, sig);
17622                }
17623            }
17624        }
17625    }
17626
17627    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17628        if (proc == null || proc == mProfileProc) {
17629            proc = mProfileProc;
17630            profileType = mProfileType;
17631            clearProfilerLocked();
17632        }
17633        if (proc == null) {
17634            return;
17635        }
17636        try {
17637            proc.thread.profilerControl(false, null, profileType);
17638        } catch (RemoteException e) {
17639            throw new IllegalStateException("Process disappeared");
17640        }
17641    }
17642
17643    private void clearProfilerLocked() {
17644        if (mProfileFd != null) {
17645            try {
17646                mProfileFd.close();
17647            } catch (IOException e) {
17648            }
17649        }
17650        mProfileApp = null;
17651        mProfileProc = null;
17652        mProfileFile = null;
17653        mProfileType = 0;
17654        mAutoStopProfiler = false;
17655        mSamplingInterval = 0;
17656    }
17657
17658    public boolean profileControl(String process, int userId, boolean start,
17659            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17660
17661        try {
17662            synchronized (this) {
17663                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17664                // its own permission.
17665                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17666                        != PackageManager.PERMISSION_GRANTED) {
17667                    throw new SecurityException("Requires permission "
17668                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17669                }
17670
17671                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17672                    throw new IllegalArgumentException("null profile info or fd");
17673                }
17674
17675                ProcessRecord proc = null;
17676                if (process != null) {
17677                    proc = findProcessLocked(process, userId, "profileControl");
17678                }
17679
17680                if (start && (proc == null || proc.thread == null)) {
17681                    throw new IllegalArgumentException("Unknown process: " + process);
17682                }
17683
17684                if (start) {
17685                    stopProfilerLocked(null, 0);
17686                    setProfileApp(proc.info, proc.processName, profilerInfo);
17687                    mProfileProc = proc;
17688                    mProfileType = profileType;
17689                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17690                    try {
17691                        fd = fd.dup();
17692                    } catch (IOException e) {
17693                        fd = null;
17694                    }
17695                    profilerInfo.profileFd = fd;
17696                    proc.thread.profilerControl(start, profilerInfo, profileType);
17697                    fd = null;
17698                    mProfileFd = null;
17699                } else {
17700                    stopProfilerLocked(proc, profileType);
17701                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17702                        try {
17703                            profilerInfo.profileFd.close();
17704                        } catch (IOException e) {
17705                        }
17706                    }
17707                }
17708
17709                return true;
17710            }
17711        } catch (RemoteException e) {
17712            throw new IllegalStateException("Process disappeared");
17713        } finally {
17714            if (profilerInfo != null && profilerInfo.profileFd != null) {
17715                try {
17716                    profilerInfo.profileFd.close();
17717                } catch (IOException e) {
17718                }
17719            }
17720        }
17721    }
17722
17723    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17724        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17725                userId, true, ALLOW_FULL_ONLY, callName, null);
17726        ProcessRecord proc = null;
17727        try {
17728            int pid = Integer.parseInt(process);
17729            synchronized (mPidsSelfLocked) {
17730                proc = mPidsSelfLocked.get(pid);
17731            }
17732        } catch (NumberFormatException e) {
17733        }
17734
17735        if (proc == null) {
17736            ArrayMap<String, SparseArray<ProcessRecord>> all
17737                    = mProcessNames.getMap();
17738            SparseArray<ProcessRecord> procs = all.get(process);
17739            if (procs != null && procs.size() > 0) {
17740                proc = procs.valueAt(0);
17741                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17742                    for (int i=1; i<procs.size(); i++) {
17743                        ProcessRecord thisProc = procs.valueAt(i);
17744                        if (thisProc.userId == userId) {
17745                            proc = thisProc;
17746                            break;
17747                        }
17748                    }
17749                }
17750            }
17751        }
17752
17753        return proc;
17754    }
17755
17756    public boolean dumpHeap(String process, int userId, boolean managed,
17757            String path, ParcelFileDescriptor fd) throws RemoteException {
17758
17759        try {
17760            synchronized (this) {
17761                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17762                // its own permission (same as profileControl).
17763                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17764                        != PackageManager.PERMISSION_GRANTED) {
17765                    throw new SecurityException("Requires permission "
17766                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17767                }
17768
17769                if (fd == null) {
17770                    throw new IllegalArgumentException("null fd");
17771                }
17772
17773                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17774                if (proc == null || proc.thread == null) {
17775                    throw new IllegalArgumentException("Unknown process: " + process);
17776                }
17777
17778                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17779                if (!isDebuggable) {
17780                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17781                        throw new SecurityException("Process not debuggable: " + proc);
17782                    }
17783                }
17784
17785                proc.thread.dumpHeap(managed, path, fd);
17786                fd = null;
17787                return true;
17788            }
17789        } catch (RemoteException e) {
17790            throw new IllegalStateException("Process disappeared");
17791        } finally {
17792            if (fd != null) {
17793                try {
17794                    fd.close();
17795                } catch (IOException e) {
17796                }
17797            }
17798        }
17799    }
17800
17801    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17802    public void monitor() {
17803        synchronized (this) { }
17804    }
17805
17806    void onCoreSettingsChange(Bundle settings) {
17807        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17808            ProcessRecord processRecord = mLruProcesses.get(i);
17809            try {
17810                if (processRecord.thread != null) {
17811                    processRecord.thread.setCoreSettings(settings);
17812                }
17813            } catch (RemoteException re) {
17814                /* ignore */
17815            }
17816        }
17817    }
17818
17819    // Multi-user methods
17820
17821    /**
17822     * Start user, if its not already running, but don't bring it to foreground.
17823     */
17824    @Override
17825    public boolean startUserInBackground(final int userId) {
17826        return startUser(userId, /* foreground */ false);
17827    }
17828
17829    /**
17830     * Start user, if its not already running, and bring it to foreground.
17831     */
17832    boolean startUserInForeground(final int userId, Dialog dlg) {
17833        boolean result = startUser(userId, /* foreground */ true);
17834        dlg.dismiss();
17835        return result;
17836    }
17837
17838    /**
17839     * Refreshes the list of users related to the current user when either a
17840     * user switch happens or when a new related user is started in the
17841     * background.
17842     */
17843    private void updateCurrentProfileIdsLocked() {
17844        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17845                mCurrentUserId, false /* enabledOnly */);
17846        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17847        for (int i = 0; i < currentProfileIds.length; i++) {
17848            currentProfileIds[i] = profiles.get(i).id;
17849        }
17850        mCurrentProfileIds = currentProfileIds;
17851
17852        synchronized (mUserProfileGroupIdsSelfLocked) {
17853            mUserProfileGroupIdsSelfLocked.clear();
17854            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17855            for (int i = 0; i < users.size(); i++) {
17856                UserInfo user = users.get(i);
17857                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17858                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17859                }
17860            }
17861        }
17862    }
17863
17864    private Set getProfileIdsLocked(int userId) {
17865        Set userIds = new HashSet<Integer>();
17866        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17867                userId, false /* enabledOnly */);
17868        for (UserInfo user : profiles) {
17869            userIds.add(Integer.valueOf(user.id));
17870        }
17871        return userIds;
17872    }
17873
17874    @Override
17875    public boolean switchUser(final int userId) {
17876        String userName;
17877        synchronized (this) {
17878            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17879            if (userInfo == null) {
17880                Slog.w(TAG, "No user info for user #" + userId);
17881                return false;
17882            }
17883            if (userInfo.isManagedProfile()) {
17884                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17885                return false;
17886            }
17887            userName = userInfo.name;
17888        }
17889        mHandler.removeMessages(START_USER_SWITCH_MSG);
17890        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17891        return true;
17892    }
17893
17894    private void showUserSwitchDialog(int userId, String userName) {
17895        // The dialog will show and then initiate the user switch by calling startUserInForeground
17896        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17897                true /* above system */);
17898        d.show();
17899    }
17900
17901    private boolean startUser(final int userId, final boolean foreground) {
17902        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17903                != PackageManager.PERMISSION_GRANTED) {
17904            String msg = "Permission Denial: switchUser() from pid="
17905                    + Binder.getCallingPid()
17906                    + ", uid=" + Binder.getCallingUid()
17907                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17908            Slog.w(TAG, msg);
17909            throw new SecurityException(msg);
17910        }
17911
17912        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17913
17914        final long ident = Binder.clearCallingIdentity();
17915        try {
17916            synchronized (this) {
17917                final int oldUserId = mCurrentUserId;
17918                if (oldUserId == userId) {
17919                    return true;
17920                }
17921
17922                mStackSupervisor.setLockTaskModeLocked(null, false);
17923
17924                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17925                if (userInfo == null) {
17926                    Slog.w(TAG, "No user info for user #" + userId);
17927                    return false;
17928                }
17929                if (foreground && userInfo.isManagedProfile()) {
17930                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17931                    return false;
17932                }
17933
17934                if (foreground) {
17935                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17936                            R.anim.screen_user_enter);
17937                }
17938
17939                boolean needStart = false;
17940
17941                // If the user we are switching to is not currently started, then
17942                // we need to start it now.
17943                if (mStartedUsers.get(userId) == null) {
17944                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17945                    updateStartedUserArrayLocked();
17946                    needStart = true;
17947                }
17948
17949                final Integer userIdInt = Integer.valueOf(userId);
17950                mUserLru.remove(userIdInt);
17951                mUserLru.add(userIdInt);
17952
17953                if (foreground) {
17954                    mCurrentUserId = userId;
17955                    updateCurrentProfileIdsLocked();
17956                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17957                    // Once the internal notion of the active user has switched, we lock the device
17958                    // with the option to show the user switcher on the keyguard.
17959                    mWindowManager.lockNow(null);
17960                } else {
17961                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17962                    updateCurrentProfileIdsLocked();
17963                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17964                    mUserLru.remove(currentUserIdInt);
17965                    mUserLru.add(currentUserIdInt);
17966                }
17967
17968                final UserStartedState uss = mStartedUsers.get(userId);
17969
17970                // Make sure user is in the started state.  If it is currently
17971                // stopping, we need to knock that off.
17972                if (uss.mState == UserStartedState.STATE_STOPPING) {
17973                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17974                    // so we can just fairly silently bring the user back from
17975                    // the almost-dead.
17976                    uss.mState = UserStartedState.STATE_RUNNING;
17977                    updateStartedUserArrayLocked();
17978                    needStart = true;
17979                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17980                    // This means ACTION_SHUTDOWN has been sent, so we will
17981                    // need to treat this as a new boot of the user.
17982                    uss.mState = UserStartedState.STATE_BOOTING;
17983                    updateStartedUserArrayLocked();
17984                    needStart = true;
17985                }
17986
17987                if (uss.mState == UserStartedState.STATE_BOOTING) {
17988                    // Booting up a new user, need to tell system services about it.
17989                    // Note that this is on the same handler as scheduling of broadcasts,
17990                    // which is important because it needs to go first.
17991                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17992                }
17993
17994                if (foreground) {
17995                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17996                            oldUserId));
17997                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17998                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17999                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18000                            oldUserId, userId, uss));
18001                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18002                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18003                }
18004
18005                if (needStart) {
18006                    // Send USER_STARTED broadcast
18007                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18008                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18009                            | Intent.FLAG_RECEIVER_FOREGROUND);
18010                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18011                    broadcastIntentLocked(null, null, intent,
18012                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18013                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18014                }
18015
18016                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18017                    if (userId != UserHandle.USER_OWNER) {
18018                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18019                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18020                        broadcastIntentLocked(null, null, intent, null,
18021                                new IIntentReceiver.Stub() {
18022                                    public void performReceive(Intent intent, int resultCode,
18023                                            String data, Bundle extras, boolean ordered,
18024                                            boolean sticky, int sendingUser) {
18025                                        onUserInitialized(uss, foreground, oldUserId, userId);
18026                                    }
18027                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18028                                true, false, MY_PID, Process.SYSTEM_UID,
18029                                userId);
18030                        uss.initializing = true;
18031                    } else {
18032                        getUserManagerLocked().makeInitialized(userInfo.id);
18033                    }
18034                }
18035
18036                if (foreground) {
18037                    if (!uss.initializing) {
18038                        moveUserToForeground(uss, oldUserId, userId);
18039                    }
18040                } else {
18041                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18042                }
18043
18044                if (needStart) {
18045                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18046                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18047                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18048                    broadcastIntentLocked(null, null, intent,
18049                            null, new IIntentReceiver.Stub() {
18050                                @Override
18051                                public void performReceive(Intent intent, int resultCode, String data,
18052                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18053                                        throws RemoteException {
18054                                }
18055                            }, 0, null, null,
18056                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18057                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18058                }
18059            }
18060        } finally {
18061            Binder.restoreCallingIdentity(ident);
18062        }
18063
18064        return true;
18065    }
18066
18067    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18068        long ident = Binder.clearCallingIdentity();
18069        try {
18070            Intent intent;
18071            if (oldUserId >= 0) {
18072                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18073                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18074                int count = profiles.size();
18075                for (int i = 0; i < count; i++) {
18076                    int profileUserId = profiles.get(i).id;
18077                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18078                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18079                            | Intent.FLAG_RECEIVER_FOREGROUND);
18080                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18081                    broadcastIntentLocked(null, null, intent,
18082                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18083                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18084                }
18085            }
18086            if (newUserId >= 0) {
18087                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18088                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18089                int count = profiles.size();
18090                for (int i = 0; i < count; i++) {
18091                    int profileUserId = profiles.get(i).id;
18092                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18093                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18094                            | Intent.FLAG_RECEIVER_FOREGROUND);
18095                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18096                    broadcastIntentLocked(null, null, intent,
18097                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18098                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18099                }
18100                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18101                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18102                        | Intent.FLAG_RECEIVER_FOREGROUND);
18103                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18104                broadcastIntentLocked(null, null, intent,
18105                        null, null, 0, null, null,
18106                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18107                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18108            }
18109        } finally {
18110            Binder.restoreCallingIdentity(ident);
18111        }
18112    }
18113
18114    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18115            final int newUserId) {
18116        final int N = mUserSwitchObservers.beginBroadcast();
18117        if (N > 0) {
18118            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18119                int mCount = 0;
18120                @Override
18121                public void sendResult(Bundle data) throws RemoteException {
18122                    synchronized (ActivityManagerService.this) {
18123                        if (mCurUserSwitchCallback == this) {
18124                            mCount++;
18125                            if (mCount == N) {
18126                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18127                            }
18128                        }
18129                    }
18130                }
18131            };
18132            synchronized (this) {
18133                uss.switching = true;
18134                mCurUserSwitchCallback = callback;
18135            }
18136            for (int i=0; i<N; i++) {
18137                try {
18138                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18139                            newUserId, callback);
18140                } catch (RemoteException e) {
18141                }
18142            }
18143        } else {
18144            synchronized (this) {
18145                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18146            }
18147        }
18148        mUserSwitchObservers.finishBroadcast();
18149    }
18150
18151    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18152        synchronized (this) {
18153            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18154            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18155        }
18156    }
18157
18158    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18159        mCurUserSwitchCallback = null;
18160        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18161        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18162                oldUserId, newUserId, uss));
18163    }
18164
18165    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18166        synchronized (this) {
18167            if (foreground) {
18168                moveUserToForeground(uss, oldUserId, newUserId);
18169            }
18170        }
18171
18172        completeSwitchAndInitalize(uss, newUserId, true, false);
18173    }
18174
18175    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18176        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18177        if (homeInFront) {
18178            startHomeActivityLocked(newUserId);
18179        } else {
18180            mStackSupervisor.resumeTopActivitiesLocked();
18181        }
18182        EventLogTags.writeAmSwitchUser(newUserId);
18183        getUserManagerLocked().userForeground(newUserId);
18184        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18185    }
18186
18187    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18188        completeSwitchAndInitalize(uss, newUserId, false, true);
18189    }
18190
18191    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18192            boolean clearInitializing, boolean clearSwitching) {
18193        boolean unfrozen = false;
18194        synchronized (this) {
18195            if (clearInitializing) {
18196                uss.initializing = false;
18197                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18198            }
18199            if (clearSwitching) {
18200                uss.switching = false;
18201            }
18202            if (!uss.switching && !uss.initializing) {
18203                mWindowManager.stopFreezingScreen();
18204                unfrozen = true;
18205            }
18206        }
18207        if (unfrozen) {
18208            final int N = mUserSwitchObservers.beginBroadcast();
18209            for (int i=0; i<N; i++) {
18210                try {
18211                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18212                } catch (RemoteException e) {
18213                }
18214            }
18215            mUserSwitchObservers.finishBroadcast();
18216        }
18217    }
18218
18219    void scheduleStartProfilesLocked() {
18220        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18221            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18222                    DateUtils.SECOND_IN_MILLIS);
18223        }
18224    }
18225
18226    void startProfilesLocked() {
18227        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18228        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18229                mCurrentUserId, false /* enabledOnly */);
18230        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18231        for (UserInfo user : profiles) {
18232            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18233                    && user.id != mCurrentUserId) {
18234                toStart.add(user);
18235            }
18236        }
18237        final int n = toStart.size();
18238        int i = 0;
18239        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18240            startUserInBackground(toStart.get(i).id);
18241        }
18242        if (i < n) {
18243            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18244        }
18245    }
18246
18247    void finishUserBoot(UserStartedState uss) {
18248        synchronized (this) {
18249            if (uss.mState == UserStartedState.STATE_BOOTING
18250                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18251                uss.mState = UserStartedState.STATE_RUNNING;
18252                final int userId = uss.mHandle.getIdentifier();
18253                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18254                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18255                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18256                broadcastIntentLocked(null, null, intent,
18257                        null, null, 0, null, null,
18258                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18259                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18260            }
18261        }
18262    }
18263
18264    void finishUserSwitch(UserStartedState uss) {
18265        synchronized (this) {
18266            finishUserBoot(uss);
18267
18268            startProfilesLocked();
18269
18270            int num = mUserLru.size();
18271            int i = 0;
18272            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18273                Integer oldUserId = mUserLru.get(i);
18274                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18275                if (oldUss == null) {
18276                    // Shouldn't happen, but be sane if it does.
18277                    mUserLru.remove(i);
18278                    num--;
18279                    continue;
18280                }
18281                if (oldUss.mState == UserStartedState.STATE_STOPPING
18282                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18283                    // This user is already stopping, doesn't count.
18284                    num--;
18285                    i++;
18286                    continue;
18287                }
18288                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18289                    // Owner and current can't be stopped, but count as running.
18290                    i++;
18291                    continue;
18292                }
18293                // This is a user to be stopped.
18294                stopUserLocked(oldUserId, null);
18295                num--;
18296                i++;
18297            }
18298        }
18299    }
18300
18301    @Override
18302    public int stopUser(final int userId, final IStopUserCallback callback) {
18303        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18304                != PackageManager.PERMISSION_GRANTED) {
18305            String msg = "Permission Denial: switchUser() from pid="
18306                    + Binder.getCallingPid()
18307                    + ", uid=" + Binder.getCallingUid()
18308                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18309            Slog.w(TAG, msg);
18310            throw new SecurityException(msg);
18311        }
18312        if (userId <= 0) {
18313            throw new IllegalArgumentException("Can't stop primary user " + userId);
18314        }
18315        synchronized (this) {
18316            return stopUserLocked(userId, callback);
18317        }
18318    }
18319
18320    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18321        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18322        if (mCurrentUserId == userId) {
18323            return ActivityManager.USER_OP_IS_CURRENT;
18324        }
18325
18326        final UserStartedState uss = mStartedUsers.get(userId);
18327        if (uss == null) {
18328            // User is not started, nothing to do...  but we do need to
18329            // callback if requested.
18330            if (callback != null) {
18331                mHandler.post(new Runnable() {
18332                    @Override
18333                    public void run() {
18334                        try {
18335                            callback.userStopped(userId);
18336                        } catch (RemoteException e) {
18337                        }
18338                    }
18339                });
18340            }
18341            return ActivityManager.USER_OP_SUCCESS;
18342        }
18343
18344        if (callback != null) {
18345            uss.mStopCallbacks.add(callback);
18346        }
18347
18348        if (uss.mState != UserStartedState.STATE_STOPPING
18349                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18350            uss.mState = UserStartedState.STATE_STOPPING;
18351            updateStartedUserArrayLocked();
18352
18353            long ident = Binder.clearCallingIdentity();
18354            try {
18355                // We are going to broadcast ACTION_USER_STOPPING and then
18356                // once that is done send a final ACTION_SHUTDOWN and then
18357                // stop the user.
18358                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18359                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18360                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18361                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18362                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18363                // This is the result receiver for the final shutdown broadcast.
18364                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18365                    @Override
18366                    public void performReceive(Intent intent, int resultCode, String data,
18367                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18368                        finishUserStop(uss);
18369                    }
18370                };
18371                // This is the result receiver for the initial stopping broadcast.
18372                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18373                    @Override
18374                    public void performReceive(Intent intent, int resultCode, String data,
18375                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18376                        // On to the next.
18377                        synchronized (ActivityManagerService.this) {
18378                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18379                                // Whoops, we are being started back up.  Abort, abort!
18380                                return;
18381                            }
18382                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18383                        }
18384                        mBatteryStatsService.noteEvent(
18385                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18386                                Integer.toString(userId), userId);
18387                        mSystemServiceManager.stopUser(userId);
18388                        broadcastIntentLocked(null, null, shutdownIntent,
18389                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18390                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18391                    }
18392                };
18393                // Kick things off.
18394                broadcastIntentLocked(null, null, stoppingIntent,
18395                        null, stoppingReceiver, 0, null, null,
18396                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18397                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18398            } finally {
18399                Binder.restoreCallingIdentity(ident);
18400            }
18401        }
18402
18403        return ActivityManager.USER_OP_SUCCESS;
18404    }
18405
18406    void finishUserStop(UserStartedState uss) {
18407        final int userId = uss.mHandle.getIdentifier();
18408        boolean stopped;
18409        ArrayList<IStopUserCallback> callbacks;
18410        synchronized (this) {
18411            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18412            if (mStartedUsers.get(userId) != uss) {
18413                stopped = false;
18414            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18415                stopped = false;
18416            } else {
18417                stopped = true;
18418                // User can no longer run.
18419                mStartedUsers.remove(userId);
18420                mUserLru.remove(Integer.valueOf(userId));
18421                updateStartedUserArrayLocked();
18422
18423                // Clean up all state and processes associated with the user.
18424                // Kill all the processes for the user.
18425                forceStopUserLocked(userId, "finish user");
18426            }
18427
18428            // Explicitly remove the old information in mRecentTasks.
18429            removeRecentTasksForUserLocked(userId);
18430        }
18431
18432        for (int i=0; i<callbacks.size(); i++) {
18433            try {
18434                if (stopped) callbacks.get(i).userStopped(userId);
18435                else callbacks.get(i).userStopAborted(userId);
18436            } catch (RemoteException e) {
18437            }
18438        }
18439
18440        if (stopped) {
18441            mSystemServiceManager.cleanupUser(userId);
18442            synchronized (this) {
18443                mStackSupervisor.removeUserLocked(userId);
18444            }
18445        }
18446    }
18447
18448    @Override
18449    public UserInfo getCurrentUser() {
18450        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18451                != PackageManager.PERMISSION_GRANTED) && (
18452                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18453                != PackageManager.PERMISSION_GRANTED)) {
18454            String msg = "Permission Denial: getCurrentUser() from pid="
18455                    + Binder.getCallingPid()
18456                    + ", uid=" + Binder.getCallingUid()
18457                    + " requires " + INTERACT_ACROSS_USERS;
18458            Slog.w(TAG, msg);
18459            throw new SecurityException(msg);
18460        }
18461        synchronized (this) {
18462            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18463        }
18464    }
18465
18466    int getCurrentUserIdLocked() {
18467        return mCurrentUserId;
18468    }
18469
18470    @Override
18471    public boolean isUserRunning(int userId, boolean orStopped) {
18472        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18473                != PackageManager.PERMISSION_GRANTED) {
18474            String msg = "Permission Denial: isUserRunning() from pid="
18475                    + Binder.getCallingPid()
18476                    + ", uid=" + Binder.getCallingUid()
18477                    + " requires " + INTERACT_ACROSS_USERS;
18478            Slog.w(TAG, msg);
18479            throw new SecurityException(msg);
18480        }
18481        synchronized (this) {
18482            return isUserRunningLocked(userId, orStopped);
18483        }
18484    }
18485
18486    boolean isUserRunningLocked(int userId, boolean orStopped) {
18487        UserStartedState state = mStartedUsers.get(userId);
18488        if (state == null) {
18489            return false;
18490        }
18491        if (orStopped) {
18492            return true;
18493        }
18494        return state.mState != UserStartedState.STATE_STOPPING
18495                && state.mState != UserStartedState.STATE_SHUTDOWN;
18496    }
18497
18498    @Override
18499    public int[] getRunningUserIds() {
18500        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18501                != PackageManager.PERMISSION_GRANTED) {
18502            String msg = "Permission Denial: isUserRunning() from pid="
18503                    + Binder.getCallingPid()
18504                    + ", uid=" + Binder.getCallingUid()
18505                    + " requires " + INTERACT_ACROSS_USERS;
18506            Slog.w(TAG, msg);
18507            throw new SecurityException(msg);
18508        }
18509        synchronized (this) {
18510            return mStartedUserArray;
18511        }
18512    }
18513
18514    private void updateStartedUserArrayLocked() {
18515        int num = 0;
18516        for (int i=0; i<mStartedUsers.size();  i++) {
18517            UserStartedState uss = mStartedUsers.valueAt(i);
18518            // This list does not include stopping users.
18519            if (uss.mState != UserStartedState.STATE_STOPPING
18520                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18521                num++;
18522            }
18523        }
18524        mStartedUserArray = new int[num];
18525        num = 0;
18526        for (int i=0; i<mStartedUsers.size();  i++) {
18527            UserStartedState uss = mStartedUsers.valueAt(i);
18528            if (uss.mState != UserStartedState.STATE_STOPPING
18529                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18530                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18531                num++;
18532            }
18533        }
18534    }
18535
18536    @Override
18537    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18538        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18539                != PackageManager.PERMISSION_GRANTED) {
18540            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18541                    + Binder.getCallingPid()
18542                    + ", uid=" + Binder.getCallingUid()
18543                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18544            Slog.w(TAG, msg);
18545            throw new SecurityException(msg);
18546        }
18547
18548        mUserSwitchObservers.register(observer);
18549    }
18550
18551    @Override
18552    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18553        mUserSwitchObservers.unregister(observer);
18554    }
18555
18556    private boolean userExists(int userId) {
18557        if (userId == 0) {
18558            return true;
18559        }
18560        UserManagerService ums = getUserManagerLocked();
18561        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18562    }
18563
18564    int[] getUsersLocked() {
18565        UserManagerService ums = getUserManagerLocked();
18566        return ums != null ? ums.getUserIds() : new int[] { 0 };
18567    }
18568
18569    UserManagerService getUserManagerLocked() {
18570        if (mUserManager == null) {
18571            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18572            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18573        }
18574        return mUserManager;
18575    }
18576
18577    private int applyUserId(int uid, int userId) {
18578        return UserHandle.getUid(userId, uid);
18579    }
18580
18581    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18582        if (info == null) return null;
18583        ApplicationInfo newInfo = new ApplicationInfo(info);
18584        newInfo.uid = applyUserId(info.uid, userId);
18585        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18586                + info.packageName;
18587        return newInfo;
18588    }
18589
18590    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18591        if (aInfo == null
18592                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18593            return aInfo;
18594        }
18595
18596        ActivityInfo info = new ActivityInfo(aInfo);
18597        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18598        return info;
18599    }
18600
18601    private final class LocalService extends ActivityManagerInternal {
18602        @Override
18603        public void goingToSleep() {
18604            ActivityManagerService.this.goingToSleep();
18605        }
18606
18607        @Override
18608        public void wakingUp() {
18609            ActivityManagerService.this.wakingUp();
18610        }
18611
18612        @Override
18613        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18614                String processName, String abiOverride, int uid, Runnable crashHandler) {
18615            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18616                    processName, abiOverride, uid, crashHandler);
18617        }
18618    }
18619
18620    /**
18621     * An implementation of IAppTask, that allows an app to manage its own tasks via
18622     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18623     * only the process that calls getAppTasks() can call the AppTask methods.
18624     */
18625    class AppTaskImpl extends IAppTask.Stub {
18626        private int mTaskId;
18627        private int mCallingUid;
18628
18629        public AppTaskImpl(int taskId, int callingUid) {
18630            mTaskId = taskId;
18631            mCallingUid = callingUid;
18632        }
18633
18634        private void checkCaller() {
18635            if (mCallingUid != Binder.getCallingUid()) {
18636                throw new SecurityException("Caller " + mCallingUid
18637                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18638            }
18639        }
18640
18641        @Override
18642        public void finishAndRemoveTask() {
18643            checkCaller();
18644
18645            synchronized (ActivityManagerService.this) {
18646                long origId = Binder.clearCallingIdentity();
18647                try {
18648                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18649                    if (tr == null) {
18650                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18651                    }
18652                    // Only kill the process if we are not a new document
18653                    int flags = tr.getBaseIntent().getFlags();
18654                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18655                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18656                    removeTaskByIdLocked(mTaskId,
18657                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18658                } finally {
18659                    Binder.restoreCallingIdentity(origId);
18660                }
18661            }
18662        }
18663
18664        @Override
18665        public ActivityManager.RecentTaskInfo getTaskInfo() {
18666            checkCaller();
18667
18668            synchronized (ActivityManagerService.this) {
18669                long origId = Binder.clearCallingIdentity();
18670                try {
18671                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18672                    if (tr == null) {
18673                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18674                    }
18675                    return createRecentTaskInfoFromTaskRecord(tr);
18676                } finally {
18677                    Binder.restoreCallingIdentity(origId);
18678                }
18679            }
18680        }
18681
18682        @Override
18683        public void moveToFront() {
18684            checkCaller();
18685
18686            final TaskRecord tr;
18687            synchronized (ActivityManagerService.this) {
18688                tr = recentTaskForIdLocked(mTaskId);
18689                if (tr == null) {
18690                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18691                }
18692                if (tr.getRootActivity() != null) {
18693                    long origId = Binder.clearCallingIdentity();
18694                    try {
18695                        moveTaskToFrontLocked(tr.taskId, 0, null);
18696                        return;
18697                    } finally {
18698                        Binder.restoreCallingIdentity(origId);
18699                    }
18700                }
18701            }
18702
18703            startActivityFromRecentsInner(tr.taskId, null);
18704        }
18705
18706        @Override
18707        public int startActivity(IBinder whoThread, String callingPackage,
18708                Intent intent, String resolvedType, Bundle options) {
18709            checkCaller();
18710
18711            int callingUser = UserHandle.getCallingUserId();
18712            TaskRecord tr;
18713            IApplicationThread appThread;
18714            synchronized (ActivityManagerService.this) {
18715                tr = recentTaskForIdLocked(mTaskId);
18716                if (tr == null) {
18717                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18718                }
18719                appThread = ApplicationThreadNative.asInterface(whoThread);
18720                if (appThread == null) {
18721                    throw new IllegalArgumentException("Bad app thread " + appThread);
18722                }
18723            }
18724            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18725                    resolvedType, null, null, null, null, 0, 0, null, null,
18726                    null, options, callingUser, null, tr);
18727        }
18728
18729        @Override
18730        public void setExcludeFromRecents(boolean exclude) {
18731            checkCaller();
18732
18733            synchronized (ActivityManagerService.this) {
18734                long origId = Binder.clearCallingIdentity();
18735                try {
18736                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18737                    if (tr == null) {
18738                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18739                    }
18740                    Intent intent = tr.getBaseIntent();
18741                    if (exclude) {
18742                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18743                    } else {
18744                        intent.setFlags(intent.getFlags()
18745                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18746                    }
18747                } finally {
18748                    Binder.restoreCallingIdentity(origId);
18749                }
18750            }
18751        }
18752    }
18753}
18754