ActivityManagerService.java revision 53dc7eac05324261a51443059b5fb5d468f33594
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        if (mRecentTasks == null) {
3820            // Happens when called from the packagemanager broadcast before boot.
3821            return;
3822        }
3823
3824        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3825        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3826        final IPackageManager pm = AppGlobals.getPackageManager();
3827        final ActivityInfo dummyAct = new ActivityInfo();
3828        final ApplicationInfo dummyApp = new ApplicationInfo();
3829
3830        int N = mRecentTasks.size();
3831
3832        int[] users = userId == UserHandle.USER_ALL
3833                ? getUsersLocked() : new int[] { userId };
3834        for (int user : users) {
3835            for (int i = 0; i < N; i++) {
3836                TaskRecord task = mRecentTasks.get(i);
3837                if (task.userId != user) {
3838                    // Only look at tasks for the user ID of interest.
3839                    continue;
3840                }
3841                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3842                    // This situation is broken, and we should just get rid of it now.
3843                    mRecentTasks.remove(i);
3844                    task.removedFromRecents(mTaskPersister);
3845                    i--;
3846                    N--;
3847                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3848                    continue;
3849                }
3850                // Check whether this activity is currently available.
3851                if (task.realActivity != null) {
3852                    ActivityInfo ai = availActCache.get(task.realActivity);
3853                    if (ai == null) {
3854                        try {
3855                            ai = pm.getActivityInfo(task.realActivity,
3856                                    PackageManager.GET_UNINSTALLED_PACKAGES
3857                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3858                        } catch (RemoteException e) {
3859                            // Will never happen.
3860                            continue;
3861                        }
3862                        if (ai == null) {
3863                            ai = dummyAct;
3864                        }
3865                        availActCache.put(task.realActivity, ai);
3866                    }
3867                    if (ai == dummyAct) {
3868                        // This could be either because the activity no longer exists, or the
3869                        // app is temporarily gone.  For the former we want to remove the recents
3870                        // entry; for the latter we want to mark it as unavailable.
3871                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3872                        if (app == null) {
3873                            try {
3874                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3875                                        PackageManager.GET_UNINSTALLED_PACKAGES
3876                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3877                            } catch (RemoteException e) {
3878                                // Will never happen.
3879                                continue;
3880                            }
3881                            if (app == null) {
3882                                app = dummyApp;
3883                            }
3884                            availAppCache.put(task.realActivity.getPackageName(), app);
3885                        }
3886                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3887                            // Doesn't exist any more!  Good-bye.
3888                            mRecentTasks.remove(i);
3889                            task.removedFromRecents(mTaskPersister);
3890                            i--;
3891                            N--;
3892                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3893                            continue;
3894                        } else {
3895                            // Otherwise just not available for now.
3896                            if (task.isAvailable) {
3897                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3898                                        + task);
3899                            }
3900                            task.isAvailable = false;
3901                        }
3902                    } else {
3903                        if (!ai.enabled || !ai.applicationInfo.enabled
3904                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3905                            if (task.isAvailable) {
3906                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3907                                        + task + " (enabled=" + ai.enabled + "/"
3908                                        + ai.applicationInfo.enabled +  " flags="
3909                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3910                            }
3911                            task.isAvailable = false;
3912                        } else {
3913                            if (!task.isAvailable) {
3914                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3915                                        + task);
3916                            }
3917                            task.isAvailable = true;
3918                        }
3919                    }
3920                }
3921            }
3922        }
3923
3924        // Verify the affiliate chain for each task.
3925        for (int i = 0; i < N; ) {
3926            TaskRecord task = mRecentTasks.remove(i);
3927            if (mTmpRecents.contains(task)) {
3928                continue;
3929            }
3930            int affiliatedTaskId = task.mAffiliatedTaskId;
3931            while (true) {
3932                TaskRecord next = task.mNextAffiliate;
3933                if (next == null) {
3934                    break;
3935                }
3936                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3937                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3938                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3939                    task.setNextAffiliate(null);
3940                    if (next.mPrevAffiliate == task) {
3941                        next.setPrevAffiliate(null);
3942                    }
3943                    break;
3944                }
3945                if (next.mPrevAffiliate != task) {
3946                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3947                            next.mPrevAffiliate + " task=" + task);
3948                    next.setPrevAffiliate(null);
3949                    task.setNextAffiliate(null);
3950                    break;
3951                }
3952                if (!mRecentTasks.contains(next)) {
3953                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3954                    task.setNextAffiliate(null);
3955                    // We know that next.mPrevAffiliate is always task, from above, so clear
3956                    // its previous affiliate.
3957                    next.setPrevAffiliate(null);
3958                    break;
3959                }
3960                task = next;
3961            }
3962            // task is now the end of the list
3963            do {
3964                mRecentTasks.remove(task);
3965                mRecentTasks.add(i++, task);
3966                mTmpRecents.add(task);
3967                task.inRecents = true;
3968            } while ((task = task.mPrevAffiliate) != null);
3969        }
3970        mTmpRecents.clear();
3971        // mRecentTasks is now in sorted, affiliated order.
3972    }
3973
3974    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3975        int N = mRecentTasks.size();
3976        TaskRecord top = task;
3977        int topIndex = taskIndex;
3978        while (top.mNextAffiliate != null && topIndex > 0) {
3979            top = top.mNextAffiliate;
3980            topIndex--;
3981        }
3982        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3983                + topIndex + " from intial " + taskIndex);
3984        // Find the end of the chain, doing a sanity check along the way.
3985        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3986        int endIndex = topIndex;
3987        TaskRecord prev = top;
3988        while (endIndex < N) {
3989            TaskRecord cur = mRecentTasks.get(endIndex);
3990            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3991                    + endIndex + " " + cur);
3992            if (cur == top) {
3993                // Verify start of the chain.
3994                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3995                    Slog.wtf(TAG, "Bad chain @" + endIndex
3996                            + ": first task has next affiliate: " + prev);
3997                    sane = false;
3998                    break;
3999                }
4000            } else {
4001                // Verify middle of the chain's next points back to the one before.
4002                if (cur.mNextAffiliate != prev
4003                        || cur.mNextAffiliateTaskId != prev.taskId) {
4004                    Slog.wtf(TAG, "Bad chain @" + endIndex
4005                            + ": middle task " + cur + " @" + endIndex
4006                            + " has bad next affiliate "
4007                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4008                            + ", expected " + prev);
4009                    sane = false;
4010                    break;
4011                }
4012            }
4013            if (cur.mPrevAffiliateTaskId == -1) {
4014                // Chain ends here.
4015                if (cur.mPrevAffiliate != null) {
4016                    Slog.wtf(TAG, "Bad chain @" + endIndex
4017                            + ": last task " + cur + " has previous affiliate "
4018                            + cur.mPrevAffiliate);
4019                    sane = false;
4020                }
4021                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4022                break;
4023            } else {
4024                // Verify middle of the chain's prev points to a valid item.
4025                if (cur.mPrevAffiliate == null) {
4026                    Slog.wtf(TAG, "Bad chain @" + endIndex
4027                            + ": task " + cur + " has previous affiliate "
4028                            + cur.mPrevAffiliate + " but should be id "
4029                            + cur.mPrevAffiliate);
4030                    sane = false;
4031                    break;
4032                }
4033            }
4034            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4035                Slog.wtf(TAG, "Bad chain @" + endIndex
4036                        + ": task " + cur + " has affiliated id "
4037                        + cur.mAffiliatedTaskId + " but should be "
4038                        + task.mAffiliatedTaskId);
4039                sane = false;
4040                break;
4041            }
4042            prev = cur;
4043            endIndex++;
4044            if (endIndex >= N) {
4045                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4046                        + ": last task " + prev);
4047                sane = false;
4048                break;
4049            }
4050        }
4051        if (sane) {
4052            if (endIndex < taskIndex) {
4053                Slog.wtf(TAG, "Bad chain @" + endIndex
4054                        + ": did not extend to task " + task + " @" + taskIndex);
4055                sane = false;
4056            }
4057        }
4058        if (sane) {
4059            // All looks good, we can just move all of the affiliated tasks
4060            // to the top.
4061            for (int i=topIndex; i<=endIndex; i++) {
4062                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4063                        + " from " + i + " to " + (i-topIndex));
4064                TaskRecord cur = mRecentTasks.remove(i);
4065                mRecentTasks.add(i-topIndex, cur);
4066            }
4067            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4068                    + " to " + endIndex);
4069            return true;
4070        }
4071
4072        // Whoops, couldn't do it.
4073        return false;
4074    }
4075
4076    final void addRecentTaskLocked(TaskRecord task) {
4077        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4078                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4079
4080        int N = mRecentTasks.size();
4081        // Quick case: check if the top-most recent task is the same.
4082        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4083            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4084            return;
4085        }
4086        // Another quick case: check if this is part of a set of affiliated
4087        // tasks that are at the top.
4088        if (isAffiliated && N > 0 && task.inRecents
4089                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4090            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4091                    + " at top when adding " + task);
4092            return;
4093        }
4094        // Another quick case: never add voice sessions.
4095        if (task.voiceSession != null) {
4096            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4097            return;
4098        }
4099
4100        boolean needAffiliationFix = false;
4101
4102        // Slightly less quick case: the task is already in recents, so all we need
4103        // to do is move it.
4104        if (task.inRecents) {
4105            int taskIndex = mRecentTasks.indexOf(task);
4106            if (taskIndex >= 0) {
4107                if (!isAffiliated) {
4108                    // Simple case: this is not an affiliated task, so we just move it to the front.
4109                    mRecentTasks.remove(taskIndex);
4110                    mRecentTasks.add(0, task);
4111                    notifyTaskPersisterLocked(task, false);
4112                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4113                            + " from " + taskIndex);
4114                    return;
4115                } else {
4116                    // More complicated: need to keep all affiliated tasks together.
4117                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4118                        // All went well.
4119                        return;
4120                    }
4121
4122                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4123                    // everything and then go through our general path of adding a new task.
4124                    needAffiliationFix = true;
4125                }
4126            } else {
4127                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4128                needAffiliationFix = true;
4129            }
4130        }
4131
4132        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4133        trimRecentsForTask(task, true);
4134
4135        N = mRecentTasks.size();
4136        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4137            final TaskRecord tr = mRecentTasks.remove(N - 1);
4138            tr.removedFromRecents(mTaskPersister);
4139            N--;
4140        }
4141        task.inRecents = true;
4142        if (!isAffiliated || needAffiliationFix) {
4143            // If this is a simple non-affiliated task, or we had some failure trying to
4144            // handle it as part of an affilated task, then just place it at the top.
4145            mRecentTasks.add(0, task);
4146        } else if (isAffiliated) {
4147            // If this is a new affiliated task, then move all of the affiliated tasks
4148            // to the front and insert this new one.
4149            TaskRecord other = task.mNextAffiliate;
4150            if (other == null) {
4151                other = task.mPrevAffiliate;
4152            }
4153            if (other != null) {
4154                int otherIndex = mRecentTasks.indexOf(other);
4155                if (otherIndex >= 0) {
4156                    // Insert new task at appropriate location.
4157                    int taskIndex;
4158                    if (other == task.mNextAffiliate) {
4159                        // We found the index of our next affiliation, which is who is
4160                        // before us in the list, so add after that point.
4161                        taskIndex = otherIndex+1;
4162                    } else {
4163                        // We found the index of our previous affiliation, which is who is
4164                        // after us in the list, so add at their position.
4165                        taskIndex = otherIndex;
4166                    }
4167                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4168                            + taskIndex + ": " + task);
4169                    mRecentTasks.add(taskIndex, task);
4170
4171                    // Now move everything to the front.
4172                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4173                        // All went well.
4174                        return;
4175                    }
4176
4177                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4178                    // everything and then go through our general path of adding a new task.
4179                    needAffiliationFix = true;
4180                } else {
4181                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4182                            + other);
4183                    needAffiliationFix = true;
4184                }
4185            } else {
4186                if (DEBUG_RECENTS) Slog.d(TAG,
4187                        "addRecent: adding affiliated task without next/prev:" + task);
4188                needAffiliationFix = true;
4189            }
4190        }
4191        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4192
4193        if (needAffiliationFix) {
4194            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4195            cleanupRecentTasksLocked(task.userId);
4196        }
4197    }
4198
4199    /**
4200     * If needed, remove oldest existing entries in recents that are for the same kind
4201     * of task as the given one.
4202     */
4203    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4204        int N = mRecentTasks.size();
4205        final Intent intent = task.intent;
4206        final boolean document = intent != null && intent.isDocument();
4207
4208        int maxRecents = task.maxRecents - 1;
4209        for (int i=0; i<N; i++) {
4210            final TaskRecord tr = mRecentTasks.get(i);
4211            if (task != tr) {
4212                if (task.userId != tr.userId) {
4213                    continue;
4214                }
4215                if (i > MAX_RECENT_BITMAPS) {
4216                    tr.freeLastThumbnail();
4217                }
4218                final Intent trIntent = tr.intent;
4219                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4220                    (intent == null || !intent.filterEquals(trIntent))) {
4221                    continue;
4222                }
4223                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4224                if (document && trIsDocument) {
4225                    // These are the same document activity (not necessarily the same doc).
4226                    if (maxRecents > 0) {
4227                        --maxRecents;
4228                        continue;
4229                    }
4230                    // Hit the maximum number of documents for this task. Fall through
4231                    // and remove this document from recents.
4232                } else if (document || trIsDocument) {
4233                    // Only one of these is a document. Not the droid we're looking for.
4234                    continue;
4235                }
4236            }
4237
4238            if (!doTrim) {
4239                // If the caller is not actually asking for a trim, just tell them we reached
4240                // a point where the trim would happen.
4241                return i;
4242            }
4243
4244            // Either task and tr are the same or, their affinities match or their intents match
4245            // and neither of them is a document, or they are documents using the same activity
4246            // and their maxRecents has been reached.
4247            tr.disposeThumbnail();
4248            mRecentTasks.remove(i);
4249            if (task != tr) {
4250                tr.removedFromRecents(mTaskPersister);
4251            }
4252            i--;
4253            N--;
4254            if (task.intent == null) {
4255                // If the new recent task we are adding is not fully
4256                // specified, then replace it with the existing recent task.
4257                task = tr;
4258            }
4259            notifyTaskPersisterLocked(tr, false);
4260        }
4261
4262        return -1;
4263    }
4264
4265    @Override
4266    public void reportActivityFullyDrawn(IBinder token) {
4267        synchronized (this) {
4268            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4269            if (r == null) {
4270                return;
4271            }
4272            r.reportFullyDrawnLocked();
4273        }
4274    }
4275
4276    @Override
4277    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4278        synchronized (this) {
4279            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4280            if (r == null) {
4281                return;
4282            }
4283            final long origId = Binder.clearCallingIdentity();
4284            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4285            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4286                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4287            if (config != null) {
4288                r.frozenBeforeDestroy = true;
4289                if (!updateConfigurationLocked(config, r, false, false)) {
4290                    mStackSupervisor.resumeTopActivitiesLocked();
4291                }
4292            }
4293            Binder.restoreCallingIdentity(origId);
4294        }
4295    }
4296
4297    @Override
4298    public int getRequestedOrientation(IBinder token) {
4299        synchronized (this) {
4300            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4301            if (r == null) {
4302                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4303            }
4304            return mWindowManager.getAppOrientation(r.appToken);
4305        }
4306    }
4307
4308    /**
4309     * This is the internal entry point for handling Activity.finish().
4310     *
4311     * @param token The Binder token referencing the Activity we want to finish.
4312     * @param resultCode Result code, if any, from this Activity.
4313     * @param resultData Result data (Intent), if any, from this Activity.
4314     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4315     *            the root Activity in the task.
4316     *
4317     * @return Returns true if the activity successfully finished, or false if it is still running.
4318     */
4319    @Override
4320    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4321            boolean finishTask) {
4322        // Refuse possible leaked file descriptors
4323        if (resultData != null && resultData.hasFileDescriptors() == true) {
4324            throw new IllegalArgumentException("File descriptors passed in Intent");
4325        }
4326
4327        synchronized(this) {
4328            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4329            if (r == null) {
4330                return true;
4331            }
4332            // Keep track of the root activity of the task before we finish it
4333            TaskRecord tr = r.task;
4334            ActivityRecord rootR = tr.getRootActivity();
4335            // Do not allow task to finish in Lock Task mode.
4336            if (tr == mStackSupervisor.mLockTaskModeTask) {
4337                if (rootR == r) {
4338                    mStackSupervisor.showLockTaskToast();
4339                    return false;
4340                }
4341            }
4342            if (mController != null) {
4343                // Find the first activity that is not finishing.
4344                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4345                if (next != null) {
4346                    // ask watcher if this is allowed
4347                    boolean resumeOK = true;
4348                    try {
4349                        resumeOK = mController.activityResuming(next.packageName);
4350                    } catch (RemoteException e) {
4351                        mController = null;
4352                        Watchdog.getInstance().setActivityController(null);
4353                    }
4354
4355                    if (!resumeOK) {
4356                        return false;
4357                    }
4358                }
4359            }
4360            final long origId = Binder.clearCallingIdentity();
4361            try {
4362                boolean res;
4363                if (finishTask && r == rootR) {
4364                    // If requested, remove the task that is associated to this activity only if it
4365                    // was the root activity in the task.  The result code and data is ignored because
4366                    // we don't support returning them across task boundaries.
4367                    res = removeTaskByIdLocked(tr.taskId, 0);
4368                } else {
4369                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4370                            resultData, "app-request", true);
4371                }
4372                return res;
4373            } finally {
4374                Binder.restoreCallingIdentity(origId);
4375            }
4376        }
4377    }
4378
4379    @Override
4380    public final void finishHeavyWeightApp() {
4381        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4382                != PackageManager.PERMISSION_GRANTED) {
4383            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4384                    + Binder.getCallingPid()
4385                    + ", uid=" + Binder.getCallingUid()
4386                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4387            Slog.w(TAG, msg);
4388            throw new SecurityException(msg);
4389        }
4390
4391        synchronized(this) {
4392            if (mHeavyWeightProcess == null) {
4393                return;
4394            }
4395
4396            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4397                    mHeavyWeightProcess.activities);
4398            for (int i=0; i<activities.size(); i++) {
4399                ActivityRecord r = activities.get(i);
4400                if (!r.finishing) {
4401                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4402                            null, "finish-heavy", true);
4403                }
4404            }
4405
4406            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4407                    mHeavyWeightProcess.userId, 0));
4408            mHeavyWeightProcess = null;
4409        }
4410    }
4411
4412    @Override
4413    public void crashApplication(int uid, int initialPid, String packageName,
4414            String message) {
4415        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4416                != PackageManager.PERMISSION_GRANTED) {
4417            String msg = "Permission Denial: crashApplication() from pid="
4418                    + Binder.getCallingPid()
4419                    + ", uid=" + Binder.getCallingUid()
4420                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4421            Slog.w(TAG, msg);
4422            throw new SecurityException(msg);
4423        }
4424
4425        synchronized(this) {
4426            ProcessRecord proc = null;
4427
4428            // Figure out which process to kill.  We don't trust that initialPid
4429            // still has any relation to current pids, so must scan through the
4430            // list.
4431            synchronized (mPidsSelfLocked) {
4432                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4433                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4434                    if (p.uid != uid) {
4435                        continue;
4436                    }
4437                    if (p.pid == initialPid) {
4438                        proc = p;
4439                        break;
4440                    }
4441                    if (p.pkgList.containsKey(packageName)) {
4442                        proc = p;
4443                    }
4444                }
4445            }
4446
4447            if (proc == null) {
4448                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4449                        + " initialPid=" + initialPid
4450                        + " packageName=" + packageName);
4451                return;
4452            }
4453
4454            if (proc.thread != null) {
4455                if (proc.pid == Process.myPid()) {
4456                    Log.w(TAG, "crashApplication: trying to crash self!");
4457                    return;
4458                }
4459                long ident = Binder.clearCallingIdentity();
4460                try {
4461                    proc.thread.scheduleCrash(message);
4462                } catch (RemoteException e) {
4463                }
4464                Binder.restoreCallingIdentity(ident);
4465            }
4466        }
4467    }
4468
4469    @Override
4470    public final void finishSubActivity(IBinder token, String resultWho,
4471            int requestCode) {
4472        synchronized(this) {
4473            final long origId = Binder.clearCallingIdentity();
4474            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4475            if (r != null) {
4476                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4477            }
4478            Binder.restoreCallingIdentity(origId);
4479        }
4480    }
4481
4482    @Override
4483    public boolean finishActivityAffinity(IBinder token) {
4484        synchronized(this) {
4485            final long origId = Binder.clearCallingIdentity();
4486            try {
4487                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4488
4489                ActivityRecord rootR = r.task.getRootActivity();
4490                // Do not allow task to finish in Lock Task mode.
4491                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4492                    if (rootR == r) {
4493                        mStackSupervisor.showLockTaskToast();
4494                        return false;
4495                    }
4496                }
4497                boolean res = false;
4498                if (r != null) {
4499                    res = r.task.stack.finishActivityAffinityLocked(r);
4500                }
4501                return res;
4502            } finally {
4503                Binder.restoreCallingIdentity(origId);
4504            }
4505        }
4506    }
4507
4508    @Override
4509    public void finishVoiceTask(IVoiceInteractionSession session) {
4510        synchronized(this) {
4511            final long origId = Binder.clearCallingIdentity();
4512            try {
4513                mStackSupervisor.finishVoiceTask(session);
4514            } finally {
4515                Binder.restoreCallingIdentity(origId);
4516            }
4517        }
4518
4519    }
4520
4521    @Override
4522    public boolean releaseActivityInstance(IBinder token) {
4523        synchronized(this) {
4524            final long origId = Binder.clearCallingIdentity();
4525            try {
4526                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4527                if (r.task == null || r.task.stack == null) {
4528                    return false;
4529                }
4530                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4531            } finally {
4532                Binder.restoreCallingIdentity(origId);
4533            }
4534        }
4535    }
4536
4537    @Override
4538    public void releaseSomeActivities(IApplicationThread appInt) {
4539        synchronized(this) {
4540            final long origId = Binder.clearCallingIdentity();
4541            try {
4542                ProcessRecord app = getRecordForAppLocked(appInt);
4543                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4544            } finally {
4545                Binder.restoreCallingIdentity(origId);
4546            }
4547        }
4548    }
4549
4550    @Override
4551    public boolean willActivityBeVisible(IBinder token) {
4552        synchronized(this) {
4553            ActivityStack stack = ActivityRecord.getStackLocked(token);
4554            if (stack != null) {
4555                return stack.willActivityBeVisibleLocked(token);
4556            }
4557            return false;
4558        }
4559    }
4560
4561    @Override
4562    public void overridePendingTransition(IBinder token, String packageName,
4563            int enterAnim, int exitAnim) {
4564        synchronized(this) {
4565            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4566            if (self == null) {
4567                return;
4568            }
4569
4570            final long origId = Binder.clearCallingIdentity();
4571
4572            if (self.state == ActivityState.RESUMED
4573                    || self.state == ActivityState.PAUSING) {
4574                mWindowManager.overridePendingAppTransition(packageName,
4575                        enterAnim, exitAnim, null);
4576            }
4577
4578            Binder.restoreCallingIdentity(origId);
4579        }
4580    }
4581
4582    /**
4583     * Main function for removing an existing process from the activity manager
4584     * as a result of that process going away.  Clears out all connections
4585     * to the process.
4586     */
4587    private final void handleAppDiedLocked(ProcessRecord app,
4588            boolean restarting, boolean allowRestart) {
4589        int pid = app.pid;
4590        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4591        if (!restarting) {
4592            removeLruProcessLocked(app);
4593            if (pid > 0) {
4594                ProcessList.remove(pid);
4595            }
4596        }
4597
4598        if (mProfileProc == app) {
4599            clearProfilerLocked();
4600        }
4601
4602        // Remove this application's activities from active lists.
4603        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4604
4605        app.activities.clear();
4606
4607        if (app.instrumentationClass != null) {
4608            Slog.w(TAG, "Crash of app " + app.processName
4609                  + " running instrumentation " + app.instrumentationClass);
4610            Bundle info = new Bundle();
4611            info.putString("shortMsg", "Process crashed.");
4612            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4613        }
4614
4615        if (!restarting) {
4616            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4617                // If there was nothing to resume, and we are not already
4618                // restarting this process, but there is a visible activity that
4619                // is hosted by the process...  then make sure all visible
4620                // activities are running, taking care of restarting this
4621                // process.
4622                if (hasVisibleActivities) {
4623                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4624                }
4625            }
4626        }
4627    }
4628
4629    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4630        IBinder threadBinder = thread.asBinder();
4631        // Find the application record.
4632        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4633            ProcessRecord rec = mLruProcesses.get(i);
4634            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4635                return i;
4636            }
4637        }
4638        return -1;
4639    }
4640
4641    final ProcessRecord getRecordForAppLocked(
4642            IApplicationThread thread) {
4643        if (thread == null) {
4644            return null;
4645        }
4646
4647        int appIndex = getLRURecordIndexForAppLocked(thread);
4648        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4649    }
4650
4651    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4652        // If there are no longer any background processes running,
4653        // and the app that died was not running instrumentation,
4654        // then tell everyone we are now low on memory.
4655        boolean haveBg = false;
4656        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4657            ProcessRecord rec = mLruProcesses.get(i);
4658            if (rec.thread != null
4659                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4660                haveBg = true;
4661                break;
4662            }
4663        }
4664
4665        if (!haveBg) {
4666            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4667            if (doReport) {
4668                long now = SystemClock.uptimeMillis();
4669                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4670                    doReport = false;
4671                } else {
4672                    mLastMemUsageReportTime = now;
4673                }
4674            }
4675            final ArrayList<ProcessMemInfo> memInfos
4676                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4677            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4678            long now = SystemClock.uptimeMillis();
4679            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4680                ProcessRecord rec = mLruProcesses.get(i);
4681                if (rec == dyingProc || rec.thread == null) {
4682                    continue;
4683                }
4684                if (doReport) {
4685                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4686                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4687                }
4688                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4689                    // The low memory report is overriding any current
4690                    // state for a GC request.  Make sure to do
4691                    // heavy/important/visible/foreground processes first.
4692                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4693                        rec.lastRequestedGc = 0;
4694                    } else {
4695                        rec.lastRequestedGc = rec.lastLowMemory;
4696                    }
4697                    rec.reportLowMemory = true;
4698                    rec.lastLowMemory = now;
4699                    mProcessesToGc.remove(rec);
4700                    addProcessToGcListLocked(rec);
4701                }
4702            }
4703            if (doReport) {
4704                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4705                mHandler.sendMessage(msg);
4706            }
4707            scheduleAppGcsLocked();
4708        }
4709    }
4710
4711    final void appDiedLocked(ProcessRecord app) {
4712       appDiedLocked(app, app.pid, app.thread);
4713    }
4714
4715    final void appDiedLocked(ProcessRecord app, int pid,
4716            IApplicationThread thread) {
4717
4718        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4719        synchronized (stats) {
4720            stats.noteProcessDiedLocked(app.info.uid, pid);
4721        }
4722
4723        Process.killProcessGroup(app.info.uid, pid);
4724
4725        // Clean up already done if the process has been re-started.
4726        if (app.pid == pid && app.thread != null &&
4727                app.thread.asBinder() == thread.asBinder()) {
4728            boolean doLowMem = app.instrumentationClass == null;
4729            boolean doOomAdj = doLowMem;
4730            if (!app.killedByAm) {
4731                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4732                        + ") has died.");
4733                mAllowLowerMemLevel = true;
4734            } else {
4735                // Note that we always want to do oom adj to update our state with the
4736                // new number of procs.
4737                mAllowLowerMemLevel = false;
4738                doLowMem = false;
4739            }
4740            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4741            if (DEBUG_CLEANUP) Slog.v(
4742                TAG, "Dying app: " + app + ", pid: " + pid
4743                + ", thread: " + thread.asBinder());
4744            handleAppDiedLocked(app, false, true);
4745
4746            if (doOomAdj) {
4747                updateOomAdjLocked();
4748            }
4749            if (doLowMem) {
4750                doLowMemReportIfNeededLocked(app);
4751            }
4752        } else if (app.pid != pid) {
4753            // A new process has already been started.
4754            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4755                    + ") has died and restarted (pid " + app.pid + ").");
4756            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4757        } else if (DEBUG_PROCESSES) {
4758            Slog.d(TAG, "Received spurious death notification for thread "
4759                    + thread.asBinder());
4760        }
4761    }
4762
4763    /**
4764     * If a stack trace dump file is configured, dump process stack traces.
4765     * @param clearTraces causes the dump file to be erased prior to the new
4766     *    traces being written, if true; when false, the new traces will be
4767     *    appended to any existing file content.
4768     * @param firstPids of dalvik VM processes to dump stack traces for first
4769     * @param lastPids of dalvik VM processes to dump stack traces for last
4770     * @param nativeProcs optional list of native process names to dump stack crawls
4771     * @return file containing stack traces, or null if no dump file is configured
4772     */
4773    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4774            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4775        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4776        if (tracesPath == null || tracesPath.length() == 0) {
4777            return null;
4778        }
4779
4780        File tracesFile = new File(tracesPath);
4781        try {
4782            File tracesDir = tracesFile.getParentFile();
4783            if (!tracesDir.exists()) {
4784                tracesFile.mkdirs();
4785                if (!SELinux.restorecon(tracesDir)) {
4786                    return null;
4787                }
4788            }
4789            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4790
4791            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4792            tracesFile.createNewFile();
4793            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4794        } catch (IOException e) {
4795            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4796            return null;
4797        }
4798
4799        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4800        return tracesFile;
4801    }
4802
4803    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4804            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4805        // Use a FileObserver to detect when traces finish writing.
4806        // The order of traces is considered important to maintain for legibility.
4807        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4808            @Override
4809            public synchronized void onEvent(int event, String path) { notify(); }
4810        };
4811
4812        try {
4813            observer.startWatching();
4814
4815            // First collect all of the stacks of the most important pids.
4816            if (firstPids != null) {
4817                try {
4818                    int num = firstPids.size();
4819                    for (int i = 0; i < num; i++) {
4820                        synchronized (observer) {
4821                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4822                            observer.wait(200);  // Wait for write-close, give up after 200msec
4823                        }
4824                    }
4825                } catch (InterruptedException e) {
4826                    Log.wtf(TAG, e);
4827                }
4828            }
4829
4830            // Next collect the stacks of the native pids
4831            if (nativeProcs != null) {
4832                int[] pids = Process.getPidsForCommands(nativeProcs);
4833                if (pids != null) {
4834                    for (int pid : pids) {
4835                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4836                    }
4837                }
4838            }
4839
4840            // Lastly, measure CPU usage.
4841            if (processCpuTracker != null) {
4842                processCpuTracker.init();
4843                System.gc();
4844                processCpuTracker.update();
4845                try {
4846                    synchronized (processCpuTracker) {
4847                        processCpuTracker.wait(500); // measure over 1/2 second.
4848                    }
4849                } catch (InterruptedException e) {
4850                }
4851                processCpuTracker.update();
4852
4853                // We'll take the stack crawls of just the top apps using CPU.
4854                final int N = processCpuTracker.countWorkingStats();
4855                int numProcs = 0;
4856                for (int i=0; i<N && numProcs<5; i++) {
4857                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4858                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4859                        numProcs++;
4860                        try {
4861                            synchronized (observer) {
4862                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4863                                observer.wait(200);  // Wait for write-close, give up after 200msec
4864                            }
4865                        } catch (InterruptedException e) {
4866                            Log.wtf(TAG, e);
4867                        }
4868
4869                    }
4870                }
4871            }
4872        } finally {
4873            observer.stopWatching();
4874        }
4875    }
4876
4877    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4878        if (true || IS_USER_BUILD) {
4879            return;
4880        }
4881        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4882        if (tracesPath == null || tracesPath.length() == 0) {
4883            return;
4884        }
4885
4886        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4887        StrictMode.allowThreadDiskWrites();
4888        try {
4889            final File tracesFile = new File(tracesPath);
4890            final File tracesDir = tracesFile.getParentFile();
4891            final File tracesTmp = new File(tracesDir, "__tmp__");
4892            try {
4893                if (!tracesDir.exists()) {
4894                    tracesFile.mkdirs();
4895                    if (!SELinux.restorecon(tracesDir.getPath())) {
4896                        return;
4897                    }
4898                }
4899                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4900
4901                if (tracesFile.exists()) {
4902                    tracesTmp.delete();
4903                    tracesFile.renameTo(tracesTmp);
4904                }
4905                StringBuilder sb = new StringBuilder();
4906                Time tobj = new Time();
4907                tobj.set(System.currentTimeMillis());
4908                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4909                sb.append(": ");
4910                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4911                sb.append(" since ");
4912                sb.append(msg);
4913                FileOutputStream fos = new FileOutputStream(tracesFile);
4914                fos.write(sb.toString().getBytes());
4915                if (app == null) {
4916                    fos.write("\n*** No application process!".getBytes());
4917                }
4918                fos.close();
4919                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4920            } catch (IOException e) {
4921                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4922                return;
4923            }
4924
4925            if (app != null) {
4926                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4927                firstPids.add(app.pid);
4928                dumpStackTraces(tracesPath, firstPids, null, null, null);
4929            }
4930
4931            File lastTracesFile = null;
4932            File curTracesFile = null;
4933            for (int i=9; i>=0; i--) {
4934                String name = String.format(Locale.US, "slow%02d.txt", i);
4935                curTracesFile = new File(tracesDir, name);
4936                if (curTracesFile.exists()) {
4937                    if (lastTracesFile != null) {
4938                        curTracesFile.renameTo(lastTracesFile);
4939                    } else {
4940                        curTracesFile.delete();
4941                    }
4942                }
4943                lastTracesFile = curTracesFile;
4944            }
4945            tracesFile.renameTo(curTracesFile);
4946            if (tracesTmp.exists()) {
4947                tracesTmp.renameTo(tracesFile);
4948            }
4949        } finally {
4950            StrictMode.setThreadPolicy(oldPolicy);
4951        }
4952    }
4953
4954    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4955            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4956        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4957        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4958
4959        if (mController != null) {
4960            try {
4961                // 0 == continue, -1 = kill process immediately
4962                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4963                if (res < 0 && app.pid != MY_PID) {
4964                    app.kill("anr", true);
4965                }
4966            } catch (RemoteException e) {
4967                mController = null;
4968                Watchdog.getInstance().setActivityController(null);
4969            }
4970        }
4971
4972        long anrTime = SystemClock.uptimeMillis();
4973        if (MONITOR_CPU_USAGE) {
4974            updateCpuStatsNow();
4975        }
4976
4977        synchronized (this) {
4978            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4979            if (mShuttingDown) {
4980                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4981                return;
4982            } else if (app.notResponding) {
4983                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4984                return;
4985            } else if (app.crashing) {
4986                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4987                return;
4988            }
4989
4990            // In case we come through here for the same app before completing
4991            // this one, mark as anring now so we will bail out.
4992            app.notResponding = true;
4993
4994            // Log the ANR to the event log.
4995            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4996                    app.processName, app.info.flags, annotation);
4997
4998            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4999            firstPids.add(app.pid);
5000
5001            int parentPid = app.pid;
5002            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5003            if (parentPid != app.pid) firstPids.add(parentPid);
5004
5005            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5006
5007            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5008                ProcessRecord r = mLruProcesses.get(i);
5009                if (r != null && r.thread != null) {
5010                    int pid = r.pid;
5011                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5012                        if (r.persistent) {
5013                            firstPids.add(pid);
5014                        } else {
5015                            lastPids.put(pid, Boolean.TRUE);
5016                        }
5017                    }
5018                }
5019            }
5020        }
5021
5022        // Log the ANR to the main log.
5023        StringBuilder info = new StringBuilder();
5024        info.setLength(0);
5025        info.append("ANR in ").append(app.processName);
5026        if (activity != null && activity.shortComponentName != null) {
5027            info.append(" (").append(activity.shortComponentName).append(")");
5028        }
5029        info.append("\n");
5030        info.append("PID: ").append(app.pid).append("\n");
5031        if (annotation != null) {
5032            info.append("Reason: ").append(annotation).append("\n");
5033        }
5034        if (parent != null && parent != activity) {
5035            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5036        }
5037
5038        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5039
5040        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5041                NATIVE_STACKS_OF_INTEREST);
5042
5043        String cpuInfo = null;
5044        if (MONITOR_CPU_USAGE) {
5045            updateCpuStatsNow();
5046            synchronized (mProcessCpuThread) {
5047                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5048            }
5049            info.append(processCpuTracker.printCurrentLoad());
5050            info.append(cpuInfo);
5051        }
5052
5053        info.append(processCpuTracker.printCurrentState(anrTime));
5054
5055        Slog.e(TAG, info.toString());
5056        if (tracesFile == null) {
5057            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5058            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5059        }
5060
5061        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5062                cpuInfo, tracesFile, null);
5063
5064        if (mController != null) {
5065            try {
5066                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5067                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5068                if (res != 0) {
5069                    if (res < 0 && app.pid != MY_PID) {
5070                        app.kill("anr", true);
5071                    } else {
5072                        synchronized (this) {
5073                            mServices.scheduleServiceTimeoutLocked(app);
5074                        }
5075                    }
5076                    return;
5077                }
5078            } catch (RemoteException e) {
5079                mController = null;
5080                Watchdog.getInstance().setActivityController(null);
5081            }
5082        }
5083
5084        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5085        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5086                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5087
5088        synchronized (this) {
5089            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5090                app.kill("bg anr", true);
5091                return;
5092            }
5093
5094            // Set the app's notResponding state, and look up the errorReportReceiver
5095            makeAppNotRespondingLocked(app,
5096                    activity != null ? activity.shortComponentName : null,
5097                    annotation != null ? "ANR " + annotation : "ANR",
5098                    info.toString());
5099
5100            // Bring up the infamous App Not Responding dialog
5101            Message msg = Message.obtain();
5102            HashMap<String, Object> map = new HashMap<String, Object>();
5103            msg.what = SHOW_NOT_RESPONDING_MSG;
5104            msg.obj = map;
5105            msg.arg1 = aboveSystem ? 1 : 0;
5106            map.put("app", app);
5107            if (activity != null) {
5108                map.put("activity", activity);
5109            }
5110
5111            mHandler.sendMessage(msg);
5112        }
5113    }
5114
5115    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5116        if (!mLaunchWarningShown) {
5117            mLaunchWarningShown = true;
5118            mHandler.post(new Runnable() {
5119                @Override
5120                public void run() {
5121                    synchronized (ActivityManagerService.this) {
5122                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5123                        d.show();
5124                        mHandler.postDelayed(new Runnable() {
5125                            @Override
5126                            public void run() {
5127                                synchronized (ActivityManagerService.this) {
5128                                    d.dismiss();
5129                                    mLaunchWarningShown = false;
5130                                }
5131                            }
5132                        }, 4000);
5133                    }
5134                }
5135            });
5136        }
5137    }
5138
5139    @Override
5140    public boolean clearApplicationUserData(final String packageName,
5141            final IPackageDataObserver observer, int userId) {
5142        enforceNotIsolatedCaller("clearApplicationUserData");
5143        int uid = Binder.getCallingUid();
5144        int pid = Binder.getCallingPid();
5145        userId = handleIncomingUser(pid, uid,
5146                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5147        long callingId = Binder.clearCallingIdentity();
5148        try {
5149            IPackageManager pm = AppGlobals.getPackageManager();
5150            int pkgUid = -1;
5151            synchronized(this) {
5152                try {
5153                    pkgUid = pm.getPackageUid(packageName, userId);
5154                } catch (RemoteException e) {
5155                }
5156                if (pkgUid == -1) {
5157                    Slog.w(TAG, "Invalid packageName: " + packageName);
5158                    if (observer != null) {
5159                        try {
5160                            observer.onRemoveCompleted(packageName, false);
5161                        } catch (RemoteException e) {
5162                            Slog.i(TAG, "Observer no longer exists.");
5163                        }
5164                    }
5165                    return false;
5166                }
5167                if (uid == pkgUid || checkComponentPermission(
5168                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5169                        pid, uid, -1, true)
5170                        == PackageManager.PERMISSION_GRANTED) {
5171                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5172                } else {
5173                    throw new SecurityException("PID " + pid + " does not have permission "
5174                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5175                                    + " of package " + packageName);
5176                }
5177
5178                // Remove all tasks match the cleared application package and user
5179                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5180                    final TaskRecord tr = mRecentTasks.get(i);
5181                    final String taskPackageName =
5182                            tr.getBaseIntent().getComponent().getPackageName();
5183                    if (tr.userId != userId) continue;
5184                    if (!taskPackageName.equals(packageName)) continue;
5185                    removeTaskByIdLocked(tr.taskId, 0);
5186                }
5187            }
5188
5189            try {
5190                // Clear application user data
5191                pm.clearApplicationUserData(packageName, observer, userId);
5192
5193                synchronized(this) {
5194                    // Remove all permissions granted from/to this package
5195                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5196                }
5197
5198                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5199                        Uri.fromParts("package", packageName, null));
5200                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5201                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5202                        null, null, 0, null, null, null, false, false, userId);
5203            } catch (RemoteException e) {
5204            }
5205        } finally {
5206            Binder.restoreCallingIdentity(callingId);
5207        }
5208        return true;
5209    }
5210
5211    @Override
5212    public void killBackgroundProcesses(final String packageName, int userId) {
5213        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5214                != PackageManager.PERMISSION_GRANTED &&
5215                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5216                        != PackageManager.PERMISSION_GRANTED) {
5217            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5218                    + Binder.getCallingPid()
5219                    + ", uid=" + Binder.getCallingUid()
5220                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5221            Slog.w(TAG, msg);
5222            throw new SecurityException(msg);
5223        }
5224
5225        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5226                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5227        long callingId = Binder.clearCallingIdentity();
5228        try {
5229            IPackageManager pm = AppGlobals.getPackageManager();
5230            synchronized(this) {
5231                int appId = -1;
5232                try {
5233                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5234                } catch (RemoteException e) {
5235                }
5236                if (appId == -1) {
5237                    Slog.w(TAG, "Invalid packageName: " + packageName);
5238                    return;
5239                }
5240                killPackageProcessesLocked(packageName, appId, userId,
5241                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5242            }
5243        } finally {
5244            Binder.restoreCallingIdentity(callingId);
5245        }
5246    }
5247
5248    @Override
5249    public void killAllBackgroundProcesses() {
5250        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5251                != PackageManager.PERMISSION_GRANTED) {
5252            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5253                    + Binder.getCallingPid()
5254                    + ", uid=" + Binder.getCallingUid()
5255                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5256            Slog.w(TAG, msg);
5257            throw new SecurityException(msg);
5258        }
5259
5260        long callingId = Binder.clearCallingIdentity();
5261        try {
5262            synchronized(this) {
5263                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5264                final int NP = mProcessNames.getMap().size();
5265                for (int ip=0; ip<NP; ip++) {
5266                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5267                    final int NA = apps.size();
5268                    for (int ia=0; ia<NA; ia++) {
5269                        ProcessRecord app = apps.valueAt(ia);
5270                        if (app.persistent) {
5271                            // we don't kill persistent processes
5272                            continue;
5273                        }
5274                        if (app.removed) {
5275                            procs.add(app);
5276                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5277                            app.removed = true;
5278                            procs.add(app);
5279                        }
5280                    }
5281                }
5282
5283                int N = procs.size();
5284                for (int i=0; i<N; i++) {
5285                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5286                }
5287                mAllowLowerMemLevel = true;
5288                updateOomAdjLocked();
5289                doLowMemReportIfNeededLocked(null);
5290            }
5291        } finally {
5292            Binder.restoreCallingIdentity(callingId);
5293        }
5294    }
5295
5296    @Override
5297    public void forceStopPackage(final String packageName, int userId) {
5298        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5299                != PackageManager.PERMISSION_GRANTED) {
5300            String msg = "Permission Denial: forceStopPackage() from pid="
5301                    + Binder.getCallingPid()
5302                    + ", uid=" + Binder.getCallingUid()
5303                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5304            Slog.w(TAG, msg);
5305            throw new SecurityException(msg);
5306        }
5307        final int callingPid = Binder.getCallingPid();
5308        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5309                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5310        long callingId = Binder.clearCallingIdentity();
5311        try {
5312            IPackageManager pm = AppGlobals.getPackageManager();
5313            synchronized(this) {
5314                int[] users = userId == UserHandle.USER_ALL
5315                        ? getUsersLocked() : new int[] { userId };
5316                for (int user : users) {
5317                    int pkgUid = -1;
5318                    try {
5319                        pkgUid = pm.getPackageUid(packageName, user);
5320                    } catch (RemoteException e) {
5321                    }
5322                    if (pkgUid == -1) {
5323                        Slog.w(TAG, "Invalid packageName: " + packageName);
5324                        continue;
5325                    }
5326                    try {
5327                        pm.setPackageStoppedState(packageName, true, user);
5328                    } catch (RemoteException e) {
5329                    } catch (IllegalArgumentException e) {
5330                        Slog.w(TAG, "Failed trying to unstop package "
5331                                + packageName + ": " + e);
5332                    }
5333                    if (isUserRunningLocked(user, false)) {
5334                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5335                    }
5336                }
5337            }
5338        } finally {
5339            Binder.restoreCallingIdentity(callingId);
5340        }
5341    }
5342
5343    @Override
5344    public void addPackageDependency(String packageName) {
5345        synchronized (this) {
5346            int callingPid = Binder.getCallingPid();
5347            if (callingPid == Process.myPid()) {
5348                //  Yeah, um, no.
5349                Slog.w(TAG, "Can't addPackageDependency on system process");
5350                return;
5351            }
5352            ProcessRecord proc;
5353            synchronized (mPidsSelfLocked) {
5354                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5355            }
5356            if (proc != null) {
5357                if (proc.pkgDeps == null) {
5358                    proc.pkgDeps = new ArraySet<String>(1);
5359                }
5360                proc.pkgDeps.add(packageName);
5361            }
5362        }
5363    }
5364
5365    /*
5366     * The pkg name and app id have to be specified.
5367     */
5368    @Override
5369    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5370        if (pkg == null) {
5371            return;
5372        }
5373        // Make sure the uid is valid.
5374        if (appid < 0) {
5375            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5376            return;
5377        }
5378        int callerUid = Binder.getCallingUid();
5379        // Only the system server can kill an application
5380        if (callerUid == Process.SYSTEM_UID) {
5381            // Post an aysnc message to kill the application
5382            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5383            msg.arg1 = appid;
5384            msg.arg2 = 0;
5385            Bundle bundle = new Bundle();
5386            bundle.putString("pkg", pkg);
5387            bundle.putString("reason", reason);
5388            msg.obj = bundle;
5389            mHandler.sendMessage(msg);
5390        } else {
5391            throw new SecurityException(callerUid + " cannot kill pkg: " +
5392                    pkg);
5393        }
5394    }
5395
5396    @Override
5397    public void closeSystemDialogs(String reason) {
5398        enforceNotIsolatedCaller("closeSystemDialogs");
5399
5400        final int pid = Binder.getCallingPid();
5401        final int uid = Binder.getCallingUid();
5402        final long origId = Binder.clearCallingIdentity();
5403        try {
5404            synchronized (this) {
5405                // Only allow this from foreground processes, so that background
5406                // applications can't abuse it to prevent system UI from being shown.
5407                if (uid >= Process.FIRST_APPLICATION_UID) {
5408                    ProcessRecord proc;
5409                    synchronized (mPidsSelfLocked) {
5410                        proc = mPidsSelfLocked.get(pid);
5411                    }
5412                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5413                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5414                                + " from background process " + proc);
5415                        return;
5416                    }
5417                }
5418                closeSystemDialogsLocked(reason);
5419            }
5420        } finally {
5421            Binder.restoreCallingIdentity(origId);
5422        }
5423    }
5424
5425    void closeSystemDialogsLocked(String reason) {
5426        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5427        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5428                | Intent.FLAG_RECEIVER_FOREGROUND);
5429        if (reason != null) {
5430            intent.putExtra("reason", reason);
5431        }
5432        mWindowManager.closeSystemDialogs(reason);
5433
5434        mStackSupervisor.closeSystemDialogsLocked();
5435
5436        broadcastIntentLocked(null, null, intent, null,
5437                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5438                Process.SYSTEM_UID, UserHandle.USER_ALL);
5439    }
5440
5441    @Override
5442    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5443        enforceNotIsolatedCaller("getProcessMemoryInfo");
5444        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5445        for (int i=pids.length-1; i>=0; i--) {
5446            ProcessRecord proc;
5447            int oomAdj;
5448            synchronized (this) {
5449                synchronized (mPidsSelfLocked) {
5450                    proc = mPidsSelfLocked.get(pids[i]);
5451                    oomAdj = proc != null ? proc.setAdj : 0;
5452                }
5453            }
5454            infos[i] = new Debug.MemoryInfo();
5455            Debug.getMemoryInfo(pids[i], infos[i]);
5456            if (proc != null) {
5457                synchronized (this) {
5458                    if (proc.thread != null && proc.setAdj == oomAdj) {
5459                        // Record this for posterity if the process has been stable.
5460                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5461                                infos[i].getTotalUss(), false, proc.pkgList);
5462                    }
5463                }
5464            }
5465        }
5466        return infos;
5467    }
5468
5469    @Override
5470    public long[] getProcessPss(int[] pids) {
5471        enforceNotIsolatedCaller("getProcessPss");
5472        long[] pss = new long[pids.length];
5473        for (int i=pids.length-1; i>=0; i--) {
5474            ProcessRecord proc;
5475            int oomAdj;
5476            synchronized (this) {
5477                synchronized (mPidsSelfLocked) {
5478                    proc = mPidsSelfLocked.get(pids[i]);
5479                    oomAdj = proc != null ? proc.setAdj : 0;
5480                }
5481            }
5482            long[] tmpUss = new long[1];
5483            pss[i] = Debug.getPss(pids[i], tmpUss);
5484            if (proc != null) {
5485                synchronized (this) {
5486                    if (proc.thread != null && proc.setAdj == oomAdj) {
5487                        // Record this for posterity if the process has been stable.
5488                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5489                    }
5490                }
5491            }
5492        }
5493        return pss;
5494    }
5495
5496    @Override
5497    public void killApplicationProcess(String processName, int uid) {
5498        if (processName == null) {
5499            return;
5500        }
5501
5502        int callerUid = Binder.getCallingUid();
5503        // Only the system server can kill an application
5504        if (callerUid == Process.SYSTEM_UID) {
5505            synchronized (this) {
5506                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5507                if (app != null && app.thread != null) {
5508                    try {
5509                        app.thread.scheduleSuicide();
5510                    } catch (RemoteException e) {
5511                        // If the other end already died, then our work here is done.
5512                    }
5513                } else {
5514                    Slog.w(TAG, "Process/uid not found attempting kill of "
5515                            + processName + " / " + uid);
5516                }
5517            }
5518        } else {
5519            throw new SecurityException(callerUid + " cannot kill app process: " +
5520                    processName);
5521        }
5522    }
5523
5524    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5525        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5526                false, true, false, false, UserHandle.getUserId(uid), reason);
5527        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5528                Uri.fromParts("package", packageName, null));
5529        if (!mProcessesReady) {
5530            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5531                    | Intent.FLAG_RECEIVER_FOREGROUND);
5532        }
5533        intent.putExtra(Intent.EXTRA_UID, uid);
5534        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5535        broadcastIntentLocked(null, null, intent,
5536                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5537                false, false,
5538                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5539    }
5540
5541    private void forceStopUserLocked(int userId, String reason) {
5542        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5543        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5544        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5545                | Intent.FLAG_RECEIVER_FOREGROUND);
5546        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5547        broadcastIntentLocked(null, null, intent,
5548                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5549                false, false,
5550                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5551    }
5552
5553    private final boolean killPackageProcessesLocked(String packageName, int appId,
5554            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5555            boolean doit, boolean evenPersistent, String reason) {
5556        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5557
5558        // Remove all processes this package may have touched: all with the
5559        // same UID (except for the system or root user), and all whose name
5560        // matches the package name.
5561        final int NP = mProcessNames.getMap().size();
5562        for (int ip=0; ip<NP; ip++) {
5563            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5564            final int NA = apps.size();
5565            for (int ia=0; ia<NA; ia++) {
5566                ProcessRecord app = apps.valueAt(ia);
5567                if (app.persistent && !evenPersistent) {
5568                    // we don't kill persistent processes
5569                    continue;
5570                }
5571                if (app.removed) {
5572                    if (doit) {
5573                        procs.add(app);
5574                    }
5575                    continue;
5576                }
5577
5578                // Skip process if it doesn't meet our oom adj requirement.
5579                if (app.setAdj < minOomAdj) {
5580                    continue;
5581                }
5582
5583                // If no package is specified, we call all processes under the
5584                // give user id.
5585                if (packageName == null) {
5586                    if (app.userId != userId) {
5587                        continue;
5588                    }
5589                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5590                        continue;
5591                    }
5592                // Package has been specified, we want to hit all processes
5593                // that match it.  We need to qualify this by the processes
5594                // that are running under the specified app and user ID.
5595                } else {
5596                    final boolean isDep = app.pkgDeps != null
5597                            && app.pkgDeps.contains(packageName);
5598                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5599                        continue;
5600                    }
5601                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5602                        continue;
5603                    }
5604                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5605                        continue;
5606                    }
5607                }
5608
5609                // Process has passed all conditions, kill it!
5610                if (!doit) {
5611                    return true;
5612                }
5613                app.removed = true;
5614                procs.add(app);
5615            }
5616        }
5617
5618        int N = procs.size();
5619        for (int i=0; i<N; i++) {
5620            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5621        }
5622        updateOomAdjLocked();
5623        return N > 0;
5624    }
5625
5626    private final boolean forceStopPackageLocked(String name, int appId,
5627            boolean callerWillRestart, boolean purgeCache, boolean doit,
5628            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5629        int i;
5630        int N;
5631
5632        if (userId == UserHandle.USER_ALL && name == null) {
5633            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5634        }
5635
5636        if (appId < 0 && name != null) {
5637            try {
5638                appId = UserHandle.getAppId(
5639                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5640            } catch (RemoteException e) {
5641            }
5642        }
5643
5644        if (doit) {
5645            if (name != null) {
5646                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5647                        + " user=" + userId + ": " + reason);
5648            } else {
5649                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5650            }
5651
5652            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5653            for (int ip=pmap.size()-1; ip>=0; ip--) {
5654                SparseArray<Long> ba = pmap.valueAt(ip);
5655                for (i=ba.size()-1; i>=0; i--) {
5656                    boolean remove = false;
5657                    final int entUid = ba.keyAt(i);
5658                    if (name != null) {
5659                        if (userId == UserHandle.USER_ALL) {
5660                            if (UserHandle.getAppId(entUid) == appId) {
5661                                remove = true;
5662                            }
5663                        } else {
5664                            if (entUid == UserHandle.getUid(userId, appId)) {
5665                                remove = true;
5666                            }
5667                        }
5668                    } else if (UserHandle.getUserId(entUid) == userId) {
5669                        remove = true;
5670                    }
5671                    if (remove) {
5672                        ba.removeAt(i);
5673                    }
5674                }
5675                if (ba.size() == 0) {
5676                    pmap.removeAt(ip);
5677                }
5678            }
5679        }
5680
5681        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5682                -100, callerWillRestart, true, doit, evenPersistent,
5683                name == null ? ("stop user " + userId) : ("stop " + name));
5684
5685        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5686            if (!doit) {
5687                return true;
5688            }
5689            didSomething = true;
5690        }
5691
5692        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5693            if (!doit) {
5694                return true;
5695            }
5696            didSomething = true;
5697        }
5698
5699        if (name == null) {
5700            // Remove all sticky broadcasts from this user.
5701            mStickyBroadcasts.remove(userId);
5702        }
5703
5704        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5705        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5706                userId, providers)) {
5707            if (!doit) {
5708                return true;
5709            }
5710            didSomething = true;
5711        }
5712        N = providers.size();
5713        for (i=0; i<N; i++) {
5714            removeDyingProviderLocked(null, providers.get(i), true);
5715        }
5716
5717        // Remove transient permissions granted from/to this package/user
5718        removeUriPermissionsForPackageLocked(name, userId, false);
5719
5720        if (name == null || uninstalling) {
5721            // Remove pending intents.  For now we only do this when force
5722            // stopping users, because we have some problems when doing this
5723            // for packages -- app widgets are not currently cleaned up for
5724            // such packages, so they can be left with bad pending intents.
5725            if (mIntentSenderRecords.size() > 0) {
5726                Iterator<WeakReference<PendingIntentRecord>> it
5727                        = mIntentSenderRecords.values().iterator();
5728                while (it.hasNext()) {
5729                    WeakReference<PendingIntentRecord> wpir = it.next();
5730                    if (wpir == null) {
5731                        it.remove();
5732                        continue;
5733                    }
5734                    PendingIntentRecord pir = wpir.get();
5735                    if (pir == null) {
5736                        it.remove();
5737                        continue;
5738                    }
5739                    if (name == null) {
5740                        // Stopping user, remove all objects for the user.
5741                        if (pir.key.userId != userId) {
5742                            // Not the same user, skip it.
5743                            continue;
5744                        }
5745                    } else {
5746                        if (UserHandle.getAppId(pir.uid) != appId) {
5747                            // Different app id, skip it.
5748                            continue;
5749                        }
5750                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5751                            // Different user, skip it.
5752                            continue;
5753                        }
5754                        if (!pir.key.packageName.equals(name)) {
5755                            // Different package, skip it.
5756                            continue;
5757                        }
5758                    }
5759                    if (!doit) {
5760                        return true;
5761                    }
5762                    didSomething = true;
5763                    it.remove();
5764                    pir.canceled = true;
5765                    if (pir.key.activity != null) {
5766                        pir.key.activity.pendingResults.remove(pir.ref);
5767                    }
5768                }
5769            }
5770        }
5771
5772        if (doit) {
5773            if (purgeCache && name != null) {
5774                AttributeCache ac = AttributeCache.instance();
5775                if (ac != null) {
5776                    ac.removePackage(name);
5777                }
5778            }
5779            if (mBooted) {
5780                mStackSupervisor.resumeTopActivitiesLocked();
5781                mStackSupervisor.scheduleIdleLocked();
5782            }
5783        }
5784
5785        return didSomething;
5786    }
5787
5788    private final boolean removeProcessLocked(ProcessRecord app,
5789            boolean callerWillRestart, boolean allowRestart, String reason) {
5790        final String name = app.processName;
5791        final int uid = app.uid;
5792        if (DEBUG_PROCESSES) Slog.d(
5793            TAG, "Force removing proc " + app.toShortString() + " (" + name
5794            + "/" + uid + ")");
5795
5796        mProcessNames.remove(name, uid);
5797        mIsolatedProcesses.remove(app.uid);
5798        if (mHeavyWeightProcess == app) {
5799            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5800                    mHeavyWeightProcess.userId, 0));
5801            mHeavyWeightProcess = null;
5802        }
5803        boolean needRestart = false;
5804        if (app.pid > 0 && app.pid != MY_PID) {
5805            int pid = app.pid;
5806            synchronized (mPidsSelfLocked) {
5807                mPidsSelfLocked.remove(pid);
5808                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5809            }
5810            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5811            if (app.isolated) {
5812                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5813            }
5814            app.kill(reason, true);
5815            handleAppDiedLocked(app, true, allowRestart);
5816            removeLruProcessLocked(app);
5817
5818            if (app.persistent && !app.isolated) {
5819                if (!callerWillRestart) {
5820                    addAppLocked(app.info, false, null /* ABI override */);
5821                } else {
5822                    needRestart = true;
5823                }
5824            }
5825        } else {
5826            mRemovedProcesses.add(app);
5827        }
5828
5829        return needRestart;
5830    }
5831
5832    private final void processStartTimedOutLocked(ProcessRecord app) {
5833        final int pid = app.pid;
5834        boolean gone = false;
5835        synchronized (mPidsSelfLocked) {
5836            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5837            if (knownApp != null && knownApp.thread == null) {
5838                mPidsSelfLocked.remove(pid);
5839                gone = true;
5840            }
5841        }
5842
5843        if (gone) {
5844            Slog.w(TAG, "Process " + app + " failed to attach");
5845            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5846                    pid, app.uid, app.processName);
5847            mProcessNames.remove(app.processName, app.uid);
5848            mIsolatedProcesses.remove(app.uid);
5849            if (mHeavyWeightProcess == app) {
5850                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5851                        mHeavyWeightProcess.userId, 0));
5852                mHeavyWeightProcess = null;
5853            }
5854            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5855            if (app.isolated) {
5856                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5857            }
5858            // Take care of any launching providers waiting for this process.
5859            checkAppInLaunchingProvidersLocked(app, true);
5860            // Take care of any services that are waiting for the process.
5861            mServices.processStartTimedOutLocked(app);
5862            app.kill("start timeout", true);
5863            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5864                Slog.w(TAG, "Unattached app died before backup, skipping");
5865                try {
5866                    IBackupManager bm = IBackupManager.Stub.asInterface(
5867                            ServiceManager.getService(Context.BACKUP_SERVICE));
5868                    bm.agentDisconnected(app.info.packageName);
5869                } catch (RemoteException e) {
5870                    // Can't happen; the backup manager is local
5871                }
5872            }
5873            if (isPendingBroadcastProcessLocked(pid)) {
5874                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5875                skipPendingBroadcastLocked(pid);
5876            }
5877        } else {
5878            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5879        }
5880    }
5881
5882    private final boolean attachApplicationLocked(IApplicationThread thread,
5883            int pid) {
5884
5885        // Find the application record that is being attached...  either via
5886        // the pid if we are running in multiple processes, or just pull the
5887        // next app record if we are emulating process with anonymous threads.
5888        ProcessRecord app;
5889        if (pid != MY_PID && pid >= 0) {
5890            synchronized (mPidsSelfLocked) {
5891                app = mPidsSelfLocked.get(pid);
5892            }
5893        } else {
5894            app = null;
5895        }
5896
5897        if (app == null) {
5898            Slog.w(TAG, "No pending application record for pid " + pid
5899                    + " (IApplicationThread " + thread + "); dropping process");
5900            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5901            if (pid > 0 && pid != MY_PID) {
5902                Process.killProcessQuiet(pid);
5903                //TODO: Process.killProcessGroup(app.info.uid, pid);
5904            } else {
5905                try {
5906                    thread.scheduleExit();
5907                } catch (Exception e) {
5908                    // Ignore exceptions.
5909                }
5910            }
5911            return false;
5912        }
5913
5914        // If this application record is still attached to a previous
5915        // process, clean it up now.
5916        if (app.thread != null) {
5917            handleAppDiedLocked(app, true, true);
5918        }
5919
5920        // Tell the process all about itself.
5921
5922        if (localLOGV) Slog.v(
5923                TAG, "Binding process pid " + pid + " to record " + app);
5924
5925        final String processName = app.processName;
5926        try {
5927            AppDeathRecipient adr = new AppDeathRecipient(
5928                    app, pid, thread);
5929            thread.asBinder().linkToDeath(adr, 0);
5930            app.deathRecipient = adr;
5931        } catch (RemoteException e) {
5932            app.resetPackageList(mProcessStats);
5933            startProcessLocked(app, "link fail", processName);
5934            return false;
5935        }
5936
5937        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5938
5939        app.makeActive(thread, mProcessStats);
5940        app.curAdj = app.setAdj = -100;
5941        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5942        app.forcingToForeground = null;
5943        updateProcessForegroundLocked(app, false, false);
5944        app.hasShownUi = false;
5945        app.debugging = false;
5946        app.cached = false;
5947
5948        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5949
5950        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5951        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5952
5953        if (!normalMode) {
5954            Slog.i(TAG, "Launching preboot mode app: " + app);
5955        }
5956
5957        if (localLOGV) Slog.v(
5958            TAG, "New app record " + app
5959            + " thread=" + thread.asBinder() + " pid=" + pid);
5960        try {
5961            int testMode = IApplicationThread.DEBUG_OFF;
5962            if (mDebugApp != null && mDebugApp.equals(processName)) {
5963                testMode = mWaitForDebugger
5964                    ? IApplicationThread.DEBUG_WAIT
5965                    : IApplicationThread.DEBUG_ON;
5966                app.debugging = true;
5967                if (mDebugTransient) {
5968                    mDebugApp = mOrigDebugApp;
5969                    mWaitForDebugger = mOrigWaitForDebugger;
5970                }
5971            }
5972            String profileFile = app.instrumentationProfileFile;
5973            ParcelFileDescriptor profileFd = null;
5974            int samplingInterval = 0;
5975            boolean profileAutoStop = false;
5976            if (mProfileApp != null && mProfileApp.equals(processName)) {
5977                mProfileProc = app;
5978                profileFile = mProfileFile;
5979                profileFd = mProfileFd;
5980                samplingInterval = mSamplingInterval;
5981                profileAutoStop = mAutoStopProfiler;
5982            }
5983            boolean enableOpenGlTrace = false;
5984            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5985                enableOpenGlTrace = true;
5986                mOpenGlTraceApp = null;
5987            }
5988
5989            // If the app is being launched for restore or full backup, set it up specially
5990            boolean isRestrictedBackupMode = false;
5991            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5992                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5993                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5994                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5995            }
5996
5997            ensurePackageDexOpt(app.instrumentationInfo != null
5998                    ? app.instrumentationInfo.packageName
5999                    : app.info.packageName);
6000            if (app.instrumentationClass != null) {
6001                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6002            }
6003            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6004                    + processName + " with config " + mConfiguration);
6005            ApplicationInfo appInfo = app.instrumentationInfo != null
6006                    ? app.instrumentationInfo : app.info;
6007            app.compat = compatibilityInfoForPackageLocked(appInfo);
6008            if (profileFd != null) {
6009                profileFd = profileFd.dup();
6010            }
6011            ProfilerInfo profilerInfo = profileFile == null ? null
6012                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6013            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6014                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6015                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6016                    isRestrictedBackupMode || !normalMode, app.persistent,
6017                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6018                    mCoreSettingsObserver.getCoreSettingsLocked());
6019            updateLruProcessLocked(app, false, null);
6020            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6021        } catch (Exception e) {
6022            // todo: Yikes!  What should we do?  For now we will try to
6023            // start another process, but that could easily get us in
6024            // an infinite loop of restarting processes...
6025            Slog.w(TAG, "Exception thrown during bind!", e);
6026
6027            app.resetPackageList(mProcessStats);
6028            app.unlinkDeathRecipient();
6029            startProcessLocked(app, "bind fail", processName);
6030            return false;
6031        }
6032
6033        // Remove this record from the list of starting applications.
6034        mPersistentStartingProcesses.remove(app);
6035        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6036                "Attach application locked removing on hold: " + app);
6037        mProcessesOnHold.remove(app);
6038
6039        boolean badApp = false;
6040        boolean didSomething = false;
6041
6042        // See if the top visible activity is waiting to run in this process...
6043        if (normalMode) {
6044            try {
6045                if (mStackSupervisor.attachApplicationLocked(app)) {
6046                    didSomething = true;
6047                }
6048            } catch (Exception e) {
6049                badApp = true;
6050            }
6051        }
6052
6053        // Find any services that should be running in this process...
6054        if (!badApp) {
6055            try {
6056                didSomething |= mServices.attachApplicationLocked(app, processName);
6057            } catch (Exception e) {
6058                badApp = true;
6059            }
6060        }
6061
6062        // Check if a next-broadcast receiver is in this process...
6063        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6064            try {
6065                didSomething |= sendPendingBroadcastsLocked(app);
6066            } catch (Exception e) {
6067                // If the app died trying to launch the receiver we declare it 'bad'
6068                badApp = true;
6069            }
6070        }
6071
6072        // Check whether the next backup agent is in this process...
6073        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6074            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6075            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6076            try {
6077                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6078                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6079                        mBackupTarget.backupMode);
6080            } catch (Exception e) {
6081                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6082                e.printStackTrace();
6083            }
6084        }
6085
6086        if (badApp) {
6087            // todo: Also need to kill application to deal with all
6088            // kinds of exceptions.
6089            handleAppDiedLocked(app, false, true);
6090            return false;
6091        }
6092
6093        if (!didSomething) {
6094            updateOomAdjLocked();
6095        }
6096
6097        return true;
6098    }
6099
6100    @Override
6101    public final void attachApplication(IApplicationThread thread) {
6102        synchronized (this) {
6103            int callingPid = Binder.getCallingPid();
6104            final long origId = Binder.clearCallingIdentity();
6105            attachApplicationLocked(thread, callingPid);
6106            Binder.restoreCallingIdentity(origId);
6107        }
6108    }
6109
6110    @Override
6111    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6112        final long origId = Binder.clearCallingIdentity();
6113        synchronized (this) {
6114            ActivityStack stack = ActivityRecord.getStackLocked(token);
6115            if (stack != null) {
6116                ActivityRecord r =
6117                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6118                if (stopProfiling) {
6119                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6120                        try {
6121                            mProfileFd.close();
6122                        } catch (IOException e) {
6123                        }
6124                        clearProfilerLocked();
6125                    }
6126                }
6127            }
6128        }
6129        Binder.restoreCallingIdentity(origId);
6130    }
6131
6132    void postEnableScreenAfterBootLocked() {
6133        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6134    }
6135
6136    void enableScreenAfterBoot() {
6137        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6138                SystemClock.uptimeMillis());
6139        mWindowManager.enableScreenAfterBoot();
6140
6141        synchronized (this) {
6142            updateEventDispatchingLocked();
6143        }
6144    }
6145
6146    @Override
6147    public void showBootMessage(final CharSequence msg, final boolean always) {
6148        enforceNotIsolatedCaller("showBootMessage");
6149        mWindowManager.showBootMessage(msg, always);
6150    }
6151
6152    @Override
6153    public void keyguardWaitingForActivityDrawn() {
6154        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6155        final long token = Binder.clearCallingIdentity();
6156        try {
6157            synchronized (this) {
6158                if (DEBUG_LOCKSCREEN) logLockScreen("");
6159                mWindowManager.keyguardWaitingForActivityDrawn();
6160            }
6161        } finally {
6162            Binder.restoreCallingIdentity(token);
6163        }
6164    }
6165
6166    final void finishBooting() {
6167        // Register receivers to handle package update events
6168        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6169
6170        // Let system services know.
6171        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6172
6173        synchronized (this) {
6174            // Ensure that any processes we had put on hold are now started
6175            // up.
6176            final int NP = mProcessesOnHold.size();
6177            if (NP > 0) {
6178                ArrayList<ProcessRecord> procs =
6179                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6180                for (int ip=0; ip<NP; ip++) {
6181                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6182                            + procs.get(ip));
6183                    startProcessLocked(procs.get(ip), "on-hold", null);
6184                }
6185            }
6186
6187            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6188                // Start looking for apps that are abusing wake locks.
6189                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6190                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6191                // Tell anyone interested that we are done booting!
6192                SystemProperties.set("sys.boot_completed", "1");
6193                SystemProperties.set("dev.bootcomplete", "1");
6194                for (int i=0; i<mStartedUsers.size(); i++) {
6195                    UserStartedState uss = mStartedUsers.valueAt(i);
6196                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6197                        uss.mState = UserStartedState.STATE_RUNNING;
6198                        final int userId = mStartedUsers.keyAt(i);
6199                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6200                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6201                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6202                        broadcastIntentLocked(null, null, intent, null,
6203                                new IIntentReceiver.Stub() {
6204                                    @Override
6205                                    public void performReceive(Intent intent, int resultCode,
6206                                            String data, Bundle extras, boolean ordered,
6207                                            boolean sticky, int sendingUser) {
6208                                        synchronized (ActivityManagerService.this) {
6209                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6210                                                    true, false);
6211                                        }
6212                                    }
6213                                },
6214                                0, null, null,
6215                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6216                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6217                                userId);
6218                    }
6219                }
6220                scheduleStartProfilesLocked();
6221            }
6222        }
6223    }
6224
6225    final void ensureBootCompleted() {
6226        boolean booting;
6227        boolean enableScreen;
6228        synchronized (this) {
6229            booting = mBooting;
6230            mBooting = false;
6231            enableScreen = !mBooted;
6232            mBooted = true;
6233        }
6234
6235        if (booting) {
6236            finishBooting();
6237        }
6238
6239        if (enableScreen) {
6240            enableScreenAfterBoot();
6241        }
6242    }
6243
6244    @Override
6245    public final void activityResumed(IBinder token) {
6246        final long origId = Binder.clearCallingIdentity();
6247        synchronized(this) {
6248            ActivityStack stack = ActivityRecord.getStackLocked(token);
6249            if (stack != null) {
6250                ActivityRecord.activityResumedLocked(token);
6251            }
6252        }
6253        Binder.restoreCallingIdentity(origId);
6254    }
6255
6256    @Override
6257    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
6258        final long origId = Binder.clearCallingIdentity();
6259        synchronized(this) {
6260            ActivityStack stack = ActivityRecord.getStackLocked(token);
6261            if (stack != null) {
6262                stack.activityPausedLocked(token, false, persistentState);
6263            }
6264        }
6265        Binder.restoreCallingIdentity(origId);
6266    }
6267
6268    @Override
6269    public final void activityStopped(IBinder token, Bundle icicle,
6270            PersistableBundle persistentState, CharSequence description) {
6271        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6272
6273        // Refuse possible leaked file descriptors
6274        if (icicle != null && icicle.hasFileDescriptors()) {
6275            throw new IllegalArgumentException("File descriptors passed in Bundle");
6276        }
6277
6278        final long origId = Binder.clearCallingIdentity();
6279
6280        synchronized (this) {
6281            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6282            if (r != null) {
6283                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6284            }
6285        }
6286
6287        trimApplications();
6288
6289        Binder.restoreCallingIdentity(origId);
6290    }
6291
6292    @Override
6293    public final void activityDestroyed(IBinder token) {
6294        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6295        synchronized (this) {
6296            ActivityStack stack = ActivityRecord.getStackLocked(token);
6297            if (stack != null) {
6298                stack.activityDestroyedLocked(token);
6299            }
6300        }
6301    }
6302
6303    @Override
6304    public final void backgroundResourcesReleased(IBinder token) {
6305        final long origId = Binder.clearCallingIdentity();
6306        try {
6307            synchronized (this) {
6308                ActivityStack stack = ActivityRecord.getStackLocked(token);
6309                if (stack != null) {
6310                    stack.backgroundResourcesReleased(token);
6311                }
6312            }
6313        } finally {
6314            Binder.restoreCallingIdentity(origId);
6315        }
6316    }
6317
6318    @Override
6319    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6320        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6321    }
6322
6323    @Override
6324    public final void notifyEnterAnimationComplete(IBinder token) {
6325        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6326    }
6327
6328    @Override
6329    public String getCallingPackage(IBinder token) {
6330        synchronized (this) {
6331            ActivityRecord r = getCallingRecordLocked(token);
6332            return r != null ? r.info.packageName : null;
6333        }
6334    }
6335
6336    @Override
6337    public ComponentName getCallingActivity(IBinder token) {
6338        synchronized (this) {
6339            ActivityRecord r = getCallingRecordLocked(token);
6340            return r != null ? r.intent.getComponent() : null;
6341        }
6342    }
6343
6344    private ActivityRecord getCallingRecordLocked(IBinder token) {
6345        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6346        if (r == null) {
6347            return null;
6348        }
6349        return r.resultTo;
6350    }
6351
6352    @Override
6353    public ComponentName getActivityClassForToken(IBinder token) {
6354        synchronized(this) {
6355            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6356            if (r == null) {
6357                return null;
6358            }
6359            return r.intent.getComponent();
6360        }
6361    }
6362
6363    @Override
6364    public String getPackageForToken(IBinder token) {
6365        synchronized(this) {
6366            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6367            if (r == null) {
6368                return null;
6369            }
6370            return r.packageName;
6371        }
6372    }
6373
6374    @Override
6375    public IIntentSender getIntentSender(int type,
6376            String packageName, IBinder token, String resultWho,
6377            int requestCode, Intent[] intents, String[] resolvedTypes,
6378            int flags, Bundle options, int userId) {
6379        enforceNotIsolatedCaller("getIntentSender");
6380        // Refuse possible leaked file descriptors
6381        if (intents != null) {
6382            if (intents.length < 1) {
6383                throw new IllegalArgumentException("Intents array length must be >= 1");
6384            }
6385            for (int i=0; i<intents.length; i++) {
6386                Intent intent = intents[i];
6387                if (intent != null) {
6388                    if (intent.hasFileDescriptors()) {
6389                        throw new IllegalArgumentException("File descriptors passed in Intent");
6390                    }
6391                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6392                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6393                        throw new IllegalArgumentException(
6394                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6395                    }
6396                    intents[i] = new Intent(intent);
6397                }
6398            }
6399            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6400                throw new IllegalArgumentException(
6401                        "Intent array length does not match resolvedTypes length");
6402            }
6403        }
6404        if (options != null) {
6405            if (options.hasFileDescriptors()) {
6406                throw new IllegalArgumentException("File descriptors passed in options");
6407            }
6408        }
6409
6410        synchronized(this) {
6411            int callingUid = Binder.getCallingUid();
6412            int origUserId = userId;
6413            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6414                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6415                    ALLOW_NON_FULL, "getIntentSender", null);
6416            if (origUserId == UserHandle.USER_CURRENT) {
6417                // We don't want to evaluate this until the pending intent is
6418                // actually executed.  However, we do want to always do the
6419                // security checking for it above.
6420                userId = UserHandle.USER_CURRENT;
6421            }
6422            try {
6423                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6424                    int uid = AppGlobals.getPackageManager()
6425                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6426                    if (!UserHandle.isSameApp(callingUid, uid)) {
6427                        String msg = "Permission Denial: getIntentSender() from pid="
6428                            + Binder.getCallingPid()
6429                            + ", uid=" + Binder.getCallingUid()
6430                            + ", (need uid=" + uid + ")"
6431                            + " is not allowed to send as package " + packageName;
6432                        Slog.w(TAG, msg);
6433                        throw new SecurityException(msg);
6434                    }
6435                }
6436
6437                return getIntentSenderLocked(type, packageName, callingUid, userId,
6438                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6439
6440            } catch (RemoteException e) {
6441                throw new SecurityException(e);
6442            }
6443        }
6444    }
6445
6446    IIntentSender getIntentSenderLocked(int type, String packageName,
6447            int callingUid, int userId, IBinder token, String resultWho,
6448            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6449            Bundle options) {
6450        if (DEBUG_MU)
6451            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6452        ActivityRecord activity = null;
6453        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6454            activity = ActivityRecord.isInStackLocked(token);
6455            if (activity == null) {
6456                return null;
6457            }
6458            if (activity.finishing) {
6459                return null;
6460            }
6461        }
6462
6463        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6464        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6465        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6466        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6467                |PendingIntent.FLAG_UPDATE_CURRENT);
6468
6469        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6470                type, packageName, activity, resultWho,
6471                requestCode, intents, resolvedTypes, flags, options, userId);
6472        WeakReference<PendingIntentRecord> ref;
6473        ref = mIntentSenderRecords.get(key);
6474        PendingIntentRecord rec = ref != null ? ref.get() : null;
6475        if (rec != null) {
6476            if (!cancelCurrent) {
6477                if (updateCurrent) {
6478                    if (rec.key.requestIntent != null) {
6479                        rec.key.requestIntent.replaceExtras(intents != null ?
6480                                intents[intents.length - 1] : null);
6481                    }
6482                    if (intents != null) {
6483                        intents[intents.length-1] = rec.key.requestIntent;
6484                        rec.key.allIntents = intents;
6485                        rec.key.allResolvedTypes = resolvedTypes;
6486                    } else {
6487                        rec.key.allIntents = null;
6488                        rec.key.allResolvedTypes = null;
6489                    }
6490                }
6491                return rec;
6492            }
6493            rec.canceled = true;
6494            mIntentSenderRecords.remove(key);
6495        }
6496        if (noCreate) {
6497            return rec;
6498        }
6499        rec = new PendingIntentRecord(this, key, callingUid);
6500        mIntentSenderRecords.put(key, rec.ref);
6501        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6502            if (activity.pendingResults == null) {
6503                activity.pendingResults
6504                        = new HashSet<WeakReference<PendingIntentRecord>>();
6505            }
6506            activity.pendingResults.add(rec.ref);
6507        }
6508        return rec;
6509    }
6510
6511    @Override
6512    public void cancelIntentSender(IIntentSender sender) {
6513        if (!(sender instanceof PendingIntentRecord)) {
6514            return;
6515        }
6516        synchronized(this) {
6517            PendingIntentRecord rec = (PendingIntentRecord)sender;
6518            try {
6519                int uid = AppGlobals.getPackageManager()
6520                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6521                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6522                    String msg = "Permission Denial: cancelIntentSender() from pid="
6523                        + Binder.getCallingPid()
6524                        + ", uid=" + Binder.getCallingUid()
6525                        + " is not allowed to cancel packges "
6526                        + rec.key.packageName;
6527                    Slog.w(TAG, msg);
6528                    throw new SecurityException(msg);
6529                }
6530            } catch (RemoteException e) {
6531                throw new SecurityException(e);
6532            }
6533            cancelIntentSenderLocked(rec, true);
6534        }
6535    }
6536
6537    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6538        rec.canceled = true;
6539        mIntentSenderRecords.remove(rec.key);
6540        if (cleanActivity && rec.key.activity != null) {
6541            rec.key.activity.pendingResults.remove(rec.ref);
6542        }
6543    }
6544
6545    @Override
6546    public String getPackageForIntentSender(IIntentSender pendingResult) {
6547        if (!(pendingResult instanceof PendingIntentRecord)) {
6548            return null;
6549        }
6550        try {
6551            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6552            return res.key.packageName;
6553        } catch (ClassCastException e) {
6554        }
6555        return null;
6556    }
6557
6558    @Override
6559    public int getUidForIntentSender(IIntentSender sender) {
6560        if (sender instanceof PendingIntentRecord) {
6561            try {
6562                PendingIntentRecord res = (PendingIntentRecord)sender;
6563                return res.uid;
6564            } catch (ClassCastException e) {
6565            }
6566        }
6567        return -1;
6568    }
6569
6570    @Override
6571    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6572        if (!(pendingResult instanceof PendingIntentRecord)) {
6573            return false;
6574        }
6575        try {
6576            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6577            if (res.key.allIntents == null) {
6578                return false;
6579            }
6580            for (int i=0; i<res.key.allIntents.length; i++) {
6581                Intent intent = res.key.allIntents[i];
6582                if (intent.getPackage() != null && intent.getComponent() != null) {
6583                    return false;
6584                }
6585            }
6586            return true;
6587        } catch (ClassCastException e) {
6588        }
6589        return false;
6590    }
6591
6592    @Override
6593    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6594        if (!(pendingResult instanceof PendingIntentRecord)) {
6595            return false;
6596        }
6597        try {
6598            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6599            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6600                return true;
6601            }
6602            return false;
6603        } catch (ClassCastException e) {
6604        }
6605        return false;
6606    }
6607
6608    @Override
6609    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6610        if (!(pendingResult instanceof PendingIntentRecord)) {
6611            return null;
6612        }
6613        try {
6614            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6615            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6616        } catch (ClassCastException e) {
6617        }
6618        return null;
6619    }
6620
6621    @Override
6622    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6623        if (!(pendingResult instanceof PendingIntentRecord)) {
6624            return null;
6625        }
6626        try {
6627            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6628            Intent intent = res.key.requestIntent;
6629            if (intent != null) {
6630                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6631                        || res.lastTagPrefix.equals(prefix))) {
6632                    return res.lastTag;
6633                }
6634                res.lastTagPrefix = prefix;
6635                StringBuilder sb = new StringBuilder(128);
6636                if (prefix != null) {
6637                    sb.append(prefix);
6638                }
6639                if (intent.getAction() != null) {
6640                    sb.append(intent.getAction());
6641                } else if (intent.getComponent() != null) {
6642                    intent.getComponent().appendShortString(sb);
6643                } else {
6644                    sb.append("?");
6645                }
6646                return res.lastTag = sb.toString();
6647            }
6648        } catch (ClassCastException e) {
6649        }
6650        return null;
6651    }
6652
6653    @Override
6654    public void setProcessLimit(int max) {
6655        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6656                "setProcessLimit()");
6657        synchronized (this) {
6658            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6659            mProcessLimitOverride = max;
6660        }
6661        trimApplications();
6662    }
6663
6664    @Override
6665    public int getProcessLimit() {
6666        synchronized (this) {
6667            return mProcessLimitOverride;
6668        }
6669    }
6670
6671    void foregroundTokenDied(ForegroundToken token) {
6672        synchronized (ActivityManagerService.this) {
6673            synchronized (mPidsSelfLocked) {
6674                ForegroundToken cur
6675                    = mForegroundProcesses.get(token.pid);
6676                if (cur != token) {
6677                    return;
6678                }
6679                mForegroundProcesses.remove(token.pid);
6680                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6681                if (pr == null) {
6682                    return;
6683                }
6684                pr.forcingToForeground = null;
6685                updateProcessForegroundLocked(pr, false, false);
6686            }
6687            updateOomAdjLocked();
6688        }
6689    }
6690
6691    @Override
6692    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6693        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6694                "setProcessForeground()");
6695        synchronized(this) {
6696            boolean changed = false;
6697
6698            synchronized (mPidsSelfLocked) {
6699                ProcessRecord pr = mPidsSelfLocked.get(pid);
6700                if (pr == null && isForeground) {
6701                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6702                    return;
6703                }
6704                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6705                if (oldToken != null) {
6706                    oldToken.token.unlinkToDeath(oldToken, 0);
6707                    mForegroundProcesses.remove(pid);
6708                    if (pr != null) {
6709                        pr.forcingToForeground = null;
6710                    }
6711                    changed = true;
6712                }
6713                if (isForeground && token != null) {
6714                    ForegroundToken newToken = new ForegroundToken() {
6715                        @Override
6716                        public void binderDied() {
6717                            foregroundTokenDied(this);
6718                        }
6719                    };
6720                    newToken.pid = pid;
6721                    newToken.token = token;
6722                    try {
6723                        token.linkToDeath(newToken, 0);
6724                        mForegroundProcesses.put(pid, newToken);
6725                        pr.forcingToForeground = token;
6726                        changed = true;
6727                    } catch (RemoteException e) {
6728                        // If the process died while doing this, we will later
6729                        // do the cleanup with the process death link.
6730                    }
6731                }
6732            }
6733
6734            if (changed) {
6735                updateOomAdjLocked();
6736            }
6737        }
6738    }
6739
6740    // =========================================================
6741    // PERMISSIONS
6742    // =========================================================
6743
6744    static class PermissionController extends IPermissionController.Stub {
6745        ActivityManagerService mActivityManagerService;
6746        PermissionController(ActivityManagerService activityManagerService) {
6747            mActivityManagerService = activityManagerService;
6748        }
6749
6750        @Override
6751        public boolean checkPermission(String permission, int pid, int uid) {
6752            return mActivityManagerService.checkPermission(permission, pid,
6753                    uid) == PackageManager.PERMISSION_GRANTED;
6754        }
6755    }
6756
6757    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6758        @Override
6759        public int checkComponentPermission(String permission, int pid, int uid,
6760                int owningUid, boolean exported) {
6761            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6762                    owningUid, exported);
6763        }
6764
6765        @Override
6766        public Object getAMSLock() {
6767            return ActivityManagerService.this;
6768        }
6769    }
6770
6771    /**
6772     * This can be called with or without the global lock held.
6773     */
6774    int checkComponentPermission(String permission, int pid, int uid,
6775            int owningUid, boolean exported) {
6776        // We might be performing an operation on behalf of an indirect binder
6777        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6778        // client identity accordingly before proceeding.
6779        Identity tlsIdentity = sCallerIdentity.get();
6780        if (tlsIdentity != null) {
6781            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6782                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6783            uid = tlsIdentity.uid;
6784            pid = tlsIdentity.pid;
6785        }
6786
6787        if (pid == MY_PID) {
6788            return PackageManager.PERMISSION_GRANTED;
6789        }
6790
6791        return ActivityManager.checkComponentPermission(permission, uid,
6792                owningUid, exported);
6793    }
6794
6795    /**
6796     * As the only public entry point for permissions checking, this method
6797     * can enforce the semantic that requesting a check on a null global
6798     * permission is automatically denied.  (Internally a null permission
6799     * string is used when calling {@link #checkComponentPermission} in cases
6800     * when only uid-based security is needed.)
6801     *
6802     * This can be called with or without the global lock held.
6803     */
6804    @Override
6805    public int checkPermission(String permission, int pid, int uid) {
6806        if (permission == null) {
6807            return PackageManager.PERMISSION_DENIED;
6808        }
6809        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6810    }
6811
6812    /**
6813     * Binder IPC calls go through the public entry point.
6814     * This can be called with or without the global lock held.
6815     */
6816    int checkCallingPermission(String permission) {
6817        return checkPermission(permission,
6818                Binder.getCallingPid(),
6819                UserHandle.getAppId(Binder.getCallingUid()));
6820    }
6821
6822    /**
6823     * This can be called with or without the global lock held.
6824     */
6825    void enforceCallingPermission(String permission, String func) {
6826        if (checkCallingPermission(permission)
6827                == PackageManager.PERMISSION_GRANTED) {
6828            return;
6829        }
6830
6831        String msg = "Permission Denial: " + func + " from pid="
6832                + Binder.getCallingPid()
6833                + ", uid=" + Binder.getCallingUid()
6834                + " requires " + permission;
6835        Slog.w(TAG, msg);
6836        throw new SecurityException(msg);
6837    }
6838
6839    /**
6840     * Determine if UID is holding permissions required to access {@link Uri} in
6841     * the given {@link ProviderInfo}. Final permission checking is always done
6842     * in {@link ContentProvider}.
6843     */
6844    private final boolean checkHoldingPermissionsLocked(
6845            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6846        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6847                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6848        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6849            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6850                    != PERMISSION_GRANTED) {
6851                return false;
6852            }
6853        }
6854        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6855    }
6856
6857    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6858            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6859        if (pi.applicationInfo.uid == uid) {
6860            return true;
6861        } else if (!pi.exported) {
6862            return false;
6863        }
6864
6865        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6866        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6867        try {
6868            // check if target holds top-level <provider> permissions
6869            if (!readMet && pi.readPermission != null && considerUidPermissions
6870                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6871                readMet = true;
6872            }
6873            if (!writeMet && pi.writePermission != null && considerUidPermissions
6874                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6875                writeMet = true;
6876            }
6877
6878            // track if unprotected read/write is allowed; any denied
6879            // <path-permission> below removes this ability
6880            boolean allowDefaultRead = pi.readPermission == null;
6881            boolean allowDefaultWrite = pi.writePermission == null;
6882
6883            // check if target holds any <path-permission> that match uri
6884            final PathPermission[] pps = pi.pathPermissions;
6885            if (pps != null) {
6886                final String path = grantUri.uri.getPath();
6887                int i = pps.length;
6888                while (i > 0 && (!readMet || !writeMet)) {
6889                    i--;
6890                    PathPermission pp = pps[i];
6891                    if (pp.match(path)) {
6892                        if (!readMet) {
6893                            final String pprperm = pp.getReadPermission();
6894                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6895                                    + pprperm + " for " + pp.getPath()
6896                                    + ": match=" + pp.match(path)
6897                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6898                            if (pprperm != null) {
6899                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6900                                        == PERMISSION_GRANTED) {
6901                                    readMet = true;
6902                                } else {
6903                                    allowDefaultRead = false;
6904                                }
6905                            }
6906                        }
6907                        if (!writeMet) {
6908                            final String ppwperm = pp.getWritePermission();
6909                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6910                                    + ppwperm + " for " + pp.getPath()
6911                                    + ": match=" + pp.match(path)
6912                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6913                            if (ppwperm != null) {
6914                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6915                                        == PERMISSION_GRANTED) {
6916                                    writeMet = true;
6917                                } else {
6918                                    allowDefaultWrite = false;
6919                                }
6920                            }
6921                        }
6922                    }
6923                }
6924            }
6925
6926            // grant unprotected <provider> read/write, if not blocked by
6927            // <path-permission> above
6928            if (allowDefaultRead) readMet = true;
6929            if (allowDefaultWrite) writeMet = true;
6930
6931        } catch (RemoteException e) {
6932            return false;
6933        }
6934
6935        return readMet && writeMet;
6936    }
6937
6938    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6939        ProviderInfo pi = null;
6940        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6941        if (cpr != null) {
6942            pi = cpr.info;
6943        } else {
6944            try {
6945                pi = AppGlobals.getPackageManager().resolveContentProvider(
6946                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6947            } catch (RemoteException ex) {
6948            }
6949        }
6950        return pi;
6951    }
6952
6953    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6954        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6955        if (targetUris != null) {
6956            return targetUris.get(grantUri);
6957        }
6958        return null;
6959    }
6960
6961    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6962            String targetPkg, int targetUid, GrantUri grantUri) {
6963        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6964        if (targetUris == null) {
6965            targetUris = Maps.newArrayMap();
6966            mGrantedUriPermissions.put(targetUid, targetUris);
6967        }
6968
6969        UriPermission perm = targetUris.get(grantUri);
6970        if (perm == null) {
6971            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6972            targetUris.put(grantUri, perm);
6973        }
6974
6975        return perm;
6976    }
6977
6978    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6979            final int modeFlags) {
6980        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6981        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6982                : UriPermission.STRENGTH_OWNED;
6983
6984        // Root gets to do everything.
6985        if (uid == 0) {
6986            return true;
6987        }
6988
6989        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6990        if (perms == null) return false;
6991
6992        // First look for exact match
6993        final UriPermission exactPerm = perms.get(grantUri);
6994        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6995            return true;
6996        }
6997
6998        // No exact match, look for prefixes
6999        final int N = perms.size();
7000        for (int i = 0; i < N; i++) {
7001            final UriPermission perm = perms.valueAt(i);
7002            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7003                    && perm.getStrength(modeFlags) >= minStrength) {
7004                return true;
7005            }
7006        }
7007
7008        return false;
7009    }
7010
7011    /**
7012     * @param uri This uri must NOT contain an embedded userId.
7013     * @param userId The userId in which the uri is to be resolved.
7014     */
7015    @Override
7016    public int checkUriPermission(Uri uri, int pid, int uid,
7017            final int modeFlags, int userId) {
7018        enforceNotIsolatedCaller("checkUriPermission");
7019
7020        // Another redirected-binder-call permissions check as in
7021        // {@link checkComponentPermission}.
7022        Identity tlsIdentity = sCallerIdentity.get();
7023        if (tlsIdentity != null) {
7024            uid = tlsIdentity.uid;
7025            pid = tlsIdentity.pid;
7026        }
7027
7028        // Our own process gets to do everything.
7029        if (pid == MY_PID) {
7030            return PackageManager.PERMISSION_GRANTED;
7031        }
7032        synchronized (this) {
7033            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7034                    ? PackageManager.PERMISSION_GRANTED
7035                    : PackageManager.PERMISSION_DENIED;
7036        }
7037    }
7038
7039    /**
7040     * Check if the targetPkg can be granted permission to access uri by
7041     * the callingUid using the given modeFlags.  Throws a security exception
7042     * if callingUid is not allowed to do this.  Returns the uid of the target
7043     * if the URI permission grant should be performed; returns -1 if it is not
7044     * needed (for example targetPkg already has permission to access the URI).
7045     * If you already know the uid of the target, you can supply it in
7046     * lastTargetUid else set that to -1.
7047     */
7048    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7049            final int modeFlags, int lastTargetUid) {
7050        if (!Intent.isAccessUriMode(modeFlags)) {
7051            return -1;
7052        }
7053
7054        if (targetPkg != null) {
7055            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7056                    "Checking grant " + targetPkg + " permission to " + grantUri);
7057        }
7058
7059        final IPackageManager pm = AppGlobals.getPackageManager();
7060
7061        // If this is not a content: uri, we can't do anything with it.
7062        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7063            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7064                    "Can't grant URI permission for non-content URI: " + grantUri);
7065            return -1;
7066        }
7067
7068        final String authority = grantUri.uri.getAuthority();
7069        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7070        if (pi == null) {
7071            Slog.w(TAG, "No content provider found for permission check: " +
7072                    grantUri.uri.toSafeString());
7073            return -1;
7074        }
7075
7076        int targetUid = lastTargetUid;
7077        if (targetUid < 0 && targetPkg != null) {
7078            try {
7079                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7080                if (targetUid < 0) {
7081                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7082                            "Can't grant URI permission no uid for: " + targetPkg);
7083                    return -1;
7084                }
7085            } catch (RemoteException ex) {
7086                return -1;
7087            }
7088        }
7089
7090        if (targetUid >= 0) {
7091            // First...  does the target actually need this permission?
7092            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7093                // No need to grant the target this permission.
7094                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7095                        "Target " + targetPkg + " already has full permission to " + grantUri);
7096                return -1;
7097            }
7098        } else {
7099            // First...  there is no target package, so can anyone access it?
7100            boolean allowed = pi.exported;
7101            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7102                if (pi.readPermission != null) {
7103                    allowed = false;
7104                }
7105            }
7106            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7107                if (pi.writePermission != null) {
7108                    allowed = false;
7109                }
7110            }
7111            if (allowed) {
7112                return -1;
7113            }
7114        }
7115
7116        /* There is a special cross user grant if:
7117         * - The target is on another user.
7118         * - Apps on the current user can access the uri without any uid permissions.
7119         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7120         * grant uri permissions.
7121         */
7122        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7123                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7124                modeFlags, false /*without considering the uid permissions*/);
7125
7126        // Second...  is the provider allowing granting of URI permissions?
7127        if (!specialCrossUserGrant) {
7128            if (!pi.grantUriPermissions) {
7129                throw new SecurityException("Provider " + pi.packageName
7130                        + "/" + pi.name
7131                        + " does not allow granting of Uri permissions (uri "
7132                        + grantUri + ")");
7133            }
7134            if (pi.uriPermissionPatterns != null) {
7135                final int N = pi.uriPermissionPatterns.length;
7136                boolean allowed = false;
7137                for (int i=0; i<N; i++) {
7138                    if (pi.uriPermissionPatterns[i] != null
7139                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7140                        allowed = true;
7141                        break;
7142                    }
7143                }
7144                if (!allowed) {
7145                    throw new SecurityException("Provider " + pi.packageName
7146                            + "/" + pi.name
7147                            + " does not allow granting of permission to path of Uri "
7148                            + grantUri);
7149                }
7150            }
7151        }
7152
7153        // Third...  does the caller itself have permission to access
7154        // this uri?
7155        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7156            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7157                // Require they hold a strong enough Uri permission
7158                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7159                    throw new SecurityException("Uid " + callingUid
7160                            + " does not have permission to uri " + grantUri);
7161                }
7162            }
7163        }
7164        return targetUid;
7165    }
7166
7167    /**
7168     * @param uri This uri must NOT contain an embedded userId.
7169     * @param userId The userId in which the uri is to be resolved.
7170     */
7171    @Override
7172    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7173            final int modeFlags, int userId) {
7174        enforceNotIsolatedCaller("checkGrantUriPermission");
7175        synchronized(this) {
7176            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7177                    new GrantUri(userId, uri, false), modeFlags, -1);
7178        }
7179    }
7180
7181    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7182            final int modeFlags, UriPermissionOwner owner) {
7183        if (!Intent.isAccessUriMode(modeFlags)) {
7184            return;
7185        }
7186
7187        // So here we are: the caller has the assumed permission
7188        // to the uri, and the target doesn't.  Let's now give this to
7189        // the target.
7190
7191        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7192                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7193
7194        final String authority = grantUri.uri.getAuthority();
7195        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7196        if (pi == null) {
7197            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7198            return;
7199        }
7200
7201        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7202            grantUri.prefix = true;
7203        }
7204        final UriPermission perm = findOrCreateUriPermissionLocked(
7205                pi.packageName, targetPkg, targetUid, grantUri);
7206        perm.grantModes(modeFlags, owner);
7207    }
7208
7209    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7210            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7211        if (targetPkg == null) {
7212            throw new NullPointerException("targetPkg");
7213        }
7214        int targetUid;
7215        final IPackageManager pm = AppGlobals.getPackageManager();
7216        try {
7217            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7218        } catch (RemoteException ex) {
7219            return;
7220        }
7221
7222        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7223                targetUid);
7224        if (targetUid < 0) {
7225            return;
7226        }
7227
7228        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7229                owner);
7230    }
7231
7232    static class NeededUriGrants extends ArrayList<GrantUri> {
7233        final String targetPkg;
7234        final int targetUid;
7235        final int flags;
7236
7237        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7238            this.targetPkg = targetPkg;
7239            this.targetUid = targetUid;
7240            this.flags = flags;
7241        }
7242    }
7243
7244    /**
7245     * Like checkGrantUriPermissionLocked, but takes an Intent.
7246     */
7247    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7248            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7249        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7250                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7251                + " clip=" + (intent != null ? intent.getClipData() : null)
7252                + " from " + intent + "; flags=0x"
7253                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7254
7255        if (targetPkg == null) {
7256            throw new NullPointerException("targetPkg");
7257        }
7258
7259        if (intent == null) {
7260            return null;
7261        }
7262        Uri data = intent.getData();
7263        ClipData clip = intent.getClipData();
7264        if (data == null && clip == null) {
7265            return null;
7266        }
7267        // Default userId for uris in the intent (if they don't specify it themselves)
7268        int contentUserHint = intent.getContentUserHint();
7269        if (contentUserHint == UserHandle.USER_CURRENT) {
7270            contentUserHint = UserHandle.getUserId(callingUid);
7271        }
7272        final IPackageManager pm = AppGlobals.getPackageManager();
7273        int targetUid;
7274        if (needed != null) {
7275            targetUid = needed.targetUid;
7276        } else {
7277            try {
7278                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7279            } catch (RemoteException ex) {
7280                return null;
7281            }
7282            if (targetUid < 0) {
7283                if (DEBUG_URI_PERMISSION) {
7284                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7285                            + " on user " + targetUserId);
7286                }
7287                return null;
7288            }
7289        }
7290        if (data != null) {
7291            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7292            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7293                    targetUid);
7294            if (targetUid > 0) {
7295                if (needed == null) {
7296                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7297                }
7298                needed.add(grantUri);
7299            }
7300        }
7301        if (clip != null) {
7302            for (int i=0; i<clip.getItemCount(); i++) {
7303                Uri uri = clip.getItemAt(i).getUri();
7304                if (uri != null) {
7305                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7306                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7307                            targetUid);
7308                    if (targetUid > 0) {
7309                        if (needed == null) {
7310                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7311                        }
7312                        needed.add(grantUri);
7313                    }
7314                } else {
7315                    Intent clipIntent = clip.getItemAt(i).getIntent();
7316                    if (clipIntent != null) {
7317                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7318                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7319                        if (newNeeded != null) {
7320                            needed = newNeeded;
7321                        }
7322                    }
7323                }
7324            }
7325        }
7326
7327        return needed;
7328    }
7329
7330    /**
7331     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7332     */
7333    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7334            UriPermissionOwner owner) {
7335        if (needed != null) {
7336            for (int i=0; i<needed.size(); i++) {
7337                GrantUri grantUri = needed.get(i);
7338                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7339                        grantUri, needed.flags, owner);
7340            }
7341        }
7342    }
7343
7344    void grantUriPermissionFromIntentLocked(int callingUid,
7345            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7346        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7347                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7348        if (needed == null) {
7349            return;
7350        }
7351
7352        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7353    }
7354
7355    /**
7356     * @param uri This uri must NOT contain an embedded userId.
7357     * @param userId The userId in which the uri is to be resolved.
7358     */
7359    @Override
7360    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7361            final int modeFlags, int userId) {
7362        enforceNotIsolatedCaller("grantUriPermission");
7363        GrantUri grantUri = new GrantUri(userId, uri, false);
7364        synchronized(this) {
7365            final ProcessRecord r = getRecordForAppLocked(caller);
7366            if (r == null) {
7367                throw new SecurityException("Unable to find app for caller "
7368                        + caller
7369                        + " when granting permission to uri " + grantUri);
7370            }
7371            if (targetPkg == null) {
7372                throw new IllegalArgumentException("null target");
7373            }
7374            if (grantUri == null) {
7375                throw new IllegalArgumentException("null uri");
7376            }
7377
7378            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7379                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7380                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7381                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7382
7383            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7384                    UserHandle.getUserId(r.uid));
7385        }
7386    }
7387
7388    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7389        if (perm.modeFlags == 0) {
7390            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7391                    perm.targetUid);
7392            if (perms != null) {
7393                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7394                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7395
7396                perms.remove(perm.uri);
7397                if (perms.isEmpty()) {
7398                    mGrantedUriPermissions.remove(perm.targetUid);
7399                }
7400            }
7401        }
7402    }
7403
7404    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7405        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7406
7407        final IPackageManager pm = AppGlobals.getPackageManager();
7408        final String authority = grantUri.uri.getAuthority();
7409        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7410        if (pi == null) {
7411            Slog.w(TAG, "No content provider found for permission revoke: "
7412                    + grantUri.toSafeString());
7413            return;
7414        }
7415
7416        // Does the caller have this permission on the URI?
7417        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7418            // Right now, if you are not the original owner of the permission,
7419            // you are not allowed to revoke it.
7420            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7421                throw new SecurityException("Uid " + callingUid
7422                        + " does not have permission to uri " + grantUri);
7423            //}
7424        }
7425
7426        boolean persistChanged = false;
7427
7428        // Go through all of the permissions and remove any that match.
7429        int N = mGrantedUriPermissions.size();
7430        for (int i = 0; i < N; i++) {
7431            final int targetUid = mGrantedUriPermissions.keyAt(i);
7432            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7433
7434            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7435                final UriPermission perm = it.next();
7436                if (perm.uri.sourceUserId == grantUri.sourceUserId
7437                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7438                    if (DEBUG_URI_PERMISSION)
7439                        Slog.v(TAG,
7440                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7441                    persistChanged |= perm.revokeModes(
7442                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7443                    if (perm.modeFlags == 0) {
7444                        it.remove();
7445                    }
7446                }
7447            }
7448
7449            if (perms.isEmpty()) {
7450                mGrantedUriPermissions.remove(targetUid);
7451                N--;
7452                i--;
7453            }
7454        }
7455
7456        if (persistChanged) {
7457            schedulePersistUriGrants();
7458        }
7459    }
7460
7461    /**
7462     * @param uri This uri must NOT contain an embedded userId.
7463     * @param userId The userId in which the uri is to be resolved.
7464     */
7465    @Override
7466    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7467            int userId) {
7468        enforceNotIsolatedCaller("revokeUriPermission");
7469        synchronized(this) {
7470            final ProcessRecord r = getRecordForAppLocked(caller);
7471            if (r == null) {
7472                throw new SecurityException("Unable to find app for caller "
7473                        + caller
7474                        + " when revoking permission to uri " + uri);
7475            }
7476            if (uri == null) {
7477                Slog.w(TAG, "revokeUriPermission: null uri");
7478                return;
7479            }
7480
7481            if (!Intent.isAccessUriMode(modeFlags)) {
7482                return;
7483            }
7484
7485            final IPackageManager pm = AppGlobals.getPackageManager();
7486            final String authority = uri.getAuthority();
7487            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7488            if (pi == null) {
7489                Slog.w(TAG, "No content provider found for permission revoke: "
7490                        + uri.toSafeString());
7491                return;
7492            }
7493
7494            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7495        }
7496    }
7497
7498    /**
7499     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7500     * given package.
7501     *
7502     * @param packageName Package name to match, or {@code null} to apply to all
7503     *            packages.
7504     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7505     *            to all users.
7506     * @param persistable If persistable grants should be removed.
7507     */
7508    private void removeUriPermissionsForPackageLocked(
7509            String packageName, int userHandle, boolean persistable) {
7510        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7511            throw new IllegalArgumentException("Must narrow by either package or user");
7512        }
7513
7514        boolean persistChanged = false;
7515
7516        int N = mGrantedUriPermissions.size();
7517        for (int i = 0; i < N; i++) {
7518            final int targetUid = mGrantedUriPermissions.keyAt(i);
7519            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7520
7521            // Only inspect grants matching user
7522            if (userHandle == UserHandle.USER_ALL
7523                    || userHandle == UserHandle.getUserId(targetUid)) {
7524                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7525                    final UriPermission perm = it.next();
7526
7527                    // Only inspect grants matching package
7528                    if (packageName == null || perm.sourcePkg.equals(packageName)
7529                            || perm.targetPkg.equals(packageName)) {
7530                        persistChanged |= perm.revokeModes(
7531                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7532
7533                        // Only remove when no modes remain; any persisted grants
7534                        // will keep this alive.
7535                        if (perm.modeFlags == 0) {
7536                            it.remove();
7537                        }
7538                    }
7539                }
7540
7541                if (perms.isEmpty()) {
7542                    mGrantedUriPermissions.remove(targetUid);
7543                    N--;
7544                    i--;
7545                }
7546            }
7547        }
7548
7549        if (persistChanged) {
7550            schedulePersistUriGrants();
7551        }
7552    }
7553
7554    @Override
7555    public IBinder newUriPermissionOwner(String name) {
7556        enforceNotIsolatedCaller("newUriPermissionOwner");
7557        synchronized(this) {
7558            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7559            return owner.getExternalTokenLocked();
7560        }
7561    }
7562
7563    /**
7564     * @param uri This uri must NOT contain an embedded userId.
7565     * @param sourceUserId The userId in which the uri is to be resolved.
7566     * @param targetUserId The userId of the app that receives the grant.
7567     */
7568    @Override
7569    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7570            final int modeFlags, int sourceUserId, int targetUserId) {
7571        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7572                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7573        synchronized(this) {
7574            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7575            if (owner == null) {
7576                throw new IllegalArgumentException("Unknown owner: " + token);
7577            }
7578            if (fromUid != Binder.getCallingUid()) {
7579                if (Binder.getCallingUid() != Process.myUid()) {
7580                    // Only system code can grant URI permissions on behalf
7581                    // of other users.
7582                    throw new SecurityException("nice try");
7583                }
7584            }
7585            if (targetPkg == null) {
7586                throw new IllegalArgumentException("null target");
7587            }
7588            if (uri == null) {
7589                throw new IllegalArgumentException("null uri");
7590            }
7591
7592            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7593                    modeFlags, owner, targetUserId);
7594        }
7595    }
7596
7597    /**
7598     * @param uri This uri must NOT contain an embedded userId.
7599     * @param userId The userId in which the uri is to be resolved.
7600     */
7601    @Override
7602    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7603        synchronized(this) {
7604            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7605            if (owner == null) {
7606                throw new IllegalArgumentException("Unknown owner: " + token);
7607            }
7608
7609            if (uri == null) {
7610                owner.removeUriPermissionsLocked(mode);
7611            } else {
7612                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7613            }
7614        }
7615    }
7616
7617    private void schedulePersistUriGrants() {
7618        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7619            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7620                    10 * DateUtils.SECOND_IN_MILLIS);
7621        }
7622    }
7623
7624    private void writeGrantedUriPermissions() {
7625        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7626
7627        // Snapshot permissions so we can persist without lock
7628        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7629        synchronized (this) {
7630            final int size = mGrantedUriPermissions.size();
7631            for (int i = 0; i < size; i++) {
7632                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7633                for (UriPermission perm : perms.values()) {
7634                    if (perm.persistedModeFlags != 0) {
7635                        persist.add(perm.snapshot());
7636                    }
7637                }
7638            }
7639        }
7640
7641        FileOutputStream fos = null;
7642        try {
7643            fos = mGrantFile.startWrite();
7644
7645            XmlSerializer out = new FastXmlSerializer();
7646            out.setOutput(fos, "utf-8");
7647            out.startDocument(null, true);
7648            out.startTag(null, TAG_URI_GRANTS);
7649            for (UriPermission.Snapshot perm : persist) {
7650                out.startTag(null, TAG_URI_GRANT);
7651                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7652                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7653                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7654                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7655                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7656                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7657                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7658                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7659                out.endTag(null, TAG_URI_GRANT);
7660            }
7661            out.endTag(null, TAG_URI_GRANTS);
7662            out.endDocument();
7663
7664            mGrantFile.finishWrite(fos);
7665        } catch (IOException e) {
7666            if (fos != null) {
7667                mGrantFile.failWrite(fos);
7668            }
7669        }
7670    }
7671
7672    private void readGrantedUriPermissionsLocked() {
7673        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7674
7675        final long now = System.currentTimeMillis();
7676
7677        FileInputStream fis = null;
7678        try {
7679            fis = mGrantFile.openRead();
7680            final XmlPullParser in = Xml.newPullParser();
7681            in.setInput(fis, null);
7682
7683            int type;
7684            while ((type = in.next()) != END_DOCUMENT) {
7685                final String tag = in.getName();
7686                if (type == START_TAG) {
7687                    if (TAG_URI_GRANT.equals(tag)) {
7688                        final int sourceUserId;
7689                        final int targetUserId;
7690                        final int userHandle = readIntAttribute(in,
7691                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7692                        if (userHandle != UserHandle.USER_NULL) {
7693                            // For backwards compatibility.
7694                            sourceUserId = userHandle;
7695                            targetUserId = userHandle;
7696                        } else {
7697                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7698                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7699                        }
7700                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7701                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7702                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7703                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7704                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7705                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7706
7707                        // Sanity check that provider still belongs to source package
7708                        final ProviderInfo pi = getProviderInfoLocked(
7709                                uri.getAuthority(), sourceUserId);
7710                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7711                            int targetUid = -1;
7712                            try {
7713                                targetUid = AppGlobals.getPackageManager()
7714                                        .getPackageUid(targetPkg, targetUserId);
7715                            } catch (RemoteException e) {
7716                            }
7717                            if (targetUid != -1) {
7718                                final UriPermission perm = findOrCreateUriPermissionLocked(
7719                                        sourcePkg, targetPkg, targetUid,
7720                                        new GrantUri(sourceUserId, uri, prefix));
7721                                perm.initPersistedModes(modeFlags, createdTime);
7722                            }
7723                        } else {
7724                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7725                                    + " but instead found " + pi);
7726                        }
7727                    }
7728                }
7729            }
7730        } catch (FileNotFoundException e) {
7731            // Missing grants is okay
7732        } catch (IOException e) {
7733            Log.wtf(TAG, "Failed reading Uri grants", e);
7734        } catch (XmlPullParserException e) {
7735            Log.wtf(TAG, "Failed reading Uri grants", e);
7736        } finally {
7737            IoUtils.closeQuietly(fis);
7738        }
7739    }
7740
7741    /**
7742     * @param uri This uri must NOT contain an embedded userId.
7743     * @param userId The userId in which the uri is to be resolved.
7744     */
7745    @Override
7746    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7747        enforceNotIsolatedCaller("takePersistableUriPermission");
7748
7749        Preconditions.checkFlagsArgument(modeFlags,
7750                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7751
7752        synchronized (this) {
7753            final int callingUid = Binder.getCallingUid();
7754            boolean persistChanged = false;
7755            GrantUri grantUri = new GrantUri(userId, uri, false);
7756
7757            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7758                    new GrantUri(userId, uri, false));
7759            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7760                    new GrantUri(userId, uri, true));
7761
7762            final boolean exactValid = (exactPerm != null)
7763                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7764            final boolean prefixValid = (prefixPerm != null)
7765                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7766
7767            if (!(exactValid || prefixValid)) {
7768                throw new SecurityException("No persistable permission grants found for UID "
7769                        + callingUid + " and Uri " + grantUri.toSafeString());
7770            }
7771
7772            if (exactValid) {
7773                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7774            }
7775            if (prefixValid) {
7776                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7777            }
7778
7779            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7780
7781            if (persistChanged) {
7782                schedulePersistUriGrants();
7783            }
7784        }
7785    }
7786
7787    /**
7788     * @param uri This uri must NOT contain an embedded userId.
7789     * @param userId The userId in which the uri is to be resolved.
7790     */
7791    @Override
7792    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7793        enforceNotIsolatedCaller("releasePersistableUriPermission");
7794
7795        Preconditions.checkFlagsArgument(modeFlags,
7796                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7797
7798        synchronized (this) {
7799            final int callingUid = Binder.getCallingUid();
7800            boolean persistChanged = false;
7801
7802            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7803                    new GrantUri(userId, uri, false));
7804            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7805                    new GrantUri(userId, uri, true));
7806            if (exactPerm == null && prefixPerm == null) {
7807                throw new SecurityException("No permission grants found for UID " + callingUid
7808                        + " and Uri " + uri.toSafeString());
7809            }
7810
7811            if (exactPerm != null) {
7812                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7813                removeUriPermissionIfNeededLocked(exactPerm);
7814            }
7815            if (prefixPerm != null) {
7816                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7817                removeUriPermissionIfNeededLocked(prefixPerm);
7818            }
7819
7820            if (persistChanged) {
7821                schedulePersistUriGrants();
7822            }
7823        }
7824    }
7825
7826    /**
7827     * Prune any older {@link UriPermission} for the given UID until outstanding
7828     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7829     *
7830     * @return if any mutations occured that require persisting.
7831     */
7832    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7833        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7834        if (perms == null) return false;
7835        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7836
7837        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7838        for (UriPermission perm : perms.values()) {
7839            if (perm.persistedModeFlags != 0) {
7840                persisted.add(perm);
7841            }
7842        }
7843
7844        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7845        if (trimCount <= 0) return false;
7846
7847        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7848        for (int i = 0; i < trimCount; i++) {
7849            final UriPermission perm = persisted.get(i);
7850
7851            if (DEBUG_URI_PERMISSION) {
7852                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7853            }
7854
7855            perm.releasePersistableModes(~0);
7856            removeUriPermissionIfNeededLocked(perm);
7857        }
7858
7859        return true;
7860    }
7861
7862    @Override
7863    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7864            String packageName, boolean incoming) {
7865        enforceNotIsolatedCaller("getPersistedUriPermissions");
7866        Preconditions.checkNotNull(packageName, "packageName");
7867
7868        final int callingUid = Binder.getCallingUid();
7869        final IPackageManager pm = AppGlobals.getPackageManager();
7870        try {
7871            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7872            if (packageUid != callingUid) {
7873                throw new SecurityException(
7874                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7875            }
7876        } catch (RemoteException e) {
7877            throw new SecurityException("Failed to verify package name ownership");
7878        }
7879
7880        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7881        synchronized (this) {
7882            if (incoming) {
7883                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7884                        callingUid);
7885                if (perms == null) {
7886                    Slog.w(TAG, "No permission grants found for " + packageName);
7887                } else {
7888                    for (UriPermission perm : perms.values()) {
7889                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7890                            result.add(perm.buildPersistedPublicApiObject());
7891                        }
7892                    }
7893                }
7894            } else {
7895                final int size = mGrantedUriPermissions.size();
7896                for (int i = 0; i < size; i++) {
7897                    final ArrayMap<GrantUri, UriPermission> perms =
7898                            mGrantedUriPermissions.valueAt(i);
7899                    for (UriPermission perm : perms.values()) {
7900                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7901                            result.add(perm.buildPersistedPublicApiObject());
7902                        }
7903                    }
7904                }
7905            }
7906        }
7907        return new ParceledListSlice<android.content.UriPermission>(result);
7908    }
7909
7910    @Override
7911    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7912        synchronized (this) {
7913            ProcessRecord app =
7914                who != null ? getRecordForAppLocked(who) : null;
7915            if (app == null) return;
7916
7917            Message msg = Message.obtain();
7918            msg.what = WAIT_FOR_DEBUGGER_MSG;
7919            msg.obj = app;
7920            msg.arg1 = waiting ? 1 : 0;
7921            mHandler.sendMessage(msg);
7922        }
7923    }
7924
7925    @Override
7926    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7927        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7928        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7929        outInfo.availMem = Process.getFreeMemory();
7930        outInfo.totalMem = Process.getTotalMemory();
7931        outInfo.threshold = homeAppMem;
7932        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7933        outInfo.hiddenAppThreshold = cachedAppMem;
7934        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7935                ProcessList.SERVICE_ADJ);
7936        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7937                ProcessList.VISIBLE_APP_ADJ);
7938        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7939                ProcessList.FOREGROUND_APP_ADJ);
7940    }
7941
7942    // =========================================================
7943    // TASK MANAGEMENT
7944    // =========================================================
7945
7946    @Override
7947    public List<IAppTask> getAppTasks(String callingPackage) {
7948        int callingUid = Binder.getCallingUid();
7949        long ident = Binder.clearCallingIdentity();
7950
7951        synchronized(this) {
7952            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7953            try {
7954                if (localLOGV) Slog.v(TAG, "getAppTasks");
7955
7956                final int N = mRecentTasks.size();
7957                for (int i = 0; i < N; i++) {
7958                    TaskRecord tr = mRecentTasks.get(i);
7959                    // Skip tasks that do not match the caller.  We don't need to verify
7960                    // callingPackage, because we are also limiting to callingUid and know
7961                    // that will limit to the correct security sandbox.
7962                    if (tr.effectiveUid != callingUid) {
7963                        continue;
7964                    }
7965                    Intent intent = tr.getBaseIntent();
7966                    if (intent == null ||
7967                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7968                        continue;
7969                    }
7970                    ActivityManager.RecentTaskInfo taskInfo =
7971                            createRecentTaskInfoFromTaskRecord(tr);
7972                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7973                    list.add(taskImpl);
7974                }
7975            } finally {
7976                Binder.restoreCallingIdentity(ident);
7977            }
7978            return list;
7979        }
7980    }
7981
7982    @Override
7983    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7984        final int callingUid = Binder.getCallingUid();
7985        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7986
7987        synchronized(this) {
7988            if (localLOGV) Slog.v(
7989                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7990
7991            final boolean allowed = checkCallingPermission(
7992                    android.Manifest.permission.GET_TASKS)
7993                    == PackageManager.PERMISSION_GRANTED;
7994            if (!allowed) {
7995                Slog.w(TAG, "getTasks: caller " + callingUid
7996                        + " does not hold GET_TASKS; limiting output");
7997            }
7998
7999            // TODO: Improve with MRU list from all ActivityStacks.
8000            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8001        }
8002
8003        return list;
8004    }
8005
8006    TaskRecord getMostRecentTask() {
8007        return mRecentTasks.get(0);
8008    }
8009
8010    /**
8011     * Creates a new RecentTaskInfo from a TaskRecord.
8012     */
8013    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8014        // Update the task description to reflect any changes in the task stack
8015        tr.updateTaskDescription();
8016
8017        // Compose the recent task info
8018        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8019        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8020        rti.persistentId = tr.taskId;
8021        rti.baseIntent = new Intent(tr.getBaseIntent());
8022        rti.origActivity = tr.origActivity;
8023        rti.description = tr.lastDescription;
8024        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8025        rti.userId = tr.userId;
8026        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8027        rti.firstActiveTime = tr.firstActiveTime;
8028        rti.lastActiveTime = tr.lastActiveTime;
8029        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8030        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8031        return rti;
8032    }
8033
8034    @Override
8035    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8036        final int callingUid = Binder.getCallingUid();
8037        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8038                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8039
8040        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8041        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8042        synchronized (this) {
8043            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8044                    == PackageManager.PERMISSION_GRANTED;
8045            if (!allowed) {
8046                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8047                        + " does not hold GET_TASKS; limiting output");
8048            }
8049            final boolean detailed = checkCallingPermission(
8050                    android.Manifest.permission.GET_DETAILED_TASKS)
8051                    == PackageManager.PERMISSION_GRANTED;
8052
8053            final int N = mRecentTasks.size();
8054            ArrayList<ActivityManager.RecentTaskInfo> res
8055                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8056                            maxNum < N ? maxNum : N);
8057
8058            final Set<Integer> includedUsers;
8059            if (includeProfiles) {
8060                includedUsers = getProfileIdsLocked(userId);
8061            } else {
8062                includedUsers = new HashSet<Integer>();
8063            }
8064            includedUsers.add(Integer.valueOf(userId));
8065
8066            for (int i=0; i<N && maxNum > 0; i++) {
8067                TaskRecord tr = mRecentTasks.get(i);
8068                // Only add calling user or related users recent tasks
8069                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8070                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8071                    continue;
8072                }
8073
8074                // Return the entry if desired by the caller.  We always return
8075                // the first entry, because callers always expect this to be the
8076                // foreground app.  We may filter others if the caller has
8077                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8078                // we should exclude the entry.
8079
8080                if (i == 0
8081                        || withExcluded
8082                        || (tr.intent == null)
8083                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8084                                == 0)) {
8085                    if (!allowed) {
8086                        // If the caller doesn't have the GET_TASKS permission, then only
8087                        // allow them to see a small subset of tasks -- their own and home.
8088                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8089                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8090                            continue;
8091                        }
8092                    }
8093                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8094                        if (tr.stack != null && tr.stack.isHomeStack()) {
8095                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8096                            continue;
8097                        }
8098                    }
8099                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8100                        // Don't include auto remove tasks that are finished or finishing.
8101                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8102                                + tr);
8103                        continue;
8104                    }
8105                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8106                            && !tr.isAvailable) {
8107                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8108                        continue;
8109                    }
8110
8111                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8112                    if (!detailed) {
8113                        rti.baseIntent.replaceExtras((Bundle)null);
8114                    }
8115
8116                    res.add(rti);
8117                    maxNum--;
8118                }
8119            }
8120            return res;
8121        }
8122    }
8123
8124    private TaskRecord recentTaskForIdLocked(int id) {
8125        final int N = mRecentTasks.size();
8126            for (int i=0; i<N; i++) {
8127                TaskRecord tr = mRecentTasks.get(i);
8128                if (tr.taskId == id) {
8129                    return tr;
8130                }
8131            }
8132            return null;
8133    }
8134
8135    @Override
8136    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8137        synchronized (this) {
8138            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8139                    "getTaskThumbnail()");
8140            TaskRecord tr = recentTaskForIdLocked(id);
8141            if (tr != null) {
8142                return tr.getTaskThumbnailLocked();
8143            }
8144        }
8145        return null;
8146    }
8147
8148    @Override
8149    public int addAppTask(IBinder activityToken, Intent intent,
8150            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8151        final int callingUid = Binder.getCallingUid();
8152        final long callingIdent = Binder.clearCallingIdentity();
8153
8154        try {
8155            synchronized (this) {
8156                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8157                if (r == null) {
8158                    throw new IllegalArgumentException("Activity does not exist; token="
8159                            + activityToken);
8160                }
8161                ComponentName comp = intent.getComponent();
8162                if (comp == null) {
8163                    throw new IllegalArgumentException("Intent " + intent
8164                            + " must specify explicit component");
8165                }
8166                if (thumbnail.getWidth() != mThumbnailWidth
8167                        || thumbnail.getHeight() != mThumbnailHeight) {
8168                    throw new IllegalArgumentException("Bad thumbnail size: got "
8169                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8170                            + mThumbnailWidth + "x" + mThumbnailHeight);
8171                }
8172                if (intent.getSelector() != null) {
8173                    intent.setSelector(null);
8174                }
8175                if (intent.getSourceBounds() != null) {
8176                    intent.setSourceBounds(null);
8177                }
8178                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8179                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8180                        // The caller has added this as an auto-remove task...  that makes no
8181                        // sense, so turn off auto-remove.
8182                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8183                    }
8184                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8185                    // Must be a new task.
8186                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8187                }
8188                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8189                    mLastAddedTaskActivity = null;
8190                }
8191                ActivityInfo ainfo = mLastAddedTaskActivity;
8192                if (ainfo == null) {
8193                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8194                            comp, 0, UserHandle.getUserId(callingUid));
8195                    if (ainfo.applicationInfo.uid != callingUid) {
8196                        throw new SecurityException(
8197                                "Can't add task for another application: target uid="
8198                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8199                    }
8200                }
8201
8202                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8203                        intent, description);
8204
8205                int trimIdx = trimRecentsForTask(task, false);
8206                if (trimIdx >= 0) {
8207                    // If this would have caused a trim, then we'll abort because that
8208                    // means it would be added at the end of the list but then just removed.
8209                    return -1;
8210                }
8211
8212                final int N = mRecentTasks.size();
8213                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8214                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8215                    tr.removedFromRecents(mTaskPersister);
8216                }
8217
8218                task.inRecents = true;
8219                mRecentTasks.add(task);
8220                r.task.stack.addTask(task, false, false);
8221
8222                task.setLastThumbnail(thumbnail);
8223                task.freeLastThumbnail();
8224
8225                return task.taskId;
8226            }
8227        } finally {
8228            Binder.restoreCallingIdentity(callingIdent);
8229        }
8230    }
8231
8232    @Override
8233    public Point getAppTaskThumbnailSize() {
8234        synchronized (this) {
8235            return new Point(mThumbnailWidth,  mThumbnailHeight);
8236        }
8237    }
8238
8239    @Override
8240    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8241        synchronized (this) {
8242            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8243            if (r != null) {
8244                r.taskDescription = td;
8245                r.task.updateTaskDescription();
8246            }
8247        }
8248    }
8249
8250    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8251        mRecentTasks.remove(tr);
8252        tr.removedFromRecents(mTaskPersister);
8253        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8254        Intent baseIntent = new Intent(
8255                tr.intent != null ? tr.intent : tr.affinityIntent);
8256        ComponentName component = baseIntent.getComponent();
8257        if (component == null) {
8258            Slog.w(TAG, "Now component for base intent of task: " + tr);
8259            return;
8260        }
8261
8262        // Find any running services associated with this app.
8263        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8264
8265        if (killProcesses) {
8266            // Find any running processes associated with this app.
8267            final String pkg = component.getPackageName();
8268            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8269            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8270            for (int i=0; i<pmap.size(); i++) {
8271                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8272                for (int j=0; j<uids.size(); j++) {
8273                    ProcessRecord proc = uids.valueAt(j);
8274                    if (proc.userId != tr.userId) {
8275                        continue;
8276                    }
8277                    if (!proc.pkgList.containsKey(pkg)) {
8278                        continue;
8279                    }
8280                    procs.add(proc);
8281                }
8282            }
8283
8284            // Kill the running processes.
8285            for (int i=0; i<procs.size(); i++) {
8286                ProcessRecord pr = procs.get(i);
8287                if (pr == mHomeProcess) {
8288                    // Don't kill the home process along with tasks from the same package.
8289                    continue;
8290                }
8291                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8292                    pr.kill("remove task", true);
8293                } else {
8294                    pr.waitingToKill = "remove task";
8295                }
8296            }
8297        }
8298    }
8299
8300    /**
8301     * Removes the task with the specified task id.
8302     *
8303     * @param taskId Identifier of the task to be removed.
8304     * @param flags Additional operational flags.  May be 0 or
8305     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8306     * @return Returns true if the given task was found and removed.
8307     */
8308    private boolean removeTaskByIdLocked(int taskId, int flags) {
8309        TaskRecord tr = recentTaskForIdLocked(taskId);
8310        if (tr != null) {
8311            tr.removeTaskActivitiesLocked();
8312            cleanUpRemovedTaskLocked(tr, flags);
8313            if (tr.isPersistable) {
8314                notifyTaskPersisterLocked(null, true);
8315            }
8316            return true;
8317        }
8318        return false;
8319    }
8320
8321    @Override
8322    public boolean removeTask(int taskId, int flags) {
8323        synchronized (this) {
8324            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8325                    "removeTask()");
8326            long ident = Binder.clearCallingIdentity();
8327            try {
8328                return removeTaskByIdLocked(taskId, flags);
8329            } finally {
8330                Binder.restoreCallingIdentity(ident);
8331            }
8332        }
8333    }
8334
8335    /**
8336     * TODO: Add mController hook
8337     */
8338    @Override
8339    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8340        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8341                "moveTaskToFront()");
8342
8343        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8344        synchronized(this) {
8345            moveTaskToFrontLocked(taskId, flags, options);
8346        }
8347    }
8348
8349    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8350        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8351                Binder.getCallingUid(), "Task to front")) {
8352            ActivityOptions.abort(options);
8353            return;
8354        }
8355        final long origId = Binder.clearCallingIdentity();
8356        try {
8357            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8358            if (task == null) {
8359                return;
8360            }
8361            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8362                mStackSupervisor.showLockTaskToast();
8363                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8364                return;
8365            }
8366            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8367            if (prev != null && prev.isRecentsActivity()) {
8368                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8369            }
8370            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8371        } finally {
8372            Binder.restoreCallingIdentity(origId);
8373        }
8374        ActivityOptions.abort(options);
8375    }
8376
8377    @Override
8378    public void moveTaskToBack(int taskId) {
8379        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8380                "moveTaskToBack()");
8381
8382        synchronized(this) {
8383            TaskRecord tr = recentTaskForIdLocked(taskId);
8384            if (tr != null) {
8385                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8386                ActivityStack stack = tr.stack;
8387                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8388                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8389                            Binder.getCallingUid(), "Task to back")) {
8390                        return;
8391                    }
8392                }
8393                final long origId = Binder.clearCallingIdentity();
8394                try {
8395                    stack.moveTaskToBackLocked(taskId, null);
8396                } finally {
8397                    Binder.restoreCallingIdentity(origId);
8398                }
8399            }
8400        }
8401    }
8402
8403    /**
8404     * Moves an activity, and all of the other activities within the same task, to the bottom
8405     * of the history stack.  The activity's order within the task is unchanged.
8406     *
8407     * @param token A reference to the activity we wish to move
8408     * @param nonRoot If false then this only works if the activity is the root
8409     *                of a task; if true it will work for any activity in a task.
8410     * @return Returns true if the move completed, false if not.
8411     */
8412    @Override
8413    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8414        enforceNotIsolatedCaller("moveActivityTaskToBack");
8415        synchronized(this) {
8416            final long origId = Binder.clearCallingIdentity();
8417            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8418            if (taskId >= 0) {
8419                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8420            }
8421            Binder.restoreCallingIdentity(origId);
8422        }
8423        return false;
8424    }
8425
8426    @Override
8427    public void moveTaskBackwards(int task) {
8428        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8429                "moveTaskBackwards()");
8430
8431        synchronized(this) {
8432            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8433                    Binder.getCallingUid(), "Task backwards")) {
8434                return;
8435            }
8436            final long origId = Binder.clearCallingIdentity();
8437            moveTaskBackwardsLocked(task);
8438            Binder.restoreCallingIdentity(origId);
8439        }
8440    }
8441
8442    private final void moveTaskBackwardsLocked(int task) {
8443        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8444    }
8445
8446    @Override
8447    public IBinder getHomeActivityToken() throws RemoteException {
8448        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8449                "getHomeActivityToken()");
8450        synchronized (this) {
8451            return mStackSupervisor.getHomeActivityToken();
8452        }
8453    }
8454
8455    @Override
8456    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8457            IActivityContainerCallback callback) throws RemoteException {
8458        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8459                "createActivityContainer()");
8460        synchronized (this) {
8461            if (parentActivityToken == null) {
8462                throw new IllegalArgumentException("parent token must not be null");
8463            }
8464            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8465            if (r == null) {
8466                return null;
8467            }
8468            if (callback == null) {
8469                throw new IllegalArgumentException("callback must not be null");
8470            }
8471            return mStackSupervisor.createActivityContainer(r, callback);
8472        }
8473    }
8474
8475    @Override
8476    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8477        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8478                "deleteActivityContainer()");
8479        synchronized (this) {
8480            mStackSupervisor.deleteActivityContainer(container);
8481        }
8482    }
8483
8484    @Override
8485    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8486            throws RemoteException {
8487        synchronized (this) {
8488            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8489            if (stack != null) {
8490                return stack.mActivityContainer;
8491            }
8492            return null;
8493        }
8494    }
8495
8496    @Override
8497    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8498        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8499                "moveTaskToStack()");
8500        if (stackId == HOME_STACK_ID) {
8501            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8502                    new RuntimeException("here").fillInStackTrace());
8503        }
8504        synchronized (this) {
8505            long ident = Binder.clearCallingIdentity();
8506            try {
8507                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8508                        + stackId + " toTop=" + toTop);
8509                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8510            } finally {
8511                Binder.restoreCallingIdentity(ident);
8512            }
8513        }
8514    }
8515
8516    @Override
8517    public void resizeStack(int stackBoxId, Rect bounds) {
8518        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8519                "resizeStackBox()");
8520        long ident = Binder.clearCallingIdentity();
8521        try {
8522            mWindowManager.resizeStack(stackBoxId, bounds);
8523        } finally {
8524            Binder.restoreCallingIdentity(ident);
8525        }
8526    }
8527
8528    @Override
8529    public List<StackInfo> getAllStackInfos() {
8530        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8531                "getAllStackInfos()");
8532        long ident = Binder.clearCallingIdentity();
8533        try {
8534            synchronized (this) {
8535                return mStackSupervisor.getAllStackInfosLocked();
8536            }
8537        } finally {
8538            Binder.restoreCallingIdentity(ident);
8539        }
8540    }
8541
8542    @Override
8543    public StackInfo getStackInfo(int stackId) {
8544        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8545                "getStackInfo()");
8546        long ident = Binder.clearCallingIdentity();
8547        try {
8548            synchronized (this) {
8549                return mStackSupervisor.getStackInfoLocked(stackId);
8550            }
8551        } finally {
8552            Binder.restoreCallingIdentity(ident);
8553        }
8554    }
8555
8556    @Override
8557    public boolean isInHomeStack(int taskId) {
8558        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8559                "getStackInfo()");
8560        long ident = Binder.clearCallingIdentity();
8561        try {
8562            synchronized (this) {
8563                TaskRecord tr = recentTaskForIdLocked(taskId);
8564                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8565            }
8566        } finally {
8567            Binder.restoreCallingIdentity(ident);
8568        }
8569    }
8570
8571    @Override
8572    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8573        synchronized(this) {
8574            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8575        }
8576    }
8577
8578    private boolean isLockTaskAuthorized(String pkg) {
8579        final DevicePolicyManager dpm = (DevicePolicyManager)
8580                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8581        try {
8582            int uid = mContext.getPackageManager().getPackageUid(pkg,
8583                    Binder.getCallingUserHandle().getIdentifier());
8584            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8585        } catch (NameNotFoundException e) {
8586            return false;
8587        }
8588    }
8589
8590    void startLockTaskMode(TaskRecord task) {
8591        final String pkg;
8592        synchronized (this) {
8593            pkg = task.intent.getComponent().getPackageName();
8594        }
8595        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8596        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8597            final TaskRecord taskRecord = task;
8598            mHandler.post(new Runnable() {
8599                @Override
8600                public void run() {
8601                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8602                }
8603            });
8604            return;
8605        }
8606        long ident = Binder.clearCallingIdentity();
8607        try {
8608            synchronized (this) {
8609                // Since we lost lock on task, make sure it is still there.
8610                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8611                if (task != null) {
8612                    if (!isSystemInitiated
8613                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8614                        throw new IllegalArgumentException("Invalid task, not in foreground");
8615                    }
8616                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8617                }
8618            }
8619        } finally {
8620            Binder.restoreCallingIdentity(ident);
8621        }
8622    }
8623
8624    @Override
8625    public void startLockTaskMode(int taskId) {
8626        final TaskRecord task;
8627        long ident = Binder.clearCallingIdentity();
8628        try {
8629            synchronized (this) {
8630                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8631            }
8632        } finally {
8633            Binder.restoreCallingIdentity(ident);
8634        }
8635        if (task != null) {
8636            startLockTaskMode(task);
8637        }
8638    }
8639
8640    @Override
8641    public void startLockTaskMode(IBinder token) {
8642        final TaskRecord task;
8643        long ident = Binder.clearCallingIdentity();
8644        try {
8645            synchronized (this) {
8646                final ActivityRecord r = ActivityRecord.forToken(token);
8647                if (r == null) {
8648                    return;
8649                }
8650                task = r.task;
8651            }
8652        } finally {
8653            Binder.restoreCallingIdentity(ident);
8654        }
8655        if (task != null) {
8656            startLockTaskMode(task);
8657        }
8658    }
8659
8660    @Override
8661    public void startLockTaskModeOnCurrent() throws RemoteException {
8662        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8663        ActivityRecord r = null;
8664        synchronized (this) {
8665            r = mStackSupervisor.topRunningActivityLocked();
8666        }
8667        startLockTaskMode(r.task);
8668    }
8669
8670    @Override
8671    public void stopLockTaskMode() {
8672        // Verify that the user matches the package of the intent for the TaskRecord
8673        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8674        // and stopLockTaskMode.
8675        final int callingUid = Binder.getCallingUid();
8676        if (callingUid != Process.SYSTEM_UID) {
8677            try {
8678                String pkg =
8679                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8680                int uid = mContext.getPackageManager().getPackageUid(pkg,
8681                        Binder.getCallingUserHandle().getIdentifier());
8682                if (uid != callingUid) {
8683                    throw new SecurityException("Invalid uid, expected " + uid);
8684                }
8685            } catch (NameNotFoundException e) {
8686                Log.d(TAG, "stopLockTaskMode " + e);
8687                return;
8688            }
8689        }
8690        long ident = Binder.clearCallingIdentity();
8691        try {
8692            Log.d(TAG, "stopLockTaskMode");
8693            // Stop lock task
8694            synchronized (this) {
8695                mStackSupervisor.setLockTaskModeLocked(null, false);
8696            }
8697        } finally {
8698            Binder.restoreCallingIdentity(ident);
8699        }
8700    }
8701
8702    @Override
8703    public void stopLockTaskModeOnCurrent() throws RemoteException {
8704        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8705        long ident = Binder.clearCallingIdentity();
8706        try {
8707            stopLockTaskMode();
8708        } finally {
8709            Binder.restoreCallingIdentity(ident);
8710        }
8711    }
8712
8713    @Override
8714    public boolean isInLockTaskMode() {
8715        synchronized (this) {
8716            return mStackSupervisor.isInLockTaskMode();
8717        }
8718    }
8719
8720    // =========================================================
8721    // CONTENT PROVIDERS
8722    // =========================================================
8723
8724    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8725        List<ProviderInfo> providers = null;
8726        try {
8727            providers = AppGlobals.getPackageManager().
8728                queryContentProviders(app.processName, app.uid,
8729                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8730        } catch (RemoteException ex) {
8731        }
8732        if (DEBUG_MU)
8733            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8734        int userId = app.userId;
8735        if (providers != null) {
8736            int N = providers.size();
8737            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8738            for (int i=0; i<N; i++) {
8739                ProviderInfo cpi =
8740                    (ProviderInfo)providers.get(i);
8741                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8742                        cpi.name, cpi.flags);
8743                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8744                    // This is a singleton provider, but a user besides the
8745                    // default user is asking to initialize a process it runs
8746                    // in...  well, no, it doesn't actually run in this process,
8747                    // it runs in the process of the default user.  Get rid of it.
8748                    providers.remove(i);
8749                    N--;
8750                    i--;
8751                    continue;
8752                }
8753
8754                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8755                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8756                if (cpr == null) {
8757                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8758                    mProviderMap.putProviderByClass(comp, cpr);
8759                }
8760                if (DEBUG_MU)
8761                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8762                app.pubProviders.put(cpi.name, cpr);
8763                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8764                    // Don't add this if it is a platform component that is marked
8765                    // to run in multiple processes, because this is actually
8766                    // part of the framework so doesn't make sense to track as a
8767                    // separate apk in the process.
8768                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8769                            mProcessStats);
8770                }
8771                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8772            }
8773        }
8774        return providers;
8775    }
8776
8777    /**
8778     * Check if {@link ProcessRecord} has a possible chance at accessing the
8779     * given {@link ProviderInfo}. Final permission checking is always done
8780     * in {@link ContentProvider}.
8781     */
8782    private final String checkContentProviderPermissionLocked(
8783            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8784        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8785        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8786        boolean checkedGrants = false;
8787        if (checkUser) {
8788            // Looking for cross-user grants before enforcing the typical cross-users permissions
8789            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8790            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8791                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8792                    return null;
8793                }
8794                checkedGrants = true;
8795            }
8796            userId = handleIncomingUser(callingPid, callingUid, userId,
8797                    false, ALLOW_NON_FULL,
8798                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8799            if (userId != tmpTargetUserId) {
8800                // When we actually went to determine the final targer user ID, this ended
8801                // up different than our initial check for the authority.  This is because
8802                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8803                // SELF.  So we need to re-check the grants again.
8804                checkedGrants = false;
8805            }
8806        }
8807        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8808                cpi.applicationInfo.uid, cpi.exported)
8809                == PackageManager.PERMISSION_GRANTED) {
8810            return null;
8811        }
8812        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8813                cpi.applicationInfo.uid, cpi.exported)
8814                == PackageManager.PERMISSION_GRANTED) {
8815            return null;
8816        }
8817
8818        PathPermission[] pps = cpi.pathPermissions;
8819        if (pps != null) {
8820            int i = pps.length;
8821            while (i > 0) {
8822                i--;
8823                PathPermission pp = pps[i];
8824                String pprperm = pp.getReadPermission();
8825                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8826                        cpi.applicationInfo.uid, cpi.exported)
8827                        == PackageManager.PERMISSION_GRANTED) {
8828                    return null;
8829                }
8830                String ppwperm = pp.getWritePermission();
8831                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8832                        cpi.applicationInfo.uid, cpi.exported)
8833                        == PackageManager.PERMISSION_GRANTED) {
8834                    return null;
8835                }
8836            }
8837        }
8838        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8839            return null;
8840        }
8841
8842        String msg;
8843        if (!cpi.exported) {
8844            msg = "Permission Denial: opening provider " + cpi.name
8845                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8846                    + ", uid=" + callingUid + ") that is not exported from uid "
8847                    + cpi.applicationInfo.uid;
8848        } else {
8849            msg = "Permission Denial: opening provider " + cpi.name
8850                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8851                    + ", uid=" + callingUid + ") requires "
8852                    + cpi.readPermission + " or " + cpi.writePermission;
8853        }
8854        Slog.w(TAG, msg);
8855        return msg;
8856    }
8857
8858    /**
8859     * Returns if the ContentProvider has granted a uri to callingUid
8860     */
8861    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8862        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8863        if (perms != null) {
8864            for (int i=perms.size()-1; i>=0; i--) {
8865                GrantUri grantUri = perms.keyAt(i);
8866                if (grantUri.sourceUserId == userId || !checkUser) {
8867                    if (matchesProvider(grantUri.uri, cpi)) {
8868                        return true;
8869                    }
8870                }
8871            }
8872        }
8873        return false;
8874    }
8875
8876    /**
8877     * Returns true if the uri authority is one of the authorities specified in the provider.
8878     */
8879    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8880        String uriAuth = uri.getAuthority();
8881        String cpiAuth = cpi.authority;
8882        if (cpiAuth.indexOf(';') == -1) {
8883            return cpiAuth.equals(uriAuth);
8884        }
8885        String[] cpiAuths = cpiAuth.split(";");
8886        int length = cpiAuths.length;
8887        for (int i = 0; i < length; i++) {
8888            if (cpiAuths[i].equals(uriAuth)) return true;
8889        }
8890        return false;
8891    }
8892
8893    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8894            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8895        if (r != null) {
8896            for (int i=0; i<r.conProviders.size(); i++) {
8897                ContentProviderConnection conn = r.conProviders.get(i);
8898                if (conn.provider == cpr) {
8899                    if (DEBUG_PROVIDER) Slog.v(TAG,
8900                            "Adding provider requested by "
8901                            + r.processName + " from process "
8902                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8903                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8904                    if (stable) {
8905                        conn.stableCount++;
8906                        conn.numStableIncs++;
8907                    } else {
8908                        conn.unstableCount++;
8909                        conn.numUnstableIncs++;
8910                    }
8911                    return conn;
8912                }
8913            }
8914            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8915            if (stable) {
8916                conn.stableCount = 1;
8917                conn.numStableIncs = 1;
8918            } else {
8919                conn.unstableCount = 1;
8920                conn.numUnstableIncs = 1;
8921            }
8922            cpr.connections.add(conn);
8923            r.conProviders.add(conn);
8924            return conn;
8925        }
8926        cpr.addExternalProcessHandleLocked(externalProcessToken);
8927        return null;
8928    }
8929
8930    boolean decProviderCountLocked(ContentProviderConnection conn,
8931            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8932        if (conn != null) {
8933            cpr = conn.provider;
8934            if (DEBUG_PROVIDER) Slog.v(TAG,
8935                    "Removing provider requested by "
8936                    + conn.client.processName + " from process "
8937                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8938                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8939            if (stable) {
8940                conn.stableCount--;
8941            } else {
8942                conn.unstableCount--;
8943            }
8944            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8945                cpr.connections.remove(conn);
8946                conn.client.conProviders.remove(conn);
8947                return true;
8948            }
8949            return false;
8950        }
8951        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8952        return false;
8953    }
8954
8955    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8956            String name, IBinder token, boolean stable, int userId) {
8957        ContentProviderRecord cpr;
8958        ContentProviderConnection conn = null;
8959        ProviderInfo cpi = null;
8960
8961        synchronized(this) {
8962            ProcessRecord r = null;
8963            if (caller != null) {
8964                r = getRecordForAppLocked(caller);
8965                if (r == null) {
8966                    throw new SecurityException(
8967                            "Unable to find app for caller " + caller
8968                          + " (pid=" + Binder.getCallingPid()
8969                          + ") when getting content provider " + name);
8970                }
8971            }
8972
8973            boolean checkCrossUser = true;
8974
8975            // First check if this content provider has been published...
8976            cpr = mProviderMap.getProviderByName(name, userId);
8977            // If that didn't work, check if it exists for user 0 and then
8978            // verify that it's a singleton provider before using it.
8979            if (cpr == null && userId != UserHandle.USER_OWNER) {
8980                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8981                if (cpr != null) {
8982                    cpi = cpr.info;
8983                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8984                            cpi.name, cpi.flags)
8985                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8986                        userId = UserHandle.USER_OWNER;
8987                        checkCrossUser = false;
8988                    } else {
8989                        cpr = null;
8990                        cpi = null;
8991                    }
8992                }
8993            }
8994
8995            boolean providerRunning = cpr != null;
8996            if (providerRunning) {
8997                cpi = cpr.info;
8998                String msg;
8999                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9000                        != null) {
9001                    throw new SecurityException(msg);
9002                }
9003
9004                if (r != null && cpr.canRunHere(r)) {
9005                    // This provider has been published or is in the process
9006                    // of being published...  but it is also allowed to run
9007                    // in the caller's process, so don't make a connection
9008                    // and just let the caller instantiate its own instance.
9009                    ContentProviderHolder holder = cpr.newHolder(null);
9010                    // don't give caller the provider object, it needs
9011                    // to make its own.
9012                    holder.provider = null;
9013                    return holder;
9014                }
9015
9016                final long origId = Binder.clearCallingIdentity();
9017
9018                // In this case the provider instance already exists, so we can
9019                // return it right away.
9020                conn = incProviderCountLocked(r, cpr, token, stable);
9021                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9022                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9023                        // If this is a perceptible app accessing the provider,
9024                        // make sure to count it as being accessed and thus
9025                        // back up on the LRU list.  This is good because
9026                        // content providers are often expensive to start.
9027                        updateLruProcessLocked(cpr.proc, false, null);
9028                    }
9029                }
9030
9031                if (cpr.proc != null) {
9032                    if (false) {
9033                        if (cpr.name.flattenToShortString().equals(
9034                                "com.android.providers.calendar/.CalendarProvider2")) {
9035                            Slog.v(TAG, "****************** KILLING "
9036                                + cpr.name.flattenToShortString());
9037                            Process.killProcess(cpr.proc.pid);
9038                        }
9039                    }
9040                    boolean success = updateOomAdjLocked(cpr.proc);
9041                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9042                    // NOTE: there is still a race here where a signal could be
9043                    // pending on the process even though we managed to update its
9044                    // adj level.  Not sure what to do about this, but at least
9045                    // the race is now smaller.
9046                    if (!success) {
9047                        // Uh oh...  it looks like the provider's process
9048                        // has been killed on us.  We need to wait for a new
9049                        // process to be started, and make sure its death
9050                        // doesn't kill our process.
9051                        Slog.i(TAG,
9052                                "Existing provider " + cpr.name.flattenToShortString()
9053                                + " is crashing; detaching " + r);
9054                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9055                        appDiedLocked(cpr.proc);
9056                        if (!lastRef) {
9057                            // This wasn't the last ref our process had on
9058                            // the provider...  we have now been killed, bail.
9059                            return null;
9060                        }
9061                        providerRunning = false;
9062                        conn = null;
9063                    }
9064                }
9065
9066                Binder.restoreCallingIdentity(origId);
9067            }
9068
9069            boolean singleton;
9070            if (!providerRunning) {
9071                try {
9072                    cpi = AppGlobals.getPackageManager().
9073                        resolveContentProvider(name,
9074                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9075                } catch (RemoteException ex) {
9076                }
9077                if (cpi == null) {
9078                    return null;
9079                }
9080                // If the provider is a singleton AND
9081                // (it's a call within the same user || the provider is a
9082                // privileged app)
9083                // Then allow connecting to the singleton provider
9084                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9085                        cpi.name, cpi.flags)
9086                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9087                if (singleton) {
9088                    userId = UserHandle.USER_OWNER;
9089                }
9090                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9091
9092                String msg;
9093                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9094                        != null) {
9095                    throw new SecurityException(msg);
9096                }
9097
9098                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9099                        && !cpi.processName.equals("system")) {
9100                    // If this content provider does not run in the system
9101                    // process, and the system is not yet ready to run other
9102                    // processes, then fail fast instead of hanging.
9103                    throw new IllegalArgumentException(
9104                            "Attempt to launch content provider before system ready");
9105                }
9106
9107                // Make sure that the user who owns this provider is started.  If not,
9108                // we don't want to allow it to run.
9109                if (mStartedUsers.get(userId) == null) {
9110                    Slog.w(TAG, "Unable to launch app "
9111                            + cpi.applicationInfo.packageName + "/"
9112                            + cpi.applicationInfo.uid + " for provider "
9113                            + name + ": user " + userId + " is stopped");
9114                    return null;
9115                }
9116
9117                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9118                cpr = mProviderMap.getProviderByClass(comp, userId);
9119                final boolean firstClass = cpr == null;
9120                if (firstClass) {
9121                    try {
9122                        ApplicationInfo ai =
9123                            AppGlobals.getPackageManager().
9124                                getApplicationInfo(
9125                                        cpi.applicationInfo.packageName,
9126                                        STOCK_PM_FLAGS, userId);
9127                        if (ai == null) {
9128                            Slog.w(TAG, "No package info for content provider "
9129                                    + cpi.name);
9130                            return null;
9131                        }
9132                        ai = getAppInfoForUser(ai, userId);
9133                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9134                    } catch (RemoteException ex) {
9135                        // pm is in same process, this will never happen.
9136                    }
9137                }
9138
9139                if (r != null && cpr.canRunHere(r)) {
9140                    // If this is a multiprocess provider, then just return its
9141                    // info and allow the caller to instantiate it.  Only do
9142                    // this if the provider is the same user as the caller's
9143                    // process, or can run as root (so can be in any process).
9144                    return cpr.newHolder(null);
9145                }
9146
9147                if (DEBUG_PROVIDER) {
9148                    RuntimeException e = new RuntimeException("here");
9149                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9150                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9151                }
9152
9153                // This is single process, and our app is now connecting to it.
9154                // See if we are already in the process of launching this
9155                // provider.
9156                final int N = mLaunchingProviders.size();
9157                int i;
9158                for (i=0; i<N; i++) {
9159                    if (mLaunchingProviders.get(i) == cpr) {
9160                        break;
9161                    }
9162                }
9163
9164                // If the provider is not already being launched, then get it
9165                // started.
9166                if (i >= N) {
9167                    final long origId = Binder.clearCallingIdentity();
9168
9169                    try {
9170                        // Content provider is now in use, its package can't be stopped.
9171                        try {
9172                            AppGlobals.getPackageManager().setPackageStoppedState(
9173                                    cpr.appInfo.packageName, false, userId);
9174                        } catch (RemoteException e) {
9175                        } catch (IllegalArgumentException e) {
9176                            Slog.w(TAG, "Failed trying to unstop package "
9177                                    + cpr.appInfo.packageName + ": " + e);
9178                        }
9179
9180                        // Use existing process if already started
9181                        ProcessRecord proc = getProcessRecordLocked(
9182                                cpi.processName, cpr.appInfo.uid, false);
9183                        if (proc != null && proc.thread != null) {
9184                            if (DEBUG_PROVIDER) {
9185                                Slog.d(TAG, "Installing in existing process " + proc);
9186                            }
9187                            proc.pubProviders.put(cpi.name, cpr);
9188                            try {
9189                                proc.thread.scheduleInstallProvider(cpi);
9190                            } catch (RemoteException e) {
9191                            }
9192                        } else {
9193                            proc = startProcessLocked(cpi.processName,
9194                                    cpr.appInfo, false, 0, "content provider",
9195                                    new ComponentName(cpi.applicationInfo.packageName,
9196                                            cpi.name), false, false, false);
9197                            if (proc == null) {
9198                                Slog.w(TAG, "Unable to launch app "
9199                                        + cpi.applicationInfo.packageName + "/"
9200                                        + cpi.applicationInfo.uid + " for provider "
9201                                        + name + ": process is bad");
9202                                return null;
9203                            }
9204                        }
9205                        cpr.launchingApp = proc;
9206                        mLaunchingProviders.add(cpr);
9207                    } finally {
9208                        Binder.restoreCallingIdentity(origId);
9209                    }
9210                }
9211
9212                // Make sure the provider is published (the same provider class
9213                // may be published under multiple names).
9214                if (firstClass) {
9215                    mProviderMap.putProviderByClass(comp, cpr);
9216                }
9217
9218                mProviderMap.putProviderByName(name, cpr);
9219                conn = incProviderCountLocked(r, cpr, token, stable);
9220                if (conn != null) {
9221                    conn.waiting = true;
9222                }
9223            }
9224        }
9225
9226        // Wait for the provider to be published...
9227        synchronized (cpr) {
9228            while (cpr.provider == null) {
9229                if (cpr.launchingApp == null) {
9230                    Slog.w(TAG, "Unable to launch app "
9231                            + cpi.applicationInfo.packageName + "/"
9232                            + cpi.applicationInfo.uid + " for provider "
9233                            + name + ": launching app became null");
9234                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9235                            UserHandle.getUserId(cpi.applicationInfo.uid),
9236                            cpi.applicationInfo.packageName,
9237                            cpi.applicationInfo.uid, name);
9238                    return null;
9239                }
9240                try {
9241                    if (DEBUG_MU) {
9242                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9243                                + cpr.launchingApp);
9244                    }
9245                    if (conn != null) {
9246                        conn.waiting = true;
9247                    }
9248                    cpr.wait();
9249                } catch (InterruptedException ex) {
9250                } finally {
9251                    if (conn != null) {
9252                        conn.waiting = false;
9253                    }
9254                }
9255            }
9256        }
9257        return cpr != null ? cpr.newHolder(conn) : null;
9258    }
9259
9260    @Override
9261    public final ContentProviderHolder getContentProvider(
9262            IApplicationThread caller, String name, int userId, boolean stable) {
9263        enforceNotIsolatedCaller("getContentProvider");
9264        if (caller == null) {
9265            String msg = "null IApplicationThread when getting content provider "
9266                    + name;
9267            Slog.w(TAG, msg);
9268            throw new SecurityException(msg);
9269        }
9270        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9271        // with cross-user grant.
9272        return getContentProviderImpl(caller, name, null, stable, userId);
9273    }
9274
9275    public ContentProviderHolder getContentProviderExternal(
9276            String name, int userId, IBinder token) {
9277        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9278            "Do not have permission in call getContentProviderExternal()");
9279        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9280                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9281        return getContentProviderExternalUnchecked(name, token, userId);
9282    }
9283
9284    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9285            IBinder token, int userId) {
9286        return getContentProviderImpl(null, name, token, true, userId);
9287    }
9288
9289    /**
9290     * Drop a content provider from a ProcessRecord's bookkeeping
9291     */
9292    public void removeContentProvider(IBinder connection, boolean stable) {
9293        enforceNotIsolatedCaller("removeContentProvider");
9294        long ident = Binder.clearCallingIdentity();
9295        try {
9296            synchronized (this) {
9297                ContentProviderConnection conn;
9298                try {
9299                    conn = (ContentProviderConnection)connection;
9300                } catch (ClassCastException e) {
9301                    String msg ="removeContentProvider: " + connection
9302                            + " not a ContentProviderConnection";
9303                    Slog.w(TAG, msg);
9304                    throw new IllegalArgumentException(msg);
9305                }
9306                if (conn == null) {
9307                    throw new NullPointerException("connection is null");
9308                }
9309                if (decProviderCountLocked(conn, null, null, stable)) {
9310                    updateOomAdjLocked();
9311                }
9312            }
9313        } finally {
9314            Binder.restoreCallingIdentity(ident);
9315        }
9316    }
9317
9318    public void removeContentProviderExternal(String name, IBinder token) {
9319        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9320            "Do not have permission in call removeContentProviderExternal()");
9321        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9322    }
9323
9324    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9325        synchronized (this) {
9326            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9327            if(cpr == null) {
9328                //remove from mProvidersByClass
9329                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9330                return;
9331            }
9332
9333            //update content provider record entry info
9334            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9335            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9336            if (localCpr.hasExternalProcessHandles()) {
9337                if (localCpr.removeExternalProcessHandleLocked(token)) {
9338                    updateOomAdjLocked();
9339                } else {
9340                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9341                            + " with no external reference for token: "
9342                            + token + ".");
9343                }
9344            } else {
9345                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9346                        + " with no external references.");
9347            }
9348        }
9349    }
9350
9351    public final void publishContentProviders(IApplicationThread caller,
9352            List<ContentProviderHolder> providers) {
9353        if (providers == null) {
9354            return;
9355        }
9356
9357        enforceNotIsolatedCaller("publishContentProviders");
9358        synchronized (this) {
9359            final ProcessRecord r = getRecordForAppLocked(caller);
9360            if (DEBUG_MU)
9361                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9362            if (r == null) {
9363                throw new SecurityException(
9364                        "Unable to find app for caller " + caller
9365                      + " (pid=" + Binder.getCallingPid()
9366                      + ") when publishing content providers");
9367            }
9368
9369            final long origId = Binder.clearCallingIdentity();
9370
9371            final int N = providers.size();
9372            for (int i=0; i<N; i++) {
9373                ContentProviderHolder src = providers.get(i);
9374                if (src == null || src.info == null || src.provider == null) {
9375                    continue;
9376                }
9377                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9378                if (DEBUG_MU)
9379                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9380                if (dst != null) {
9381                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9382                    mProviderMap.putProviderByClass(comp, dst);
9383                    String names[] = dst.info.authority.split(";");
9384                    for (int j = 0; j < names.length; j++) {
9385                        mProviderMap.putProviderByName(names[j], dst);
9386                    }
9387
9388                    int NL = mLaunchingProviders.size();
9389                    int j;
9390                    for (j=0; j<NL; j++) {
9391                        if (mLaunchingProviders.get(j) == dst) {
9392                            mLaunchingProviders.remove(j);
9393                            j--;
9394                            NL--;
9395                        }
9396                    }
9397                    synchronized (dst) {
9398                        dst.provider = src.provider;
9399                        dst.proc = r;
9400                        dst.notifyAll();
9401                    }
9402                    updateOomAdjLocked(r);
9403                }
9404            }
9405
9406            Binder.restoreCallingIdentity(origId);
9407        }
9408    }
9409
9410    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9411        ContentProviderConnection conn;
9412        try {
9413            conn = (ContentProviderConnection)connection;
9414        } catch (ClassCastException e) {
9415            String msg ="refContentProvider: " + connection
9416                    + " not a ContentProviderConnection";
9417            Slog.w(TAG, msg);
9418            throw new IllegalArgumentException(msg);
9419        }
9420        if (conn == null) {
9421            throw new NullPointerException("connection is null");
9422        }
9423
9424        synchronized (this) {
9425            if (stable > 0) {
9426                conn.numStableIncs += stable;
9427            }
9428            stable = conn.stableCount + stable;
9429            if (stable < 0) {
9430                throw new IllegalStateException("stableCount < 0: " + stable);
9431            }
9432
9433            if (unstable > 0) {
9434                conn.numUnstableIncs += unstable;
9435            }
9436            unstable = conn.unstableCount + unstable;
9437            if (unstable < 0) {
9438                throw new IllegalStateException("unstableCount < 0: " + unstable);
9439            }
9440
9441            if ((stable+unstable) <= 0) {
9442                throw new IllegalStateException("ref counts can't go to zero here: stable="
9443                        + stable + " unstable=" + unstable);
9444            }
9445            conn.stableCount = stable;
9446            conn.unstableCount = unstable;
9447            return !conn.dead;
9448        }
9449    }
9450
9451    public void unstableProviderDied(IBinder connection) {
9452        ContentProviderConnection conn;
9453        try {
9454            conn = (ContentProviderConnection)connection;
9455        } catch (ClassCastException e) {
9456            String msg ="refContentProvider: " + connection
9457                    + " not a ContentProviderConnection";
9458            Slog.w(TAG, msg);
9459            throw new IllegalArgumentException(msg);
9460        }
9461        if (conn == null) {
9462            throw new NullPointerException("connection is null");
9463        }
9464
9465        // Safely retrieve the content provider associated with the connection.
9466        IContentProvider provider;
9467        synchronized (this) {
9468            provider = conn.provider.provider;
9469        }
9470
9471        if (provider == null) {
9472            // Um, yeah, we're way ahead of you.
9473            return;
9474        }
9475
9476        // Make sure the caller is being honest with us.
9477        if (provider.asBinder().pingBinder()) {
9478            // Er, no, still looks good to us.
9479            synchronized (this) {
9480                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9481                        + " says " + conn + " died, but we don't agree");
9482                return;
9483            }
9484        }
9485
9486        // Well look at that!  It's dead!
9487        synchronized (this) {
9488            if (conn.provider.provider != provider) {
9489                // But something changed...  good enough.
9490                return;
9491            }
9492
9493            ProcessRecord proc = conn.provider.proc;
9494            if (proc == null || proc.thread == null) {
9495                // Seems like the process is already cleaned up.
9496                return;
9497            }
9498
9499            // As far as we're concerned, this is just like receiving a
9500            // death notification...  just a bit prematurely.
9501            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9502                    + ") early provider death");
9503            final long ident = Binder.clearCallingIdentity();
9504            try {
9505                appDiedLocked(proc);
9506            } finally {
9507                Binder.restoreCallingIdentity(ident);
9508            }
9509        }
9510    }
9511
9512    @Override
9513    public void appNotRespondingViaProvider(IBinder connection) {
9514        enforceCallingPermission(
9515                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9516
9517        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9518        if (conn == null) {
9519            Slog.w(TAG, "ContentProviderConnection is null");
9520            return;
9521        }
9522
9523        final ProcessRecord host = conn.provider.proc;
9524        if (host == null) {
9525            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9526            return;
9527        }
9528
9529        final long token = Binder.clearCallingIdentity();
9530        try {
9531            appNotResponding(host, null, null, false, "ContentProvider not responding");
9532        } finally {
9533            Binder.restoreCallingIdentity(token);
9534        }
9535    }
9536
9537    public final void installSystemProviders() {
9538        List<ProviderInfo> providers;
9539        synchronized (this) {
9540            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9541            providers = generateApplicationProvidersLocked(app);
9542            if (providers != null) {
9543                for (int i=providers.size()-1; i>=0; i--) {
9544                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9545                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9546                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9547                                + ": not system .apk");
9548                        providers.remove(i);
9549                    }
9550                }
9551            }
9552        }
9553        if (providers != null) {
9554            mSystemThread.installSystemProviders(providers);
9555        }
9556
9557        mCoreSettingsObserver = new CoreSettingsObserver(this);
9558
9559        //mUsageStatsService.monitorPackages();
9560    }
9561
9562    /**
9563     * Allows apps to retrieve the MIME type of a URI.
9564     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9565     * users, then it does not need permission to access the ContentProvider.
9566     * Either, it needs cross-user uri grants.
9567     *
9568     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9569     *
9570     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9571     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9572     */
9573    public String getProviderMimeType(Uri uri, int userId) {
9574        enforceNotIsolatedCaller("getProviderMimeType");
9575        final String name = uri.getAuthority();
9576        int callingUid = Binder.getCallingUid();
9577        int callingPid = Binder.getCallingPid();
9578        long ident = 0;
9579        boolean clearedIdentity = false;
9580        userId = unsafeConvertIncomingUser(userId);
9581        if (UserHandle.getUserId(callingUid) != userId) {
9582            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9583                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9584                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9585                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9586                clearedIdentity = true;
9587                ident = Binder.clearCallingIdentity();
9588            }
9589        }
9590        ContentProviderHolder holder = null;
9591        try {
9592            holder = getContentProviderExternalUnchecked(name, null, userId);
9593            if (holder != null) {
9594                return holder.provider.getType(uri);
9595            }
9596        } catch (RemoteException e) {
9597            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9598            return null;
9599        } finally {
9600            // We need to clear the identity to call removeContentProviderExternalUnchecked
9601            if (!clearedIdentity) {
9602                ident = Binder.clearCallingIdentity();
9603            }
9604            try {
9605                if (holder != null) {
9606                    removeContentProviderExternalUnchecked(name, null, userId);
9607                }
9608            } finally {
9609                Binder.restoreCallingIdentity(ident);
9610            }
9611        }
9612
9613        return null;
9614    }
9615
9616    // =========================================================
9617    // GLOBAL MANAGEMENT
9618    // =========================================================
9619
9620    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9621            boolean isolated, int isolatedUid) {
9622        String proc = customProcess != null ? customProcess : info.processName;
9623        BatteryStatsImpl.Uid.Proc ps = null;
9624        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9625        int uid = info.uid;
9626        if (isolated) {
9627            if (isolatedUid == 0) {
9628                int userId = UserHandle.getUserId(uid);
9629                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9630                while (true) {
9631                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9632                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9633                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9634                    }
9635                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9636                    mNextIsolatedProcessUid++;
9637                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9638                        // No process for this uid, use it.
9639                        break;
9640                    }
9641                    stepsLeft--;
9642                    if (stepsLeft <= 0) {
9643                        return null;
9644                    }
9645                }
9646            } else {
9647                // Special case for startIsolatedProcess (internal only), where
9648                // the uid of the isolated process is specified by the caller.
9649                uid = isolatedUid;
9650            }
9651        }
9652        return new ProcessRecord(stats, info, proc, uid);
9653    }
9654
9655    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9656            String abiOverride) {
9657        ProcessRecord app;
9658        if (!isolated) {
9659            app = getProcessRecordLocked(info.processName, info.uid, true);
9660        } else {
9661            app = null;
9662        }
9663
9664        if (app == null) {
9665            app = newProcessRecordLocked(info, null, isolated, 0);
9666            mProcessNames.put(info.processName, app.uid, app);
9667            if (isolated) {
9668                mIsolatedProcesses.put(app.uid, app);
9669            }
9670            updateLruProcessLocked(app, false, null);
9671            updateOomAdjLocked();
9672        }
9673
9674        // This package really, really can not be stopped.
9675        try {
9676            AppGlobals.getPackageManager().setPackageStoppedState(
9677                    info.packageName, false, UserHandle.getUserId(app.uid));
9678        } catch (RemoteException e) {
9679        } catch (IllegalArgumentException e) {
9680            Slog.w(TAG, "Failed trying to unstop package "
9681                    + info.packageName + ": " + e);
9682        }
9683
9684        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9685                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9686            app.persistent = true;
9687            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9688        }
9689        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9690            mPersistentStartingProcesses.add(app);
9691            startProcessLocked(app, "added application", app.processName, abiOverride,
9692                    null /* entryPoint */, null /* entryPointArgs */);
9693        }
9694
9695        return app;
9696    }
9697
9698    public void unhandledBack() {
9699        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9700                "unhandledBack()");
9701
9702        synchronized(this) {
9703            final long origId = Binder.clearCallingIdentity();
9704            try {
9705                getFocusedStack().unhandledBackLocked();
9706            } finally {
9707                Binder.restoreCallingIdentity(origId);
9708            }
9709        }
9710    }
9711
9712    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9713        enforceNotIsolatedCaller("openContentUri");
9714        final int userId = UserHandle.getCallingUserId();
9715        String name = uri.getAuthority();
9716        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9717        ParcelFileDescriptor pfd = null;
9718        if (cph != null) {
9719            // We record the binder invoker's uid in thread-local storage before
9720            // going to the content provider to open the file.  Later, in the code
9721            // that handles all permissions checks, we look for this uid and use
9722            // that rather than the Activity Manager's own uid.  The effect is that
9723            // we do the check against the caller's permissions even though it looks
9724            // to the content provider like the Activity Manager itself is making
9725            // the request.
9726            sCallerIdentity.set(new Identity(
9727                    Binder.getCallingPid(), Binder.getCallingUid()));
9728            try {
9729                pfd = cph.provider.openFile(null, uri, "r", null);
9730            } catch (FileNotFoundException e) {
9731                // do nothing; pfd will be returned null
9732            } finally {
9733                // Ensure that whatever happens, we clean up the identity state
9734                sCallerIdentity.remove();
9735            }
9736
9737            // We've got the fd now, so we're done with the provider.
9738            removeContentProviderExternalUnchecked(name, null, userId);
9739        } else {
9740            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9741        }
9742        return pfd;
9743    }
9744
9745    // Actually is sleeping or shutting down or whatever else in the future
9746    // is an inactive state.
9747    public boolean isSleepingOrShuttingDown() {
9748        return mSleeping || mShuttingDown;
9749    }
9750
9751    public boolean isSleeping() {
9752        return mSleeping;
9753    }
9754
9755    void goingToSleep() {
9756        synchronized(this) {
9757            mWentToSleep = true;
9758            updateEventDispatchingLocked();
9759            goToSleepIfNeededLocked();
9760        }
9761    }
9762
9763    void finishRunningVoiceLocked() {
9764        if (mRunningVoice) {
9765            mRunningVoice = false;
9766            goToSleepIfNeededLocked();
9767        }
9768    }
9769
9770    void goToSleepIfNeededLocked() {
9771        if (mWentToSleep && !mRunningVoice) {
9772            if (!mSleeping) {
9773                mSleeping = true;
9774                mStackSupervisor.goingToSleepLocked();
9775
9776                // Initialize the wake times of all processes.
9777                checkExcessivePowerUsageLocked(false);
9778                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9779                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9780                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9781            }
9782        }
9783    }
9784
9785    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9786        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9787            // Never persist the home stack.
9788            return;
9789        }
9790        mTaskPersister.wakeup(task, flush);
9791    }
9792
9793    @Override
9794    public boolean shutdown(int timeout) {
9795        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9796                != PackageManager.PERMISSION_GRANTED) {
9797            throw new SecurityException("Requires permission "
9798                    + android.Manifest.permission.SHUTDOWN);
9799        }
9800
9801        boolean timedout = false;
9802
9803        synchronized(this) {
9804            mShuttingDown = true;
9805            updateEventDispatchingLocked();
9806            timedout = mStackSupervisor.shutdownLocked(timeout);
9807        }
9808
9809        mAppOpsService.shutdown();
9810        if (mUsageStatsService != null) {
9811            mUsageStatsService.prepareShutdown();
9812        }
9813        mBatteryStatsService.shutdown();
9814        synchronized (this) {
9815            mProcessStats.shutdownLocked();
9816        }
9817        notifyTaskPersisterLocked(null, true);
9818
9819        return timedout;
9820    }
9821
9822    public final void activitySlept(IBinder token) {
9823        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9824
9825        final long origId = Binder.clearCallingIdentity();
9826
9827        synchronized (this) {
9828            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9829            if (r != null) {
9830                mStackSupervisor.activitySleptLocked(r);
9831            }
9832        }
9833
9834        Binder.restoreCallingIdentity(origId);
9835    }
9836
9837    void logLockScreen(String msg) {
9838        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9839                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9840                mWentToSleep + " mSleeping=" + mSleeping);
9841    }
9842
9843    private void comeOutOfSleepIfNeededLocked() {
9844        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9845            if (mSleeping) {
9846                mSleeping = false;
9847                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9848            }
9849        }
9850    }
9851
9852    void wakingUp() {
9853        synchronized(this) {
9854            mWentToSleep = false;
9855            updateEventDispatchingLocked();
9856            comeOutOfSleepIfNeededLocked();
9857        }
9858    }
9859
9860    void startRunningVoiceLocked() {
9861        if (!mRunningVoice) {
9862            mRunningVoice = true;
9863            comeOutOfSleepIfNeededLocked();
9864        }
9865    }
9866
9867    private void updateEventDispatchingLocked() {
9868        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9869    }
9870
9871    public void setLockScreenShown(boolean shown) {
9872        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9873                != PackageManager.PERMISSION_GRANTED) {
9874            throw new SecurityException("Requires permission "
9875                    + android.Manifest.permission.DEVICE_POWER);
9876        }
9877
9878        synchronized(this) {
9879            long ident = Binder.clearCallingIdentity();
9880            try {
9881                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9882                mLockScreenShown = shown;
9883                comeOutOfSleepIfNeededLocked();
9884            } finally {
9885                Binder.restoreCallingIdentity(ident);
9886            }
9887        }
9888    }
9889
9890    @Override
9891    public void stopAppSwitches() {
9892        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9893                != PackageManager.PERMISSION_GRANTED) {
9894            throw new SecurityException("Requires permission "
9895                    + android.Manifest.permission.STOP_APP_SWITCHES);
9896        }
9897
9898        synchronized(this) {
9899            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9900                    + APP_SWITCH_DELAY_TIME;
9901            mDidAppSwitch = false;
9902            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9903            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9904            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9905        }
9906    }
9907
9908    public void resumeAppSwitches() {
9909        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9910                != PackageManager.PERMISSION_GRANTED) {
9911            throw new SecurityException("Requires permission "
9912                    + android.Manifest.permission.STOP_APP_SWITCHES);
9913        }
9914
9915        synchronized(this) {
9916            // Note that we don't execute any pending app switches... we will
9917            // let those wait until either the timeout, or the next start
9918            // activity request.
9919            mAppSwitchesAllowedTime = 0;
9920        }
9921    }
9922
9923    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9924            String name) {
9925        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9926            return true;
9927        }
9928
9929        final int perm = checkComponentPermission(
9930                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9931                callingUid, -1, true);
9932        if (perm == PackageManager.PERMISSION_GRANTED) {
9933            return true;
9934        }
9935
9936        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9937        return false;
9938    }
9939
9940    public void setDebugApp(String packageName, boolean waitForDebugger,
9941            boolean persistent) {
9942        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9943                "setDebugApp()");
9944
9945        long ident = Binder.clearCallingIdentity();
9946        try {
9947            // Note that this is not really thread safe if there are multiple
9948            // callers into it at the same time, but that's not a situation we
9949            // care about.
9950            if (persistent) {
9951                final ContentResolver resolver = mContext.getContentResolver();
9952                Settings.Global.putString(
9953                    resolver, Settings.Global.DEBUG_APP,
9954                    packageName);
9955                Settings.Global.putInt(
9956                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9957                    waitForDebugger ? 1 : 0);
9958            }
9959
9960            synchronized (this) {
9961                if (!persistent) {
9962                    mOrigDebugApp = mDebugApp;
9963                    mOrigWaitForDebugger = mWaitForDebugger;
9964                }
9965                mDebugApp = packageName;
9966                mWaitForDebugger = waitForDebugger;
9967                mDebugTransient = !persistent;
9968                if (packageName != null) {
9969                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9970                            false, UserHandle.USER_ALL, "set debug app");
9971                }
9972            }
9973        } finally {
9974            Binder.restoreCallingIdentity(ident);
9975        }
9976    }
9977
9978    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9979        synchronized (this) {
9980            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9981            if (!isDebuggable) {
9982                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9983                    throw new SecurityException("Process not debuggable: " + app.packageName);
9984                }
9985            }
9986
9987            mOpenGlTraceApp = processName;
9988        }
9989    }
9990
9991    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
9992        synchronized (this) {
9993            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9994            if (!isDebuggable) {
9995                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9996                    throw new SecurityException("Process not debuggable: " + app.packageName);
9997                }
9998            }
9999            mProfileApp = processName;
10000            mProfileFile = profilerInfo.profileFile;
10001            if (mProfileFd != null) {
10002                try {
10003                    mProfileFd.close();
10004                } catch (IOException e) {
10005                }
10006                mProfileFd = null;
10007            }
10008            mProfileFd = profilerInfo.profileFd;
10009            mSamplingInterval = profilerInfo.samplingInterval;
10010            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10011            mProfileType = 0;
10012        }
10013    }
10014
10015    @Override
10016    public void setAlwaysFinish(boolean enabled) {
10017        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10018                "setAlwaysFinish()");
10019
10020        Settings.Global.putInt(
10021                mContext.getContentResolver(),
10022                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10023
10024        synchronized (this) {
10025            mAlwaysFinishActivities = enabled;
10026        }
10027    }
10028
10029    @Override
10030    public void setActivityController(IActivityController controller) {
10031        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10032                "setActivityController()");
10033        synchronized (this) {
10034            mController = controller;
10035            Watchdog.getInstance().setActivityController(controller);
10036        }
10037    }
10038
10039    @Override
10040    public void setUserIsMonkey(boolean userIsMonkey) {
10041        synchronized (this) {
10042            synchronized (mPidsSelfLocked) {
10043                final int callingPid = Binder.getCallingPid();
10044                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10045                if (precessRecord == null) {
10046                    throw new SecurityException("Unknown process: " + callingPid);
10047                }
10048                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10049                    throw new SecurityException("Only an instrumentation process "
10050                            + "with a UiAutomation can call setUserIsMonkey");
10051                }
10052            }
10053            mUserIsMonkey = userIsMonkey;
10054        }
10055    }
10056
10057    @Override
10058    public boolean isUserAMonkey() {
10059        synchronized (this) {
10060            // If there is a controller also implies the user is a monkey.
10061            return (mUserIsMonkey || mController != null);
10062        }
10063    }
10064
10065    public void requestBugReport() {
10066        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10067        SystemProperties.set("ctl.start", "bugreport");
10068    }
10069
10070    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10071        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10072    }
10073
10074    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10075        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10076            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10077        }
10078        return KEY_DISPATCHING_TIMEOUT;
10079    }
10080
10081    @Override
10082    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10083        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10084                != PackageManager.PERMISSION_GRANTED) {
10085            throw new SecurityException("Requires permission "
10086                    + android.Manifest.permission.FILTER_EVENTS);
10087        }
10088        ProcessRecord proc;
10089        long timeout;
10090        synchronized (this) {
10091            synchronized (mPidsSelfLocked) {
10092                proc = mPidsSelfLocked.get(pid);
10093            }
10094            timeout = getInputDispatchingTimeoutLocked(proc);
10095        }
10096
10097        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10098            return -1;
10099        }
10100
10101        return timeout;
10102    }
10103
10104    /**
10105     * Handle input dispatching timeouts.
10106     * Returns whether input dispatching should be aborted or not.
10107     */
10108    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10109            final ActivityRecord activity, final ActivityRecord parent,
10110            final boolean aboveSystem, String reason) {
10111        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10112                != PackageManager.PERMISSION_GRANTED) {
10113            throw new SecurityException("Requires permission "
10114                    + android.Manifest.permission.FILTER_EVENTS);
10115        }
10116
10117        final String annotation;
10118        if (reason == null) {
10119            annotation = "Input dispatching timed out";
10120        } else {
10121            annotation = "Input dispatching timed out (" + reason + ")";
10122        }
10123
10124        if (proc != null) {
10125            synchronized (this) {
10126                if (proc.debugging) {
10127                    return false;
10128                }
10129
10130                if (mDidDexOpt) {
10131                    // Give more time since we were dexopting.
10132                    mDidDexOpt = false;
10133                    return false;
10134                }
10135
10136                if (proc.instrumentationClass != null) {
10137                    Bundle info = new Bundle();
10138                    info.putString("shortMsg", "keyDispatchingTimedOut");
10139                    info.putString("longMsg", annotation);
10140                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10141                    return true;
10142                }
10143            }
10144            mHandler.post(new Runnable() {
10145                @Override
10146                public void run() {
10147                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10148                }
10149            });
10150        }
10151
10152        return true;
10153    }
10154
10155    public Bundle getAssistContextExtras(int requestType) {
10156        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10157                "getAssistContextExtras()");
10158        PendingAssistExtras pae;
10159        Bundle extras = new Bundle();
10160        synchronized (this) {
10161            ActivityRecord activity = getFocusedStack().mResumedActivity;
10162            if (activity == null) {
10163                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10164                return null;
10165            }
10166            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10167            if (activity.app == null || activity.app.thread == null) {
10168                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10169                return extras;
10170            }
10171            if (activity.app.pid == Binder.getCallingPid()) {
10172                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10173                return extras;
10174            }
10175            pae = new PendingAssistExtras(activity);
10176            try {
10177                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10178                        requestType);
10179                mPendingAssistExtras.add(pae);
10180                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10181            } catch (RemoteException e) {
10182                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10183                return extras;
10184            }
10185        }
10186        synchronized (pae) {
10187            while (!pae.haveResult) {
10188                try {
10189                    pae.wait();
10190                } catch (InterruptedException e) {
10191                }
10192            }
10193            if (pae.result != null) {
10194                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10195            }
10196        }
10197        synchronized (this) {
10198            mPendingAssistExtras.remove(pae);
10199            mHandler.removeCallbacks(pae);
10200        }
10201        return extras;
10202    }
10203
10204    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10205        PendingAssistExtras pae = (PendingAssistExtras)token;
10206        synchronized (pae) {
10207            pae.result = extras;
10208            pae.haveResult = true;
10209            pae.notifyAll();
10210        }
10211    }
10212
10213    public void registerProcessObserver(IProcessObserver observer) {
10214        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10215                "registerProcessObserver()");
10216        synchronized (this) {
10217            mProcessObservers.register(observer);
10218        }
10219    }
10220
10221    @Override
10222    public void unregisterProcessObserver(IProcessObserver observer) {
10223        synchronized (this) {
10224            mProcessObservers.unregister(observer);
10225        }
10226    }
10227
10228    @Override
10229    public boolean convertFromTranslucent(IBinder token) {
10230        final long origId = Binder.clearCallingIdentity();
10231        try {
10232            synchronized (this) {
10233                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10234                if (r == null) {
10235                    return false;
10236                }
10237                if (r.changeWindowTranslucency(true)) {
10238                    mWindowManager.setAppFullscreen(token, true);
10239                    r.task.stack.releaseBackgroundResources();
10240                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10241                    return true;
10242                }
10243                return false;
10244            }
10245        } finally {
10246            Binder.restoreCallingIdentity(origId);
10247        }
10248    }
10249
10250    @Override
10251    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10252        final long origId = Binder.clearCallingIdentity();
10253        try {
10254            synchronized (this) {
10255                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10256                if (r == null) {
10257                    return false;
10258                }
10259                int index = r.task.mActivities.lastIndexOf(r);
10260                if (index > 0) {
10261                    ActivityRecord under = r.task.mActivities.get(index - 1);
10262                    under.returningOptions = options;
10263                }
10264                if (r.changeWindowTranslucency(false)) {
10265                    r.task.stack.convertToTranslucent(r);
10266                    mWindowManager.setAppFullscreen(token, false);
10267                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10268                    return true;
10269                } else {
10270                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10271                    return false;
10272                }
10273            }
10274        } finally {
10275            Binder.restoreCallingIdentity(origId);
10276        }
10277    }
10278
10279    @Override
10280    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10281        final long origId = Binder.clearCallingIdentity();
10282        try {
10283            synchronized (this) {
10284                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10285                if (r != null) {
10286                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10287                }
10288            }
10289            return false;
10290        } finally {
10291            Binder.restoreCallingIdentity(origId);
10292        }
10293    }
10294
10295    @Override
10296    public boolean isBackgroundVisibleBehind(IBinder token) {
10297        final long origId = Binder.clearCallingIdentity();
10298        try {
10299            synchronized (this) {
10300                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10301                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10302                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10303                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10304                return visible;
10305            }
10306        } finally {
10307            Binder.restoreCallingIdentity(origId);
10308        }
10309    }
10310
10311    @Override
10312    public ActivityOptions getActivityOptions(IBinder token) {
10313        final long origId = Binder.clearCallingIdentity();
10314        try {
10315            synchronized (this) {
10316                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10317                if (r != null) {
10318                    final ActivityOptions activityOptions = r.pendingOptions;
10319                    r.pendingOptions = null;
10320                    return activityOptions;
10321                }
10322                return null;
10323            }
10324        } finally {
10325            Binder.restoreCallingIdentity(origId);
10326        }
10327    }
10328
10329    @Override
10330    public void setImmersive(IBinder token, boolean immersive) {
10331        synchronized(this) {
10332            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10333            if (r == null) {
10334                throw new IllegalArgumentException();
10335            }
10336            r.immersive = immersive;
10337
10338            // update associated state if we're frontmost
10339            if (r == mFocusedActivity) {
10340                if (DEBUG_IMMERSIVE) {
10341                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10342                }
10343                applyUpdateLockStateLocked(r);
10344            }
10345        }
10346    }
10347
10348    @Override
10349    public boolean isImmersive(IBinder token) {
10350        synchronized (this) {
10351            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10352            if (r == null) {
10353                throw new IllegalArgumentException();
10354            }
10355            return r.immersive;
10356        }
10357    }
10358
10359    public boolean isTopActivityImmersive() {
10360        enforceNotIsolatedCaller("startActivity");
10361        synchronized (this) {
10362            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10363            return (r != null) ? r.immersive : false;
10364        }
10365    }
10366
10367    @Override
10368    public boolean isTopOfTask(IBinder token) {
10369        synchronized (this) {
10370            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10371            if (r == null) {
10372                throw new IllegalArgumentException();
10373            }
10374            return r.task.getTopActivity() == r;
10375        }
10376    }
10377
10378    public final void enterSafeMode() {
10379        synchronized(this) {
10380            // It only makes sense to do this before the system is ready
10381            // and started launching other packages.
10382            if (!mSystemReady) {
10383                try {
10384                    AppGlobals.getPackageManager().enterSafeMode();
10385                } catch (RemoteException e) {
10386                }
10387            }
10388
10389            mSafeMode = true;
10390        }
10391    }
10392
10393    public final void showSafeModeOverlay() {
10394        View v = LayoutInflater.from(mContext).inflate(
10395                com.android.internal.R.layout.safe_mode, null);
10396        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10397        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10398        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10399        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10400        lp.gravity = Gravity.BOTTOM | Gravity.START;
10401        lp.format = v.getBackground().getOpacity();
10402        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10403                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10404        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10405        ((WindowManager)mContext.getSystemService(
10406                Context.WINDOW_SERVICE)).addView(v, lp);
10407    }
10408
10409    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10410        if (!(sender instanceof PendingIntentRecord)) {
10411            return;
10412        }
10413        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10414        synchronized (stats) {
10415            if (mBatteryStatsService.isOnBattery()) {
10416                mBatteryStatsService.enforceCallingPermission();
10417                PendingIntentRecord rec = (PendingIntentRecord)sender;
10418                int MY_UID = Binder.getCallingUid();
10419                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10420                BatteryStatsImpl.Uid.Pkg pkg =
10421                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10422                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10423                pkg.incWakeupsLocked();
10424            }
10425        }
10426    }
10427
10428    public boolean killPids(int[] pids, String pReason, boolean secure) {
10429        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10430            throw new SecurityException("killPids only available to the system");
10431        }
10432        String reason = (pReason == null) ? "Unknown" : pReason;
10433        // XXX Note: don't acquire main activity lock here, because the window
10434        // manager calls in with its locks held.
10435
10436        boolean killed = false;
10437        synchronized (mPidsSelfLocked) {
10438            int[] types = new int[pids.length];
10439            int worstType = 0;
10440            for (int i=0; i<pids.length; i++) {
10441                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10442                if (proc != null) {
10443                    int type = proc.setAdj;
10444                    types[i] = type;
10445                    if (type > worstType) {
10446                        worstType = type;
10447                    }
10448                }
10449            }
10450
10451            // If the worst oom_adj is somewhere in the cached proc LRU range,
10452            // then constrain it so we will kill all cached procs.
10453            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10454                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10455                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10456            }
10457
10458            // If this is not a secure call, don't let it kill processes that
10459            // are important.
10460            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10461                worstType = ProcessList.SERVICE_ADJ;
10462            }
10463
10464            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10465            for (int i=0; i<pids.length; i++) {
10466                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10467                if (proc == null) {
10468                    continue;
10469                }
10470                int adj = proc.setAdj;
10471                if (adj >= worstType && !proc.killedByAm) {
10472                    proc.kill(reason, true);
10473                    killed = true;
10474                }
10475            }
10476        }
10477        return killed;
10478    }
10479
10480    @Override
10481    public void killUid(int uid, String reason) {
10482        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10483            throw new SecurityException("killUid only available to the system");
10484        }
10485        synchronized (this) {
10486            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10487                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10488                    reason != null ? reason : "kill uid");
10489        }
10490    }
10491
10492    @Override
10493    public boolean killProcessesBelowForeground(String reason) {
10494        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10495            throw new SecurityException("killProcessesBelowForeground() only available to system");
10496        }
10497
10498        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10499    }
10500
10501    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10502        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10503            throw new SecurityException("killProcessesBelowAdj() only available to system");
10504        }
10505
10506        boolean killed = false;
10507        synchronized (mPidsSelfLocked) {
10508            final int size = mPidsSelfLocked.size();
10509            for (int i = 0; i < size; i++) {
10510                final int pid = mPidsSelfLocked.keyAt(i);
10511                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10512                if (proc == null) continue;
10513
10514                final int adj = proc.setAdj;
10515                if (adj > belowAdj && !proc.killedByAm) {
10516                    proc.kill(reason, true);
10517                    killed = true;
10518                }
10519            }
10520        }
10521        return killed;
10522    }
10523
10524    @Override
10525    public void hang(final IBinder who, boolean allowRestart) {
10526        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10527                != PackageManager.PERMISSION_GRANTED) {
10528            throw new SecurityException("Requires permission "
10529                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10530        }
10531
10532        final IBinder.DeathRecipient death = new DeathRecipient() {
10533            @Override
10534            public void binderDied() {
10535                synchronized (this) {
10536                    notifyAll();
10537                }
10538            }
10539        };
10540
10541        try {
10542            who.linkToDeath(death, 0);
10543        } catch (RemoteException e) {
10544            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10545            return;
10546        }
10547
10548        synchronized (this) {
10549            Watchdog.getInstance().setAllowRestart(allowRestart);
10550            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10551            synchronized (death) {
10552                while (who.isBinderAlive()) {
10553                    try {
10554                        death.wait();
10555                    } catch (InterruptedException e) {
10556                    }
10557                }
10558            }
10559            Watchdog.getInstance().setAllowRestart(true);
10560        }
10561    }
10562
10563    @Override
10564    public void restart() {
10565        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10566                != PackageManager.PERMISSION_GRANTED) {
10567            throw new SecurityException("Requires permission "
10568                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10569        }
10570
10571        Log.i(TAG, "Sending shutdown broadcast...");
10572
10573        BroadcastReceiver br = new BroadcastReceiver() {
10574            @Override public void onReceive(Context context, Intent intent) {
10575                // Now the broadcast is done, finish up the low-level shutdown.
10576                Log.i(TAG, "Shutting down activity manager...");
10577                shutdown(10000);
10578                Log.i(TAG, "Shutdown complete, restarting!");
10579                Process.killProcess(Process.myPid());
10580                System.exit(10);
10581            }
10582        };
10583
10584        // First send the high-level shut down broadcast.
10585        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10586        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10587        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10588        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10589        mContext.sendOrderedBroadcastAsUser(intent,
10590                UserHandle.ALL, null, br, mHandler, 0, null, null);
10591        */
10592        br.onReceive(mContext, intent);
10593    }
10594
10595    private long getLowRamTimeSinceIdle(long now) {
10596        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10597    }
10598
10599    @Override
10600    public void performIdleMaintenance() {
10601        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10602                != PackageManager.PERMISSION_GRANTED) {
10603            throw new SecurityException("Requires permission "
10604                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10605        }
10606
10607        synchronized (this) {
10608            final long now = SystemClock.uptimeMillis();
10609            final long timeSinceLastIdle = now - mLastIdleTime;
10610            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10611            mLastIdleTime = now;
10612            mLowRamTimeSinceLastIdle = 0;
10613            if (mLowRamStartTime != 0) {
10614                mLowRamStartTime = now;
10615            }
10616
10617            StringBuilder sb = new StringBuilder(128);
10618            sb.append("Idle maintenance over ");
10619            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10620            sb.append(" low RAM for ");
10621            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10622            Slog.i(TAG, sb.toString());
10623
10624            // If at least 1/3 of our time since the last idle period has been spent
10625            // with RAM low, then we want to kill processes.
10626            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10627
10628            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10629                ProcessRecord proc = mLruProcesses.get(i);
10630                if (proc.notCachedSinceIdle) {
10631                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10632                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10633                        if (doKilling && proc.initialIdlePss != 0
10634                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10635                            proc.kill("idle maint (pss " + proc.lastPss
10636                                    + " from " + proc.initialIdlePss + ")", true);
10637                        }
10638                    }
10639                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10640                    proc.notCachedSinceIdle = true;
10641                    proc.initialIdlePss = 0;
10642                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10643                            isSleeping(), now);
10644                }
10645            }
10646
10647            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10648            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10649        }
10650    }
10651
10652    private void retrieveSettings() {
10653        final ContentResolver resolver = mContext.getContentResolver();
10654        String debugApp = Settings.Global.getString(
10655            resolver, Settings.Global.DEBUG_APP);
10656        boolean waitForDebugger = Settings.Global.getInt(
10657            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10658        boolean alwaysFinishActivities = Settings.Global.getInt(
10659            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10660        boolean forceRtl = Settings.Global.getInt(
10661                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10662        // Transfer any global setting for forcing RTL layout, into a System Property
10663        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10664
10665        Configuration configuration = new Configuration();
10666        Settings.System.getConfiguration(resolver, configuration);
10667        if (forceRtl) {
10668            // This will take care of setting the correct layout direction flags
10669            configuration.setLayoutDirection(configuration.locale);
10670        }
10671
10672        synchronized (this) {
10673            mDebugApp = mOrigDebugApp = debugApp;
10674            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10675            mAlwaysFinishActivities = alwaysFinishActivities;
10676            // This happens before any activities are started, so we can
10677            // change mConfiguration in-place.
10678            updateConfigurationLocked(configuration, null, false, true);
10679            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10680        }
10681    }
10682
10683    public boolean testIsSystemReady() {
10684        // no need to synchronize(this) just to read & return the value
10685        return mSystemReady;
10686    }
10687
10688    private static File getCalledPreBootReceiversFile() {
10689        File dataDir = Environment.getDataDirectory();
10690        File systemDir = new File(dataDir, "system");
10691        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10692        return fname;
10693    }
10694
10695    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10696        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10697        File file = getCalledPreBootReceiversFile();
10698        FileInputStream fis = null;
10699        try {
10700            fis = new FileInputStream(file);
10701            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10702            int fvers = dis.readInt();
10703            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10704                String vers = dis.readUTF();
10705                String codename = dis.readUTF();
10706                String build = dis.readUTF();
10707                if (android.os.Build.VERSION.RELEASE.equals(vers)
10708                        && android.os.Build.VERSION.CODENAME.equals(codename)
10709                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10710                    int num = dis.readInt();
10711                    while (num > 0) {
10712                        num--;
10713                        String pkg = dis.readUTF();
10714                        String cls = dis.readUTF();
10715                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10716                    }
10717                }
10718            }
10719        } catch (FileNotFoundException e) {
10720        } catch (IOException e) {
10721            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10722        } finally {
10723            if (fis != null) {
10724                try {
10725                    fis.close();
10726                } catch (IOException e) {
10727                }
10728            }
10729        }
10730        return lastDoneReceivers;
10731    }
10732
10733    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10734        File file = getCalledPreBootReceiversFile();
10735        FileOutputStream fos = null;
10736        DataOutputStream dos = null;
10737        try {
10738            fos = new FileOutputStream(file);
10739            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10740            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10741            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10742            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10743            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10744            dos.writeInt(list.size());
10745            for (int i=0; i<list.size(); i++) {
10746                dos.writeUTF(list.get(i).getPackageName());
10747                dos.writeUTF(list.get(i).getClassName());
10748            }
10749        } catch (IOException e) {
10750            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10751            file.delete();
10752        } finally {
10753            FileUtils.sync(fos);
10754            if (dos != null) {
10755                try {
10756                    dos.close();
10757                } catch (IOException e) {
10758                    // TODO Auto-generated catch block
10759                    e.printStackTrace();
10760                }
10761            }
10762        }
10763    }
10764
10765    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10766            ArrayList<ComponentName> doneReceivers, int userId) {
10767        boolean waitingUpdate = false;
10768        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10769        List<ResolveInfo> ris = null;
10770        try {
10771            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10772                    intent, null, 0, userId);
10773        } catch (RemoteException e) {
10774        }
10775        if (ris != null) {
10776            for (int i=ris.size()-1; i>=0; i--) {
10777                if ((ris.get(i).activityInfo.applicationInfo.flags
10778                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10779                    ris.remove(i);
10780                }
10781            }
10782            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10783
10784            // For User 0, load the version number. When delivering to a new user, deliver
10785            // to all receivers.
10786            if (userId == UserHandle.USER_OWNER) {
10787                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10788                for (int i=0; i<ris.size(); i++) {
10789                    ActivityInfo ai = ris.get(i).activityInfo;
10790                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10791                    if (lastDoneReceivers.contains(comp)) {
10792                        // We already did the pre boot receiver for this app with the current
10793                        // platform version, so don't do it again...
10794                        ris.remove(i);
10795                        i--;
10796                        // ...however, do keep it as one that has been done, so we don't
10797                        // forget about it when rewriting the file of last done receivers.
10798                        doneReceivers.add(comp);
10799                    }
10800                }
10801            }
10802
10803            // If primary user, send broadcast to all available users, else just to userId
10804            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10805                    : new int[] { userId };
10806            for (int i = 0; i < ris.size(); i++) {
10807                ActivityInfo ai = ris.get(i).activityInfo;
10808                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10809                doneReceivers.add(comp);
10810                intent.setComponent(comp);
10811                for (int j=0; j<users.length; j++) {
10812                    IIntentReceiver finisher = null;
10813                    // On last receiver and user, set up a completion callback
10814                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10815                        finisher = new IIntentReceiver.Stub() {
10816                            public void performReceive(Intent intent, int resultCode,
10817                                    String data, Bundle extras, boolean ordered,
10818                                    boolean sticky, int sendingUser) {
10819                                // The raw IIntentReceiver interface is called
10820                                // with the AM lock held, so redispatch to
10821                                // execute our code without the lock.
10822                                mHandler.post(onFinishCallback);
10823                            }
10824                        };
10825                    }
10826                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10827                            + " for user " + users[j]);
10828                    broadcastIntentLocked(null, null, intent, null, finisher,
10829                            0, null, null, null, AppOpsManager.OP_NONE,
10830                            true, false, MY_PID, Process.SYSTEM_UID,
10831                            users[j]);
10832                    if (finisher != null) {
10833                        waitingUpdate = true;
10834                    }
10835                }
10836            }
10837        }
10838
10839        return waitingUpdate;
10840    }
10841
10842    public void systemReady(final Runnable goingCallback) {
10843        synchronized(this) {
10844            if (mSystemReady) {
10845                // If we're done calling all the receivers, run the next "boot phase" passed in
10846                // by the SystemServer
10847                if (goingCallback != null) {
10848                    goingCallback.run();
10849                }
10850                return;
10851            }
10852
10853            // Make sure we have the current profile info, since it is needed for
10854            // security checks.
10855            updateCurrentProfileIdsLocked();
10856
10857            if (mRecentTasks == null) {
10858                mRecentTasks = mTaskPersister.restoreTasksLocked();
10859                if (!mRecentTasks.isEmpty()) {
10860                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10861                }
10862                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10863                mTaskPersister.startPersisting();
10864            }
10865
10866            // Check to see if there are any update receivers to run.
10867            if (!mDidUpdate) {
10868                if (mWaitingUpdate) {
10869                    return;
10870                }
10871                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10872                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10873                    public void run() {
10874                        synchronized (ActivityManagerService.this) {
10875                            mDidUpdate = true;
10876                        }
10877                        writeLastDonePreBootReceivers(doneReceivers);
10878                        showBootMessage(mContext.getText(
10879                                R.string.android_upgrading_complete),
10880                                false);
10881                        systemReady(goingCallback);
10882                    }
10883                }, doneReceivers, UserHandle.USER_OWNER);
10884
10885                if (mWaitingUpdate) {
10886                    return;
10887                }
10888                mDidUpdate = true;
10889            }
10890
10891            mAppOpsService.systemReady();
10892            mSystemReady = true;
10893        }
10894
10895        ArrayList<ProcessRecord> procsToKill = null;
10896        synchronized(mPidsSelfLocked) {
10897            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10898                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10899                if (!isAllowedWhileBooting(proc.info)){
10900                    if (procsToKill == null) {
10901                        procsToKill = new ArrayList<ProcessRecord>();
10902                    }
10903                    procsToKill.add(proc);
10904                }
10905            }
10906        }
10907
10908        synchronized(this) {
10909            if (procsToKill != null) {
10910                for (int i=procsToKill.size()-1; i>=0; i--) {
10911                    ProcessRecord proc = procsToKill.get(i);
10912                    Slog.i(TAG, "Removing system update proc: " + proc);
10913                    removeProcessLocked(proc, true, false, "system update done");
10914                }
10915            }
10916
10917            // Now that we have cleaned up any update processes, we
10918            // are ready to start launching real processes and know that
10919            // we won't trample on them any more.
10920            mProcessesReady = true;
10921        }
10922
10923        Slog.i(TAG, "System now ready");
10924        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10925            SystemClock.uptimeMillis());
10926
10927        synchronized(this) {
10928            // Make sure we have no pre-ready processes sitting around.
10929
10930            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10931                ResolveInfo ri = mContext.getPackageManager()
10932                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10933                                STOCK_PM_FLAGS);
10934                CharSequence errorMsg = null;
10935                if (ri != null) {
10936                    ActivityInfo ai = ri.activityInfo;
10937                    ApplicationInfo app = ai.applicationInfo;
10938                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10939                        mTopAction = Intent.ACTION_FACTORY_TEST;
10940                        mTopData = null;
10941                        mTopComponent = new ComponentName(app.packageName,
10942                                ai.name);
10943                    } else {
10944                        errorMsg = mContext.getResources().getText(
10945                                com.android.internal.R.string.factorytest_not_system);
10946                    }
10947                } else {
10948                    errorMsg = mContext.getResources().getText(
10949                            com.android.internal.R.string.factorytest_no_action);
10950                }
10951                if (errorMsg != null) {
10952                    mTopAction = null;
10953                    mTopData = null;
10954                    mTopComponent = null;
10955                    Message msg = Message.obtain();
10956                    msg.what = SHOW_FACTORY_ERROR_MSG;
10957                    msg.getData().putCharSequence("msg", errorMsg);
10958                    mHandler.sendMessage(msg);
10959                }
10960            }
10961        }
10962
10963        retrieveSettings();
10964
10965        synchronized (this) {
10966            readGrantedUriPermissionsLocked();
10967        }
10968
10969        if (goingCallback != null) goingCallback.run();
10970
10971        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10972                Integer.toString(mCurrentUserId), mCurrentUserId);
10973        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10974                Integer.toString(mCurrentUserId), mCurrentUserId);
10975        mSystemServiceManager.startUser(mCurrentUserId);
10976
10977        synchronized (this) {
10978            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10979                try {
10980                    List apps = AppGlobals.getPackageManager().
10981                        getPersistentApplications(STOCK_PM_FLAGS);
10982                    if (apps != null) {
10983                        int N = apps.size();
10984                        int i;
10985                        for (i=0; i<N; i++) {
10986                            ApplicationInfo info
10987                                = (ApplicationInfo)apps.get(i);
10988                            if (info != null &&
10989                                    !info.packageName.equals("android")) {
10990                                addAppLocked(info, false, null /* ABI override */);
10991                            }
10992                        }
10993                    }
10994                } catch (RemoteException ex) {
10995                    // pm is in same process, this will never happen.
10996                }
10997            }
10998
10999            // Start up initial activity.
11000            mBooting = true;
11001
11002            try {
11003                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11004                    Message msg = Message.obtain();
11005                    msg.what = SHOW_UID_ERROR_MSG;
11006                    mHandler.sendMessage(msg);
11007                }
11008            } catch (RemoteException e) {
11009            }
11010
11011            long ident = Binder.clearCallingIdentity();
11012            try {
11013                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11014                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11015                        | Intent.FLAG_RECEIVER_FOREGROUND);
11016                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11017                broadcastIntentLocked(null, null, intent,
11018                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11019                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11020                intent = new Intent(Intent.ACTION_USER_STARTING);
11021                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11022                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11023                broadcastIntentLocked(null, null, intent,
11024                        null, new IIntentReceiver.Stub() {
11025                            @Override
11026                            public void performReceive(Intent intent, int resultCode, String data,
11027                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11028                                    throws RemoteException {
11029                            }
11030                        }, 0, null, null,
11031                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11032                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11033            } catch (Throwable t) {
11034                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11035            } finally {
11036                Binder.restoreCallingIdentity(ident);
11037            }
11038            mStackSupervisor.resumeTopActivitiesLocked();
11039            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11040        }
11041    }
11042
11043    private boolean makeAppCrashingLocked(ProcessRecord app,
11044            String shortMsg, String longMsg, String stackTrace) {
11045        app.crashing = true;
11046        app.crashingReport = generateProcessError(app,
11047                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11048        startAppProblemLocked(app);
11049        app.stopFreezingAllLocked();
11050        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11051    }
11052
11053    private void makeAppNotRespondingLocked(ProcessRecord app,
11054            String activity, String shortMsg, String longMsg) {
11055        app.notResponding = true;
11056        app.notRespondingReport = generateProcessError(app,
11057                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11058                activity, shortMsg, longMsg, null);
11059        startAppProblemLocked(app);
11060        app.stopFreezingAllLocked();
11061    }
11062
11063    /**
11064     * Generate a process error record, suitable for attachment to a ProcessRecord.
11065     *
11066     * @param app The ProcessRecord in which the error occurred.
11067     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11068     *                      ActivityManager.AppErrorStateInfo
11069     * @param activity The activity associated with the crash, if known.
11070     * @param shortMsg Short message describing the crash.
11071     * @param longMsg Long message describing the crash.
11072     * @param stackTrace Full crash stack trace, may be null.
11073     *
11074     * @return Returns a fully-formed AppErrorStateInfo record.
11075     */
11076    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11077            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11078        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11079
11080        report.condition = condition;
11081        report.processName = app.processName;
11082        report.pid = app.pid;
11083        report.uid = app.info.uid;
11084        report.tag = activity;
11085        report.shortMsg = shortMsg;
11086        report.longMsg = longMsg;
11087        report.stackTrace = stackTrace;
11088
11089        return report;
11090    }
11091
11092    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11093        synchronized (this) {
11094            app.crashing = false;
11095            app.crashingReport = null;
11096            app.notResponding = false;
11097            app.notRespondingReport = null;
11098            if (app.anrDialog == fromDialog) {
11099                app.anrDialog = null;
11100            }
11101            if (app.waitDialog == fromDialog) {
11102                app.waitDialog = null;
11103            }
11104            if (app.pid > 0 && app.pid != MY_PID) {
11105                handleAppCrashLocked(app, null, null, null);
11106                app.kill("user request after error", true);
11107            }
11108        }
11109    }
11110
11111    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11112            String stackTrace) {
11113        long now = SystemClock.uptimeMillis();
11114
11115        Long crashTime;
11116        if (!app.isolated) {
11117            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11118        } else {
11119            crashTime = null;
11120        }
11121        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11122            // This process loses!
11123            Slog.w(TAG, "Process " + app.info.processName
11124                    + " has crashed too many times: killing!");
11125            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11126                    app.userId, app.info.processName, app.uid);
11127            mStackSupervisor.handleAppCrashLocked(app);
11128            if (!app.persistent) {
11129                // We don't want to start this process again until the user
11130                // explicitly does so...  but for persistent process, we really
11131                // need to keep it running.  If a persistent process is actually
11132                // repeatedly crashing, then badness for everyone.
11133                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11134                        app.info.processName);
11135                if (!app.isolated) {
11136                    // XXX We don't have a way to mark isolated processes
11137                    // as bad, since they don't have a peristent identity.
11138                    mBadProcesses.put(app.info.processName, app.uid,
11139                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11140                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11141                }
11142                app.bad = true;
11143                app.removed = true;
11144                // Don't let services in this process be restarted and potentially
11145                // annoy the user repeatedly.  Unless it is persistent, since those
11146                // processes run critical code.
11147                removeProcessLocked(app, false, false, "crash");
11148                mStackSupervisor.resumeTopActivitiesLocked();
11149                return false;
11150            }
11151            mStackSupervisor.resumeTopActivitiesLocked();
11152        } else {
11153            mStackSupervisor.finishTopRunningActivityLocked(app);
11154        }
11155
11156        // Bump up the crash count of any services currently running in the proc.
11157        for (int i=app.services.size()-1; i>=0; i--) {
11158            // Any services running in the application need to be placed
11159            // back in the pending list.
11160            ServiceRecord sr = app.services.valueAt(i);
11161            sr.crashCount++;
11162        }
11163
11164        // If the crashing process is what we consider to be the "home process" and it has been
11165        // replaced by a third-party app, clear the package preferred activities from packages
11166        // with a home activity running in the process to prevent a repeatedly crashing app
11167        // from blocking the user to manually clear the list.
11168        final ArrayList<ActivityRecord> activities = app.activities;
11169        if (app == mHomeProcess && activities.size() > 0
11170                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11171            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11172                final ActivityRecord r = activities.get(activityNdx);
11173                if (r.isHomeActivity()) {
11174                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11175                    try {
11176                        ActivityThread.getPackageManager()
11177                                .clearPackagePreferredActivities(r.packageName);
11178                    } catch (RemoteException c) {
11179                        // pm is in same process, this will never happen.
11180                    }
11181                }
11182            }
11183        }
11184
11185        if (!app.isolated) {
11186            // XXX Can't keep track of crash times for isolated processes,
11187            // because they don't have a perisistent identity.
11188            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11189        }
11190
11191        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11192        return true;
11193    }
11194
11195    void startAppProblemLocked(ProcessRecord app) {
11196        // If this app is not running under the current user, then we
11197        // can't give it a report button because that would require
11198        // launching the report UI under a different user.
11199        app.errorReportReceiver = null;
11200
11201        for (int userId : mCurrentProfileIds) {
11202            if (app.userId == userId) {
11203                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11204                        mContext, app.info.packageName, app.info.flags);
11205            }
11206        }
11207        skipCurrentReceiverLocked(app);
11208    }
11209
11210    void skipCurrentReceiverLocked(ProcessRecord app) {
11211        for (BroadcastQueue queue : mBroadcastQueues) {
11212            queue.skipCurrentReceiverLocked(app);
11213        }
11214    }
11215
11216    /**
11217     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11218     * The application process will exit immediately after this call returns.
11219     * @param app object of the crashing app, null for the system server
11220     * @param crashInfo describing the exception
11221     */
11222    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11223        ProcessRecord r = findAppProcess(app, "Crash");
11224        final String processName = app == null ? "system_server"
11225                : (r == null ? "unknown" : r.processName);
11226
11227        handleApplicationCrashInner("crash", r, processName, crashInfo);
11228    }
11229
11230    /* Native crash reporting uses this inner version because it needs to be somewhat
11231     * decoupled from the AM-managed cleanup lifecycle
11232     */
11233    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11234            ApplicationErrorReport.CrashInfo crashInfo) {
11235        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11236                UserHandle.getUserId(Binder.getCallingUid()), processName,
11237                r == null ? -1 : r.info.flags,
11238                crashInfo.exceptionClassName,
11239                crashInfo.exceptionMessage,
11240                crashInfo.throwFileName,
11241                crashInfo.throwLineNumber);
11242
11243        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11244
11245        crashApplication(r, crashInfo);
11246    }
11247
11248    public void handleApplicationStrictModeViolation(
11249            IBinder app,
11250            int violationMask,
11251            StrictMode.ViolationInfo info) {
11252        ProcessRecord r = findAppProcess(app, "StrictMode");
11253        if (r == null) {
11254            return;
11255        }
11256
11257        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11258            Integer stackFingerprint = info.hashCode();
11259            boolean logIt = true;
11260            synchronized (mAlreadyLoggedViolatedStacks) {
11261                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11262                    logIt = false;
11263                    // TODO: sub-sample into EventLog for these, with
11264                    // the info.durationMillis?  Then we'd get
11265                    // the relative pain numbers, without logging all
11266                    // the stack traces repeatedly.  We'd want to do
11267                    // likewise in the client code, which also does
11268                    // dup suppression, before the Binder call.
11269                } else {
11270                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11271                        mAlreadyLoggedViolatedStacks.clear();
11272                    }
11273                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11274                }
11275            }
11276            if (logIt) {
11277                logStrictModeViolationToDropBox(r, info);
11278            }
11279        }
11280
11281        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11282            AppErrorResult result = new AppErrorResult();
11283            synchronized (this) {
11284                final long origId = Binder.clearCallingIdentity();
11285
11286                Message msg = Message.obtain();
11287                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11288                HashMap<String, Object> data = new HashMap<String, Object>();
11289                data.put("result", result);
11290                data.put("app", r);
11291                data.put("violationMask", violationMask);
11292                data.put("info", info);
11293                msg.obj = data;
11294                mHandler.sendMessage(msg);
11295
11296                Binder.restoreCallingIdentity(origId);
11297            }
11298            int res = result.get();
11299            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11300        }
11301    }
11302
11303    // Depending on the policy in effect, there could be a bunch of
11304    // these in quick succession so we try to batch these together to
11305    // minimize disk writes, number of dropbox entries, and maximize
11306    // compression, by having more fewer, larger records.
11307    private void logStrictModeViolationToDropBox(
11308            ProcessRecord process,
11309            StrictMode.ViolationInfo info) {
11310        if (info == null) {
11311            return;
11312        }
11313        final boolean isSystemApp = process == null ||
11314                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11315                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11316        final String processName = process == null ? "unknown" : process.processName;
11317        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11318        final DropBoxManager dbox = (DropBoxManager)
11319                mContext.getSystemService(Context.DROPBOX_SERVICE);
11320
11321        // Exit early if the dropbox isn't configured to accept this report type.
11322        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11323
11324        boolean bufferWasEmpty;
11325        boolean needsFlush;
11326        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11327        synchronized (sb) {
11328            bufferWasEmpty = sb.length() == 0;
11329            appendDropBoxProcessHeaders(process, processName, sb);
11330            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11331            sb.append("System-App: ").append(isSystemApp).append("\n");
11332            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11333            if (info.violationNumThisLoop != 0) {
11334                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11335            }
11336            if (info.numAnimationsRunning != 0) {
11337                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11338            }
11339            if (info.broadcastIntentAction != null) {
11340                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11341            }
11342            if (info.durationMillis != -1) {
11343                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11344            }
11345            if (info.numInstances != -1) {
11346                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11347            }
11348            if (info.tags != null) {
11349                for (String tag : info.tags) {
11350                    sb.append("Span-Tag: ").append(tag).append("\n");
11351                }
11352            }
11353            sb.append("\n");
11354            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11355                sb.append(info.crashInfo.stackTrace);
11356            }
11357            sb.append("\n");
11358
11359            // Only buffer up to ~64k.  Various logging bits truncate
11360            // things at 128k.
11361            needsFlush = (sb.length() > 64 * 1024);
11362        }
11363
11364        // Flush immediately if the buffer's grown too large, or this
11365        // is a non-system app.  Non-system apps are isolated with a
11366        // different tag & policy and not batched.
11367        //
11368        // Batching is useful during internal testing with
11369        // StrictMode settings turned up high.  Without batching,
11370        // thousands of separate files could be created on boot.
11371        if (!isSystemApp || needsFlush) {
11372            new Thread("Error dump: " + dropboxTag) {
11373                @Override
11374                public void run() {
11375                    String report;
11376                    synchronized (sb) {
11377                        report = sb.toString();
11378                        sb.delete(0, sb.length());
11379                        sb.trimToSize();
11380                    }
11381                    if (report.length() != 0) {
11382                        dbox.addText(dropboxTag, report);
11383                    }
11384                }
11385            }.start();
11386            return;
11387        }
11388
11389        // System app batching:
11390        if (!bufferWasEmpty) {
11391            // An existing dropbox-writing thread is outstanding, so
11392            // we don't need to start it up.  The existing thread will
11393            // catch the buffer appends we just did.
11394            return;
11395        }
11396
11397        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11398        // (After this point, we shouldn't access AMS internal data structures.)
11399        new Thread("Error dump: " + dropboxTag) {
11400            @Override
11401            public void run() {
11402                // 5 second sleep to let stacks arrive and be batched together
11403                try {
11404                    Thread.sleep(5000);  // 5 seconds
11405                } catch (InterruptedException e) {}
11406
11407                String errorReport;
11408                synchronized (mStrictModeBuffer) {
11409                    errorReport = mStrictModeBuffer.toString();
11410                    if (errorReport.length() == 0) {
11411                        return;
11412                    }
11413                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11414                    mStrictModeBuffer.trimToSize();
11415                }
11416                dbox.addText(dropboxTag, errorReport);
11417            }
11418        }.start();
11419    }
11420
11421    /**
11422     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11423     * @param app object of the crashing app, null for the system server
11424     * @param tag reported by the caller
11425     * @param system whether this wtf is coming from the system
11426     * @param crashInfo describing the context of the error
11427     * @return true if the process should exit immediately (WTF is fatal)
11428     */
11429    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11430            final ApplicationErrorReport.CrashInfo crashInfo) {
11431        final ProcessRecord r = findAppProcess(app, "WTF");
11432        final String processName = app == null ? "system_server"
11433                : (r == null ? "unknown" : r.processName);
11434
11435        EventLog.writeEvent(EventLogTags.AM_WTF,
11436                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11437                processName,
11438                r == null ? -1 : r.info.flags,
11439                tag, crashInfo.exceptionMessage);
11440
11441        if (system) {
11442            // If this is coming from the system, we could very well have low-level
11443            // system locks held, so we want to do this all asynchronously.  And we
11444            // never want this to become fatal, so there is that too.
11445            mHandler.post(new Runnable() {
11446                @Override public void run() {
11447                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11448                            crashInfo);
11449                }
11450            });
11451            return false;
11452        }
11453
11454        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11455
11456        if (r != null && r.pid != Process.myPid() &&
11457                Settings.Global.getInt(mContext.getContentResolver(),
11458                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11459            crashApplication(r, crashInfo);
11460            return true;
11461        } else {
11462            return false;
11463        }
11464    }
11465
11466    /**
11467     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11468     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11469     */
11470    private ProcessRecord findAppProcess(IBinder app, String reason) {
11471        if (app == null) {
11472            return null;
11473        }
11474
11475        synchronized (this) {
11476            final int NP = mProcessNames.getMap().size();
11477            for (int ip=0; ip<NP; ip++) {
11478                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11479                final int NA = apps.size();
11480                for (int ia=0; ia<NA; ia++) {
11481                    ProcessRecord p = apps.valueAt(ia);
11482                    if (p.thread != null && p.thread.asBinder() == app) {
11483                        return p;
11484                    }
11485                }
11486            }
11487
11488            Slog.w(TAG, "Can't find mystery application for " + reason
11489                    + " from pid=" + Binder.getCallingPid()
11490                    + " uid=" + Binder.getCallingUid() + ": " + app);
11491            return null;
11492        }
11493    }
11494
11495    /**
11496     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11497     * to append various headers to the dropbox log text.
11498     */
11499    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11500            StringBuilder sb) {
11501        // Watchdog thread ends up invoking this function (with
11502        // a null ProcessRecord) to add the stack file to dropbox.
11503        // Do not acquire a lock on this (am) in such cases, as it
11504        // could cause a potential deadlock, if and when watchdog
11505        // is invoked due to unavailability of lock on am and it
11506        // would prevent watchdog from killing system_server.
11507        if (process == null) {
11508            sb.append("Process: ").append(processName).append("\n");
11509            return;
11510        }
11511        // Note: ProcessRecord 'process' is guarded by the service
11512        // instance.  (notably process.pkgList, which could otherwise change
11513        // concurrently during execution of this method)
11514        synchronized (this) {
11515            sb.append("Process: ").append(processName).append("\n");
11516            int flags = process.info.flags;
11517            IPackageManager pm = AppGlobals.getPackageManager();
11518            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11519            for (int ip=0; ip<process.pkgList.size(); ip++) {
11520                String pkg = process.pkgList.keyAt(ip);
11521                sb.append("Package: ").append(pkg);
11522                try {
11523                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11524                    if (pi != null) {
11525                        sb.append(" v").append(pi.versionCode);
11526                        if (pi.versionName != null) {
11527                            sb.append(" (").append(pi.versionName).append(")");
11528                        }
11529                    }
11530                } catch (RemoteException e) {
11531                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11532                }
11533                sb.append("\n");
11534            }
11535        }
11536    }
11537
11538    private static String processClass(ProcessRecord process) {
11539        if (process == null || process.pid == MY_PID) {
11540            return "system_server";
11541        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11542            return "system_app";
11543        } else {
11544            return "data_app";
11545        }
11546    }
11547
11548    /**
11549     * Write a description of an error (crash, WTF, ANR) to the drop box.
11550     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11551     * @param process which caused the error, null means the system server
11552     * @param activity which triggered the error, null if unknown
11553     * @param parent activity related to the error, null if unknown
11554     * @param subject line related to the error, null if absent
11555     * @param report in long form describing the error, null if absent
11556     * @param logFile to include in the report, null if none
11557     * @param crashInfo giving an application stack trace, null if absent
11558     */
11559    public void addErrorToDropBox(String eventType,
11560            ProcessRecord process, String processName, ActivityRecord activity,
11561            ActivityRecord parent, String subject,
11562            final String report, final File logFile,
11563            final ApplicationErrorReport.CrashInfo crashInfo) {
11564        // NOTE -- this must never acquire the ActivityManagerService lock,
11565        // otherwise the watchdog may be prevented from resetting the system.
11566
11567        final String dropboxTag = processClass(process) + "_" + eventType;
11568        final DropBoxManager dbox = (DropBoxManager)
11569                mContext.getSystemService(Context.DROPBOX_SERVICE);
11570
11571        // Exit early if the dropbox isn't configured to accept this report type.
11572        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11573
11574        final StringBuilder sb = new StringBuilder(1024);
11575        appendDropBoxProcessHeaders(process, processName, sb);
11576        if (activity != null) {
11577            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11578        }
11579        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11580            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11581        }
11582        if (parent != null && parent != activity) {
11583            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11584        }
11585        if (subject != null) {
11586            sb.append("Subject: ").append(subject).append("\n");
11587        }
11588        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11589        if (Debug.isDebuggerConnected()) {
11590            sb.append("Debugger: Connected\n");
11591        }
11592        sb.append("\n");
11593
11594        // Do the rest in a worker thread to avoid blocking the caller on I/O
11595        // (After this point, we shouldn't access AMS internal data structures.)
11596        Thread worker = new Thread("Error dump: " + dropboxTag) {
11597            @Override
11598            public void run() {
11599                if (report != null) {
11600                    sb.append(report);
11601                }
11602                if (logFile != null) {
11603                    try {
11604                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11605                                    "\n\n[[TRUNCATED]]"));
11606                    } catch (IOException e) {
11607                        Slog.e(TAG, "Error reading " + logFile, e);
11608                    }
11609                }
11610                if (crashInfo != null && crashInfo.stackTrace != null) {
11611                    sb.append(crashInfo.stackTrace);
11612                }
11613
11614                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11615                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11616                if (lines > 0) {
11617                    sb.append("\n");
11618
11619                    // Merge several logcat streams, and take the last N lines
11620                    InputStreamReader input = null;
11621                    try {
11622                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11623                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11624                                "-b", "crash",
11625                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11626
11627                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11628                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11629                        input = new InputStreamReader(logcat.getInputStream());
11630
11631                        int num;
11632                        char[] buf = new char[8192];
11633                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11634                    } catch (IOException e) {
11635                        Slog.e(TAG, "Error running logcat", e);
11636                    } finally {
11637                        if (input != null) try { input.close(); } catch (IOException e) {}
11638                    }
11639                }
11640
11641                dbox.addText(dropboxTag, sb.toString());
11642            }
11643        };
11644
11645        if (process == null) {
11646            // If process is null, we are being called from some internal code
11647            // and may be about to die -- run this synchronously.
11648            worker.run();
11649        } else {
11650            worker.start();
11651        }
11652    }
11653
11654    /**
11655     * Bring up the "unexpected error" dialog box for a crashing app.
11656     * Deal with edge cases (intercepts from instrumented applications,
11657     * ActivityController, error intent receivers, that sort of thing).
11658     * @param r the application crashing
11659     * @param crashInfo describing the failure
11660     */
11661    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11662        long timeMillis = System.currentTimeMillis();
11663        String shortMsg = crashInfo.exceptionClassName;
11664        String longMsg = crashInfo.exceptionMessage;
11665        String stackTrace = crashInfo.stackTrace;
11666        if (shortMsg != null && longMsg != null) {
11667            longMsg = shortMsg + ": " + longMsg;
11668        } else if (shortMsg != null) {
11669            longMsg = shortMsg;
11670        }
11671
11672        AppErrorResult result = new AppErrorResult();
11673        synchronized (this) {
11674            if (mController != null) {
11675                try {
11676                    String name = r != null ? r.processName : null;
11677                    int pid = r != null ? r.pid : Binder.getCallingPid();
11678                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11679                    if (!mController.appCrashed(name, pid,
11680                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11681                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11682                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11683                            Slog.w(TAG, "Skip killing native crashed app " + name
11684                                    + "(" + pid + ") during testing");
11685                        } else {
11686                            Slog.w(TAG, "Force-killing crashed app " + name
11687                                    + " at watcher's request");
11688                            if (r != null) {
11689                                r.kill("crash", true);
11690                            } else {
11691                                // Huh.
11692                                Process.killProcess(pid);
11693                                Process.killProcessGroup(uid, pid);
11694                            }
11695                        }
11696                        return;
11697                    }
11698                } catch (RemoteException e) {
11699                    mController = null;
11700                    Watchdog.getInstance().setActivityController(null);
11701                }
11702            }
11703
11704            final long origId = Binder.clearCallingIdentity();
11705
11706            // If this process is running instrumentation, finish it.
11707            if (r != null && r.instrumentationClass != null) {
11708                Slog.w(TAG, "Error in app " + r.processName
11709                      + " running instrumentation " + r.instrumentationClass + ":");
11710                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11711                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11712                Bundle info = new Bundle();
11713                info.putString("shortMsg", shortMsg);
11714                info.putString("longMsg", longMsg);
11715                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11716                Binder.restoreCallingIdentity(origId);
11717                return;
11718            }
11719
11720            // If we can't identify the process or it's already exceeded its crash quota,
11721            // quit right away without showing a crash dialog.
11722            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11723                Binder.restoreCallingIdentity(origId);
11724                return;
11725            }
11726
11727            Message msg = Message.obtain();
11728            msg.what = SHOW_ERROR_MSG;
11729            HashMap data = new HashMap();
11730            data.put("result", result);
11731            data.put("app", r);
11732            msg.obj = data;
11733            mHandler.sendMessage(msg);
11734
11735            Binder.restoreCallingIdentity(origId);
11736        }
11737
11738        int res = result.get();
11739
11740        Intent appErrorIntent = null;
11741        synchronized (this) {
11742            if (r != null && !r.isolated) {
11743                // XXX Can't keep track of crash time for isolated processes,
11744                // since they don't have a persistent identity.
11745                mProcessCrashTimes.put(r.info.processName, r.uid,
11746                        SystemClock.uptimeMillis());
11747            }
11748            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11749                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11750            }
11751        }
11752
11753        if (appErrorIntent != null) {
11754            try {
11755                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11756            } catch (ActivityNotFoundException e) {
11757                Slog.w(TAG, "bug report receiver dissappeared", e);
11758            }
11759        }
11760    }
11761
11762    Intent createAppErrorIntentLocked(ProcessRecord r,
11763            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11764        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11765        if (report == null) {
11766            return null;
11767        }
11768        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11769        result.setComponent(r.errorReportReceiver);
11770        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11771        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11772        return result;
11773    }
11774
11775    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11776            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11777        if (r.errorReportReceiver == null) {
11778            return null;
11779        }
11780
11781        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11782            return null;
11783        }
11784
11785        ApplicationErrorReport report = new ApplicationErrorReport();
11786        report.packageName = r.info.packageName;
11787        report.installerPackageName = r.errorReportReceiver.getPackageName();
11788        report.processName = r.processName;
11789        report.time = timeMillis;
11790        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11791
11792        if (r.crashing || r.forceCrashReport) {
11793            report.type = ApplicationErrorReport.TYPE_CRASH;
11794            report.crashInfo = crashInfo;
11795        } else if (r.notResponding) {
11796            report.type = ApplicationErrorReport.TYPE_ANR;
11797            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11798
11799            report.anrInfo.activity = r.notRespondingReport.tag;
11800            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11801            report.anrInfo.info = r.notRespondingReport.longMsg;
11802        }
11803
11804        return report;
11805    }
11806
11807    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11808        enforceNotIsolatedCaller("getProcessesInErrorState");
11809        // assume our apps are happy - lazy create the list
11810        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11811
11812        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11813                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11814        int userId = UserHandle.getUserId(Binder.getCallingUid());
11815
11816        synchronized (this) {
11817
11818            // iterate across all processes
11819            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11820                ProcessRecord app = mLruProcesses.get(i);
11821                if (!allUsers && app.userId != userId) {
11822                    continue;
11823                }
11824                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11825                    // This one's in trouble, so we'll generate a report for it
11826                    // crashes are higher priority (in case there's a crash *and* an anr)
11827                    ActivityManager.ProcessErrorStateInfo report = null;
11828                    if (app.crashing) {
11829                        report = app.crashingReport;
11830                    } else if (app.notResponding) {
11831                        report = app.notRespondingReport;
11832                    }
11833
11834                    if (report != null) {
11835                        if (errList == null) {
11836                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11837                        }
11838                        errList.add(report);
11839                    } else {
11840                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11841                                " crashing = " + app.crashing +
11842                                " notResponding = " + app.notResponding);
11843                    }
11844                }
11845            }
11846        }
11847
11848        return errList;
11849    }
11850
11851    static int procStateToImportance(int procState, int memAdj,
11852            ActivityManager.RunningAppProcessInfo currApp) {
11853        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11854        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11855            currApp.lru = memAdj;
11856        } else {
11857            currApp.lru = 0;
11858        }
11859        return imp;
11860    }
11861
11862    private void fillInProcMemInfo(ProcessRecord app,
11863            ActivityManager.RunningAppProcessInfo outInfo) {
11864        outInfo.pid = app.pid;
11865        outInfo.uid = app.info.uid;
11866        if (mHeavyWeightProcess == app) {
11867            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11868        }
11869        if (app.persistent) {
11870            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11871        }
11872        if (app.activities.size() > 0) {
11873            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11874        }
11875        outInfo.lastTrimLevel = app.trimMemoryLevel;
11876        int adj = app.curAdj;
11877        int procState = app.curProcState;
11878        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11879        outInfo.importanceReasonCode = app.adjTypeCode;
11880        outInfo.processState = app.curProcState;
11881    }
11882
11883    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11884        enforceNotIsolatedCaller("getRunningAppProcesses");
11885        // Lazy instantiation of list
11886        List<ActivityManager.RunningAppProcessInfo> runList = null;
11887        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11888                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11889        int userId = UserHandle.getUserId(Binder.getCallingUid());
11890        synchronized (this) {
11891            // Iterate across all processes
11892            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11893                ProcessRecord app = mLruProcesses.get(i);
11894                if (!allUsers && app.userId != userId) {
11895                    continue;
11896                }
11897                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11898                    // Generate process state info for running application
11899                    ActivityManager.RunningAppProcessInfo currApp =
11900                        new ActivityManager.RunningAppProcessInfo(app.processName,
11901                                app.pid, app.getPackageList());
11902                    fillInProcMemInfo(app, currApp);
11903                    if (app.adjSource instanceof ProcessRecord) {
11904                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11905                        currApp.importanceReasonImportance =
11906                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11907                                        app.adjSourceProcState);
11908                    } else if (app.adjSource instanceof ActivityRecord) {
11909                        ActivityRecord r = (ActivityRecord)app.adjSource;
11910                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11911                    }
11912                    if (app.adjTarget instanceof ComponentName) {
11913                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11914                    }
11915                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11916                    //        + " lru=" + currApp.lru);
11917                    if (runList == null) {
11918                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11919                    }
11920                    runList.add(currApp);
11921                }
11922            }
11923        }
11924        return runList;
11925    }
11926
11927    public List<ApplicationInfo> getRunningExternalApplications() {
11928        enforceNotIsolatedCaller("getRunningExternalApplications");
11929        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11930        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11931        if (runningApps != null && runningApps.size() > 0) {
11932            Set<String> extList = new HashSet<String>();
11933            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11934                if (app.pkgList != null) {
11935                    for (String pkg : app.pkgList) {
11936                        extList.add(pkg);
11937                    }
11938                }
11939            }
11940            IPackageManager pm = AppGlobals.getPackageManager();
11941            for (String pkg : extList) {
11942                try {
11943                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11944                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11945                        retList.add(info);
11946                    }
11947                } catch (RemoteException e) {
11948                }
11949            }
11950        }
11951        return retList;
11952    }
11953
11954    @Override
11955    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11956        enforceNotIsolatedCaller("getMyMemoryState");
11957        synchronized (this) {
11958            ProcessRecord proc;
11959            synchronized (mPidsSelfLocked) {
11960                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11961            }
11962            fillInProcMemInfo(proc, outInfo);
11963        }
11964    }
11965
11966    @Override
11967    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11968        if (checkCallingPermission(android.Manifest.permission.DUMP)
11969                != PackageManager.PERMISSION_GRANTED) {
11970            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11971                    + Binder.getCallingPid()
11972                    + ", uid=" + Binder.getCallingUid()
11973                    + " without permission "
11974                    + android.Manifest.permission.DUMP);
11975            return;
11976        }
11977
11978        boolean dumpAll = false;
11979        boolean dumpClient = false;
11980        String dumpPackage = null;
11981
11982        int opti = 0;
11983        while (opti < args.length) {
11984            String opt = args[opti];
11985            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11986                break;
11987            }
11988            opti++;
11989            if ("-a".equals(opt)) {
11990                dumpAll = true;
11991            } else if ("-c".equals(opt)) {
11992                dumpClient = true;
11993            } else if ("-h".equals(opt)) {
11994                pw.println("Activity manager dump options:");
11995                pw.println("  [-a] [-c] [-h] [cmd] ...");
11996                pw.println("  cmd may be one of:");
11997                pw.println("    a[ctivities]: activity stack state");
11998                pw.println("    r[recents]: recent activities state");
11999                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12000                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12001                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12002                pw.println("    o[om]: out of memory management");
12003                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12004                pw.println("    provider [COMP_SPEC]: provider client-side state");
12005                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12006                pw.println("    service [COMP_SPEC]: service client-side state");
12007                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12008                pw.println("    all: dump all activities");
12009                pw.println("    top: dump the top activity");
12010                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12011                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12012                pw.println("    a partial substring in a component name, a");
12013                pw.println("    hex object identifier.");
12014                pw.println("  -a: include all available server state.");
12015                pw.println("  -c: include client state.");
12016                return;
12017            } else {
12018                pw.println("Unknown argument: " + opt + "; use -h for help");
12019            }
12020        }
12021
12022        long origId = Binder.clearCallingIdentity();
12023        boolean more = false;
12024        // Is the caller requesting to dump a particular piece of data?
12025        if (opti < args.length) {
12026            String cmd = args[opti];
12027            opti++;
12028            if ("activities".equals(cmd) || "a".equals(cmd)) {
12029                synchronized (this) {
12030                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12031                }
12032            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12033                synchronized (this) {
12034                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12035                }
12036            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12037                String[] newArgs;
12038                String name;
12039                if (opti >= args.length) {
12040                    name = null;
12041                    newArgs = EMPTY_STRING_ARRAY;
12042                } else {
12043                    name = args[opti];
12044                    opti++;
12045                    newArgs = new String[args.length - opti];
12046                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12047                            args.length - opti);
12048                }
12049                synchronized (this) {
12050                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12051                }
12052            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12053                String[] newArgs;
12054                String name;
12055                if (opti >= args.length) {
12056                    name = null;
12057                    newArgs = EMPTY_STRING_ARRAY;
12058                } else {
12059                    name = args[opti];
12060                    opti++;
12061                    newArgs = new String[args.length - opti];
12062                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12063                            args.length - opti);
12064                }
12065                synchronized (this) {
12066                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12067                }
12068            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12069                String[] newArgs;
12070                String name;
12071                if (opti >= args.length) {
12072                    name = null;
12073                    newArgs = EMPTY_STRING_ARRAY;
12074                } else {
12075                    name = args[opti];
12076                    opti++;
12077                    newArgs = new String[args.length - opti];
12078                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12079                            args.length - opti);
12080                }
12081                synchronized (this) {
12082                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12083                }
12084            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12085                synchronized (this) {
12086                    dumpOomLocked(fd, pw, args, opti, true);
12087                }
12088            } else if ("provider".equals(cmd)) {
12089                String[] newArgs;
12090                String name;
12091                if (opti >= args.length) {
12092                    name = null;
12093                    newArgs = EMPTY_STRING_ARRAY;
12094                } else {
12095                    name = args[opti];
12096                    opti++;
12097                    newArgs = new String[args.length - opti];
12098                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12099                }
12100                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12101                    pw.println("No providers match: " + name);
12102                    pw.println("Use -h for help.");
12103                }
12104            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12105                synchronized (this) {
12106                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12107                }
12108            } else if ("service".equals(cmd)) {
12109                String[] newArgs;
12110                String name;
12111                if (opti >= args.length) {
12112                    name = null;
12113                    newArgs = EMPTY_STRING_ARRAY;
12114                } else {
12115                    name = args[opti];
12116                    opti++;
12117                    newArgs = new String[args.length - opti];
12118                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12119                            args.length - opti);
12120                }
12121                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12122                    pw.println("No services match: " + name);
12123                    pw.println("Use -h for help.");
12124                }
12125            } else if ("package".equals(cmd)) {
12126                String[] newArgs;
12127                if (opti >= args.length) {
12128                    pw.println("package: no package name specified");
12129                    pw.println("Use -h for help.");
12130                } else {
12131                    dumpPackage = args[opti];
12132                    opti++;
12133                    newArgs = new String[args.length - opti];
12134                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12135                            args.length - opti);
12136                    args = newArgs;
12137                    opti = 0;
12138                    more = true;
12139                }
12140            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12141                synchronized (this) {
12142                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12143                }
12144            } else {
12145                // Dumping a single activity?
12146                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12147                    pw.println("Bad activity command, or no activities match: " + cmd);
12148                    pw.println("Use -h for help.");
12149                }
12150            }
12151            if (!more) {
12152                Binder.restoreCallingIdentity(origId);
12153                return;
12154            }
12155        }
12156
12157        // No piece of data specified, dump everything.
12158        synchronized (this) {
12159            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12160            pw.println();
12161            if (dumpAll) {
12162                pw.println("-------------------------------------------------------------------------------");
12163            }
12164            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12165            pw.println();
12166            if (dumpAll) {
12167                pw.println("-------------------------------------------------------------------------------");
12168            }
12169            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12170            pw.println();
12171            if (dumpAll) {
12172                pw.println("-------------------------------------------------------------------------------");
12173            }
12174            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12175            pw.println();
12176            if (dumpAll) {
12177                pw.println("-------------------------------------------------------------------------------");
12178            }
12179            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12180            pw.println();
12181            if (dumpAll) {
12182                pw.println("-------------------------------------------------------------------------------");
12183            }
12184            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12185            pw.println();
12186            if (dumpAll) {
12187                pw.println("-------------------------------------------------------------------------------");
12188            }
12189            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12190        }
12191        Binder.restoreCallingIdentity(origId);
12192    }
12193
12194    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12195            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12196        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12197
12198        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12199                dumpPackage);
12200        boolean needSep = printedAnything;
12201
12202        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12203                dumpPackage, needSep, "  mFocusedActivity: ");
12204        if (printed) {
12205            printedAnything = true;
12206            needSep = false;
12207        }
12208
12209        if (dumpPackage == null) {
12210            if (needSep) {
12211                pw.println();
12212            }
12213            needSep = true;
12214            printedAnything = true;
12215            mStackSupervisor.dump(pw, "  ");
12216        }
12217
12218        if (!printedAnything) {
12219            pw.println("  (nothing)");
12220        }
12221    }
12222
12223    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12224            int opti, boolean dumpAll, String dumpPackage) {
12225        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12226
12227        boolean printedAnything = false;
12228
12229        if (mRecentTasks.size() > 0) {
12230            boolean printedHeader = false;
12231
12232            final int N = mRecentTasks.size();
12233            for (int i=0; i<N; i++) {
12234                TaskRecord tr = mRecentTasks.get(i);
12235                if (dumpPackage != null) {
12236                    if (tr.realActivity == null ||
12237                            !dumpPackage.equals(tr.realActivity)) {
12238                        continue;
12239                    }
12240                }
12241                if (!printedHeader) {
12242                    pw.println("  Recent tasks:");
12243                    printedHeader = true;
12244                    printedAnything = true;
12245                }
12246                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12247                        pw.println(tr);
12248                if (dumpAll) {
12249                    mRecentTasks.get(i).dump(pw, "    ");
12250                }
12251            }
12252        }
12253
12254        if (!printedAnything) {
12255            pw.println("  (nothing)");
12256        }
12257    }
12258
12259    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12260            int opti, boolean dumpAll, String dumpPackage) {
12261        boolean needSep = false;
12262        boolean printedAnything = false;
12263        int numPers = 0;
12264
12265        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12266
12267        if (dumpAll) {
12268            final int NP = mProcessNames.getMap().size();
12269            for (int ip=0; ip<NP; ip++) {
12270                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12271                final int NA = procs.size();
12272                for (int ia=0; ia<NA; ia++) {
12273                    ProcessRecord r = procs.valueAt(ia);
12274                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12275                        continue;
12276                    }
12277                    if (!needSep) {
12278                        pw.println("  All known processes:");
12279                        needSep = true;
12280                        printedAnything = true;
12281                    }
12282                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12283                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12284                        pw.print(" "); pw.println(r);
12285                    r.dump(pw, "    ");
12286                    if (r.persistent) {
12287                        numPers++;
12288                    }
12289                }
12290            }
12291        }
12292
12293        if (mIsolatedProcesses.size() > 0) {
12294            boolean printed = false;
12295            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12296                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12297                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12298                    continue;
12299                }
12300                if (!printed) {
12301                    if (needSep) {
12302                        pw.println();
12303                    }
12304                    pw.println("  Isolated process list (sorted by uid):");
12305                    printedAnything = true;
12306                    printed = true;
12307                    needSep = true;
12308                }
12309                pw.println(String.format("%sIsolated #%2d: %s",
12310                        "    ", i, r.toString()));
12311            }
12312        }
12313
12314        if (mLruProcesses.size() > 0) {
12315            if (needSep) {
12316                pw.println();
12317            }
12318            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12319                    pw.print(" total, non-act at ");
12320                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12321                    pw.print(", non-svc at ");
12322                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12323                    pw.println("):");
12324            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12325            needSep = true;
12326            printedAnything = true;
12327        }
12328
12329        if (dumpAll || dumpPackage != null) {
12330            synchronized (mPidsSelfLocked) {
12331                boolean printed = false;
12332                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12333                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12334                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12335                        continue;
12336                    }
12337                    if (!printed) {
12338                        if (needSep) pw.println();
12339                        needSep = true;
12340                        pw.println("  PID mappings:");
12341                        printed = true;
12342                        printedAnything = true;
12343                    }
12344                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12345                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12346                }
12347            }
12348        }
12349
12350        if (mForegroundProcesses.size() > 0) {
12351            synchronized (mPidsSelfLocked) {
12352                boolean printed = false;
12353                for (int i=0; i<mForegroundProcesses.size(); i++) {
12354                    ProcessRecord r = mPidsSelfLocked.get(
12355                            mForegroundProcesses.valueAt(i).pid);
12356                    if (dumpPackage != null && (r == null
12357                            || !r.pkgList.containsKey(dumpPackage))) {
12358                        continue;
12359                    }
12360                    if (!printed) {
12361                        if (needSep) pw.println();
12362                        needSep = true;
12363                        pw.println("  Foreground Processes:");
12364                        printed = true;
12365                        printedAnything = true;
12366                    }
12367                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12368                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12369                }
12370            }
12371        }
12372
12373        if (mPersistentStartingProcesses.size() > 0) {
12374            if (needSep) pw.println();
12375            needSep = true;
12376            printedAnything = true;
12377            pw.println("  Persisent processes that are starting:");
12378            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12379                    "Starting Norm", "Restarting PERS", dumpPackage);
12380        }
12381
12382        if (mRemovedProcesses.size() > 0) {
12383            if (needSep) pw.println();
12384            needSep = true;
12385            printedAnything = true;
12386            pw.println("  Processes that are being removed:");
12387            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12388                    "Removed Norm", "Removed PERS", dumpPackage);
12389        }
12390
12391        if (mProcessesOnHold.size() > 0) {
12392            if (needSep) pw.println();
12393            needSep = true;
12394            printedAnything = true;
12395            pw.println("  Processes that are on old until the system is ready:");
12396            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12397                    "OnHold Norm", "OnHold PERS", dumpPackage);
12398        }
12399
12400        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12401
12402        if (mProcessCrashTimes.getMap().size() > 0) {
12403            boolean printed = false;
12404            long now = SystemClock.uptimeMillis();
12405            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12406            final int NP = pmap.size();
12407            for (int ip=0; ip<NP; ip++) {
12408                String pname = pmap.keyAt(ip);
12409                SparseArray<Long> uids = pmap.valueAt(ip);
12410                final int N = uids.size();
12411                for (int i=0; i<N; i++) {
12412                    int puid = uids.keyAt(i);
12413                    ProcessRecord r = mProcessNames.get(pname, puid);
12414                    if (dumpPackage != null && (r == null
12415                            || !r.pkgList.containsKey(dumpPackage))) {
12416                        continue;
12417                    }
12418                    if (!printed) {
12419                        if (needSep) pw.println();
12420                        needSep = true;
12421                        pw.println("  Time since processes crashed:");
12422                        printed = true;
12423                        printedAnything = true;
12424                    }
12425                    pw.print("    Process "); pw.print(pname);
12426                            pw.print(" uid "); pw.print(puid);
12427                            pw.print(": last crashed ");
12428                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12429                            pw.println(" ago");
12430                }
12431            }
12432        }
12433
12434        if (mBadProcesses.getMap().size() > 0) {
12435            boolean printed = false;
12436            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12437            final int NP = pmap.size();
12438            for (int ip=0; ip<NP; ip++) {
12439                String pname = pmap.keyAt(ip);
12440                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12441                final int N = uids.size();
12442                for (int i=0; i<N; i++) {
12443                    int puid = uids.keyAt(i);
12444                    ProcessRecord r = mProcessNames.get(pname, puid);
12445                    if (dumpPackage != null && (r == null
12446                            || !r.pkgList.containsKey(dumpPackage))) {
12447                        continue;
12448                    }
12449                    if (!printed) {
12450                        if (needSep) pw.println();
12451                        needSep = true;
12452                        pw.println("  Bad processes:");
12453                        printedAnything = true;
12454                    }
12455                    BadProcessInfo info = uids.valueAt(i);
12456                    pw.print("    Bad process "); pw.print(pname);
12457                            pw.print(" uid "); pw.print(puid);
12458                            pw.print(": crashed at time "); pw.println(info.time);
12459                    if (info.shortMsg != null) {
12460                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12461                    }
12462                    if (info.longMsg != null) {
12463                        pw.print("      Long msg: "); pw.println(info.longMsg);
12464                    }
12465                    if (info.stack != null) {
12466                        pw.println("      Stack:");
12467                        int lastPos = 0;
12468                        for (int pos=0; pos<info.stack.length(); pos++) {
12469                            if (info.stack.charAt(pos) == '\n') {
12470                                pw.print("        ");
12471                                pw.write(info.stack, lastPos, pos-lastPos);
12472                                pw.println();
12473                                lastPos = pos+1;
12474                            }
12475                        }
12476                        if (lastPos < info.stack.length()) {
12477                            pw.print("        ");
12478                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12479                            pw.println();
12480                        }
12481                    }
12482                }
12483            }
12484        }
12485
12486        if (dumpPackage == null) {
12487            pw.println();
12488            needSep = false;
12489            pw.println("  mStartedUsers:");
12490            for (int i=0; i<mStartedUsers.size(); i++) {
12491                UserStartedState uss = mStartedUsers.valueAt(i);
12492                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12493                        pw.print(": "); uss.dump("", pw);
12494            }
12495            pw.print("  mStartedUserArray: [");
12496            for (int i=0; i<mStartedUserArray.length; i++) {
12497                if (i > 0) pw.print(", ");
12498                pw.print(mStartedUserArray[i]);
12499            }
12500            pw.println("]");
12501            pw.print("  mUserLru: [");
12502            for (int i=0; i<mUserLru.size(); i++) {
12503                if (i > 0) pw.print(", ");
12504                pw.print(mUserLru.get(i));
12505            }
12506            pw.println("]");
12507            if (dumpAll) {
12508                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12509            }
12510            synchronized (mUserProfileGroupIdsSelfLocked) {
12511                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12512                    pw.println("  mUserProfileGroupIds:");
12513                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12514                        pw.print("    User #");
12515                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12516                        pw.print(" -> profile #");
12517                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12518                    }
12519                }
12520            }
12521        }
12522        if (mHomeProcess != null && (dumpPackage == null
12523                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12524            if (needSep) {
12525                pw.println();
12526                needSep = false;
12527            }
12528            pw.println("  mHomeProcess: " + mHomeProcess);
12529        }
12530        if (mPreviousProcess != null && (dumpPackage == null
12531                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12532            if (needSep) {
12533                pw.println();
12534                needSep = false;
12535            }
12536            pw.println("  mPreviousProcess: " + mPreviousProcess);
12537        }
12538        if (dumpAll) {
12539            StringBuilder sb = new StringBuilder(128);
12540            sb.append("  mPreviousProcessVisibleTime: ");
12541            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12542            pw.println(sb);
12543        }
12544        if (mHeavyWeightProcess != null && (dumpPackage == null
12545                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12546            if (needSep) {
12547                pw.println();
12548                needSep = false;
12549            }
12550            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12551        }
12552        if (dumpPackage == null) {
12553            pw.println("  mConfiguration: " + mConfiguration);
12554        }
12555        if (dumpAll) {
12556            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12557            if (mCompatModePackages.getPackages().size() > 0) {
12558                boolean printed = false;
12559                for (Map.Entry<String, Integer> entry
12560                        : mCompatModePackages.getPackages().entrySet()) {
12561                    String pkg = entry.getKey();
12562                    int mode = entry.getValue();
12563                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12564                        continue;
12565                    }
12566                    if (!printed) {
12567                        pw.println("  mScreenCompatPackages:");
12568                        printed = true;
12569                    }
12570                    pw.print("    "); pw.print(pkg); pw.print(": ");
12571                            pw.print(mode); pw.println();
12572                }
12573            }
12574        }
12575        if (dumpPackage == null) {
12576            if (mSleeping || mWentToSleep || mLockScreenShown) {
12577                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12578                        + " mLockScreenShown " + mLockScreenShown);
12579            }
12580            if (mShuttingDown || mRunningVoice) {
12581                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12582            }
12583        }
12584        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12585                || mOrigWaitForDebugger) {
12586            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12587                    || dumpPackage.equals(mOrigDebugApp)) {
12588                if (needSep) {
12589                    pw.println();
12590                    needSep = false;
12591                }
12592                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12593                        + " mDebugTransient=" + mDebugTransient
12594                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12595            }
12596        }
12597        if (mOpenGlTraceApp != null) {
12598            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12599                if (needSep) {
12600                    pw.println();
12601                    needSep = false;
12602                }
12603                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12604            }
12605        }
12606        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12607                || mProfileFd != null) {
12608            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12609                if (needSep) {
12610                    pw.println();
12611                    needSep = false;
12612                }
12613                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12614                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12615                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12616                        + mAutoStopProfiler);
12617                pw.println("  mProfileType=" + mProfileType);
12618            }
12619        }
12620        if (dumpPackage == null) {
12621            if (mAlwaysFinishActivities || mController != null) {
12622                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12623                        + " mController=" + mController);
12624            }
12625            if (dumpAll) {
12626                pw.println("  Total persistent processes: " + numPers);
12627                pw.println("  mProcessesReady=" + mProcessesReady
12628                        + " mSystemReady=" + mSystemReady);
12629                pw.println("  mBooting=" + mBooting
12630                        + " mBooted=" + mBooted
12631                        + " mFactoryTest=" + mFactoryTest);
12632                pw.print("  mLastPowerCheckRealtime=");
12633                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12634                        pw.println("");
12635                pw.print("  mLastPowerCheckUptime=");
12636                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12637                        pw.println("");
12638                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12639                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12640                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12641                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12642                        + " (" + mLruProcesses.size() + " total)"
12643                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12644                        + " mNumServiceProcs=" + mNumServiceProcs
12645                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12646                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12647                        + " mLastMemoryLevel" + mLastMemoryLevel
12648                        + " mLastNumProcesses" + mLastNumProcesses);
12649                long now = SystemClock.uptimeMillis();
12650                pw.print("  mLastIdleTime=");
12651                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12652                        pw.print(" mLowRamSinceLastIdle=");
12653                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12654                        pw.println();
12655            }
12656        }
12657
12658        if (!printedAnything) {
12659            pw.println("  (nothing)");
12660        }
12661    }
12662
12663    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12664            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12665        if (mProcessesToGc.size() > 0) {
12666            boolean printed = false;
12667            long now = SystemClock.uptimeMillis();
12668            for (int i=0; i<mProcessesToGc.size(); i++) {
12669                ProcessRecord proc = mProcessesToGc.get(i);
12670                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12671                    continue;
12672                }
12673                if (!printed) {
12674                    if (needSep) pw.println();
12675                    needSep = true;
12676                    pw.println("  Processes that are waiting to GC:");
12677                    printed = true;
12678                }
12679                pw.print("    Process "); pw.println(proc);
12680                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12681                        pw.print(", last gced=");
12682                        pw.print(now-proc.lastRequestedGc);
12683                        pw.print(" ms ago, last lowMem=");
12684                        pw.print(now-proc.lastLowMemory);
12685                        pw.println(" ms ago");
12686
12687            }
12688        }
12689        return needSep;
12690    }
12691
12692    void printOomLevel(PrintWriter pw, String name, int adj) {
12693        pw.print("    ");
12694        if (adj >= 0) {
12695            pw.print(' ');
12696            if (adj < 10) pw.print(' ');
12697        } else {
12698            if (adj > -10) pw.print(' ');
12699        }
12700        pw.print(adj);
12701        pw.print(": ");
12702        pw.print(name);
12703        pw.print(" (");
12704        pw.print(mProcessList.getMemLevel(adj)/1024);
12705        pw.println(" kB)");
12706    }
12707
12708    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12709            int opti, boolean dumpAll) {
12710        boolean needSep = false;
12711
12712        if (mLruProcesses.size() > 0) {
12713            if (needSep) pw.println();
12714            needSep = true;
12715            pw.println("  OOM levels:");
12716            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12717            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12718            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12719            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12720            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12721            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12722            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12723            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12724            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12725            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12726            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12727            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12728            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12729
12730            if (needSep) pw.println();
12731            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12732                    pw.print(" total, non-act at ");
12733                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12734                    pw.print(", non-svc at ");
12735                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12736                    pw.println("):");
12737            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12738            needSep = true;
12739        }
12740
12741        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12742
12743        pw.println();
12744        pw.println("  mHomeProcess: " + mHomeProcess);
12745        pw.println("  mPreviousProcess: " + mPreviousProcess);
12746        if (mHeavyWeightProcess != null) {
12747            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12748        }
12749
12750        return true;
12751    }
12752
12753    /**
12754     * There are three ways to call this:
12755     *  - no provider specified: dump all the providers
12756     *  - a flattened component name that matched an existing provider was specified as the
12757     *    first arg: dump that one provider
12758     *  - the first arg isn't the flattened component name of an existing provider:
12759     *    dump all providers whose component contains the first arg as a substring
12760     */
12761    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12762            int opti, boolean dumpAll) {
12763        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12764    }
12765
12766    static class ItemMatcher {
12767        ArrayList<ComponentName> components;
12768        ArrayList<String> strings;
12769        ArrayList<Integer> objects;
12770        boolean all;
12771
12772        ItemMatcher() {
12773            all = true;
12774        }
12775
12776        void build(String name) {
12777            ComponentName componentName = ComponentName.unflattenFromString(name);
12778            if (componentName != null) {
12779                if (components == null) {
12780                    components = new ArrayList<ComponentName>();
12781                }
12782                components.add(componentName);
12783                all = false;
12784            } else {
12785                int objectId = 0;
12786                // Not a '/' separated full component name; maybe an object ID?
12787                try {
12788                    objectId = Integer.parseInt(name, 16);
12789                    if (objects == null) {
12790                        objects = new ArrayList<Integer>();
12791                    }
12792                    objects.add(objectId);
12793                    all = false;
12794                } catch (RuntimeException e) {
12795                    // Not an integer; just do string match.
12796                    if (strings == null) {
12797                        strings = new ArrayList<String>();
12798                    }
12799                    strings.add(name);
12800                    all = false;
12801                }
12802            }
12803        }
12804
12805        int build(String[] args, int opti) {
12806            for (; opti<args.length; opti++) {
12807                String name = args[opti];
12808                if ("--".equals(name)) {
12809                    return opti+1;
12810                }
12811                build(name);
12812            }
12813            return opti;
12814        }
12815
12816        boolean match(Object object, ComponentName comp) {
12817            if (all) {
12818                return true;
12819            }
12820            if (components != null) {
12821                for (int i=0; i<components.size(); i++) {
12822                    if (components.get(i).equals(comp)) {
12823                        return true;
12824                    }
12825                }
12826            }
12827            if (objects != null) {
12828                for (int i=0; i<objects.size(); i++) {
12829                    if (System.identityHashCode(object) == objects.get(i)) {
12830                        return true;
12831                    }
12832                }
12833            }
12834            if (strings != null) {
12835                String flat = comp.flattenToString();
12836                for (int i=0; i<strings.size(); i++) {
12837                    if (flat.contains(strings.get(i))) {
12838                        return true;
12839                    }
12840                }
12841            }
12842            return false;
12843        }
12844    }
12845
12846    /**
12847     * There are three things that cmd can be:
12848     *  - a flattened component name that matches an existing activity
12849     *  - the cmd arg isn't the flattened component name of an existing activity:
12850     *    dump all activity whose component contains the cmd as a substring
12851     *  - A hex number of the ActivityRecord object instance.
12852     */
12853    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12854            int opti, boolean dumpAll) {
12855        ArrayList<ActivityRecord> activities;
12856
12857        synchronized (this) {
12858            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12859        }
12860
12861        if (activities.size() <= 0) {
12862            return false;
12863        }
12864
12865        String[] newArgs = new String[args.length - opti];
12866        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12867
12868        TaskRecord lastTask = null;
12869        boolean needSep = false;
12870        for (int i=activities.size()-1; i>=0; i--) {
12871            ActivityRecord r = activities.get(i);
12872            if (needSep) {
12873                pw.println();
12874            }
12875            needSep = true;
12876            synchronized (this) {
12877                if (lastTask != r.task) {
12878                    lastTask = r.task;
12879                    pw.print("TASK "); pw.print(lastTask.affinity);
12880                            pw.print(" id="); pw.println(lastTask.taskId);
12881                    if (dumpAll) {
12882                        lastTask.dump(pw, "  ");
12883                    }
12884                }
12885            }
12886            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12887        }
12888        return true;
12889    }
12890
12891    /**
12892     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12893     * there is a thread associated with the activity.
12894     */
12895    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12896            final ActivityRecord r, String[] args, boolean dumpAll) {
12897        String innerPrefix = prefix + "  ";
12898        synchronized (this) {
12899            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12900                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12901                    pw.print(" pid=");
12902                    if (r.app != null) pw.println(r.app.pid);
12903                    else pw.println("(not running)");
12904            if (dumpAll) {
12905                r.dump(pw, innerPrefix);
12906            }
12907        }
12908        if (r.app != null && r.app.thread != null) {
12909            // flush anything that is already in the PrintWriter since the thread is going
12910            // to write to the file descriptor directly
12911            pw.flush();
12912            try {
12913                TransferPipe tp = new TransferPipe();
12914                try {
12915                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12916                            r.appToken, innerPrefix, args);
12917                    tp.go(fd);
12918                } finally {
12919                    tp.kill();
12920                }
12921            } catch (IOException e) {
12922                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12923            } catch (RemoteException e) {
12924                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12925            }
12926        }
12927    }
12928
12929    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12930            int opti, boolean dumpAll, String dumpPackage) {
12931        boolean needSep = false;
12932        boolean onlyHistory = false;
12933        boolean printedAnything = false;
12934
12935        if ("history".equals(dumpPackage)) {
12936            if (opti < args.length && "-s".equals(args[opti])) {
12937                dumpAll = false;
12938            }
12939            onlyHistory = true;
12940            dumpPackage = null;
12941        }
12942
12943        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12944        if (!onlyHistory && dumpAll) {
12945            if (mRegisteredReceivers.size() > 0) {
12946                boolean printed = false;
12947                Iterator it = mRegisteredReceivers.values().iterator();
12948                while (it.hasNext()) {
12949                    ReceiverList r = (ReceiverList)it.next();
12950                    if (dumpPackage != null && (r.app == null ||
12951                            !dumpPackage.equals(r.app.info.packageName))) {
12952                        continue;
12953                    }
12954                    if (!printed) {
12955                        pw.println("  Registered Receivers:");
12956                        needSep = true;
12957                        printed = true;
12958                        printedAnything = true;
12959                    }
12960                    pw.print("  * "); pw.println(r);
12961                    r.dump(pw, "    ");
12962                }
12963            }
12964
12965            if (mReceiverResolver.dump(pw, needSep ?
12966                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12967                    "    ", dumpPackage, false)) {
12968                needSep = true;
12969                printedAnything = true;
12970            }
12971        }
12972
12973        for (BroadcastQueue q : mBroadcastQueues) {
12974            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12975            printedAnything |= needSep;
12976        }
12977
12978        needSep = true;
12979
12980        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12981            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12982                if (needSep) {
12983                    pw.println();
12984                }
12985                needSep = true;
12986                printedAnything = true;
12987                pw.print("  Sticky broadcasts for user ");
12988                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12989                StringBuilder sb = new StringBuilder(128);
12990                for (Map.Entry<String, ArrayList<Intent>> ent
12991                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12992                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12993                    if (dumpAll) {
12994                        pw.println(":");
12995                        ArrayList<Intent> intents = ent.getValue();
12996                        final int N = intents.size();
12997                        for (int i=0; i<N; i++) {
12998                            sb.setLength(0);
12999                            sb.append("    Intent: ");
13000                            intents.get(i).toShortString(sb, false, true, false, false);
13001                            pw.println(sb.toString());
13002                            Bundle bundle = intents.get(i).getExtras();
13003                            if (bundle != null) {
13004                                pw.print("      ");
13005                                pw.println(bundle.toString());
13006                            }
13007                        }
13008                    } else {
13009                        pw.println("");
13010                    }
13011                }
13012            }
13013        }
13014
13015        if (!onlyHistory && dumpAll) {
13016            pw.println();
13017            for (BroadcastQueue queue : mBroadcastQueues) {
13018                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13019                        + queue.mBroadcastsScheduled);
13020            }
13021            pw.println("  mHandler:");
13022            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13023            needSep = true;
13024            printedAnything = true;
13025        }
13026
13027        if (!printedAnything) {
13028            pw.println("  (nothing)");
13029        }
13030    }
13031
13032    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13033            int opti, boolean dumpAll, String dumpPackage) {
13034        boolean needSep;
13035        boolean printedAnything = false;
13036
13037        ItemMatcher matcher = new ItemMatcher();
13038        matcher.build(args, opti);
13039
13040        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13041
13042        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13043        printedAnything |= needSep;
13044
13045        if (mLaunchingProviders.size() > 0) {
13046            boolean printed = false;
13047            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13048                ContentProviderRecord r = mLaunchingProviders.get(i);
13049                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13050                    continue;
13051                }
13052                if (!printed) {
13053                    if (needSep) pw.println();
13054                    needSep = true;
13055                    pw.println("  Launching content providers:");
13056                    printed = true;
13057                    printedAnything = true;
13058                }
13059                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13060                        pw.println(r);
13061            }
13062        }
13063
13064        if (mGrantedUriPermissions.size() > 0) {
13065            boolean printed = false;
13066            int dumpUid = -2;
13067            if (dumpPackage != null) {
13068                try {
13069                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13070                } catch (NameNotFoundException e) {
13071                    dumpUid = -1;
13072                }
13073            }
13074            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13075                int uid = mGrantedUriPermissions.keyAt(i);
13076                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13077                    continue;
13078                }
13079                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13080                if (!printed) {
13081                    if (needSep) pw.println();
13082                    needSep = true;
13083                    pw.println("  Granted Uri Permissions:");
13084                    printed = true;
13085                    printedAnything = true;
13086                }
13087                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13088                for (UriPermission perm : perms.values()) {
13089                    pw.print("    "); pw.println(perm);
13090                    if (dumpAll) {
13091                        perm.dump(pw, "      ");
13092                    }
13093                }
13094            }
13095        }
13096
13097        if (!printedAnything) {
13098            pw.println("  (nothing)");
13099        }
13100    }
13101
13102    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13103            int opti, boolean dumpAll, String dumpPackage) {
13104        boolean printed = false;
13105
13106        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13107
13108        if (mIntentSenderRecords.size() > 0) {
13109            Iterator<WeakReference<PendingIntentRecord>> it
13110                    = mIntentSenderRecords.values().iterator();
13111            while (it.hasNext()) {
13112                WeakReference<PendingIntentRecord> ref = it.next();
13113                PendingIntentRecord rec = ref != null ? ref.get(): null;
13114                if (dumpPackage != null && (rec == null
13115                        || !dumpPackage.equals(rec.key.packageName))) {
13116                    continue;
13117                }
13118                printed = true;
13119                if (rec != null) {
13120                    pw.print("  * "); pw.println(rec);
13121                    if (dumpAll) {
13122                        rec.dump(pw, "    ");
13123                    }
13124                } else {
13125                    pw.print("  * "); pw.println(ref);
13126                }
13127            }
13128        }
13129
13130        if (!printed) {
13131            pw.println("  (nothing)");
13132        }
13133    }
13134
13135    private static final int dumpProcessList(PrintWriter pw,
13136            ActivityManagerService service, List list,
13137            String prefix, String normalLabel, String persistentLabel,
13138            String dumpPackage) {
13139        int numPers = 0;
13140        final int N = list.size()-1;
13141        for (int i=N; i>=0; i--) {
13142            ProcessRecord r = (ProcessRecord)list.get(i);
13143            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13144                continue;
13145            }
13146            pw.println(String.format("%s%s #%2d: %s",
13147                    prefix, (r.persistent ? persistentLabel : normalLabel),
13148                    i, r.toString()));
13149            if (r.persistent) {
13150                numPers++;
13151            }
13152        }
13153        return numPers;
13154    }
13155
13156    private static final boolean dumpProcessOomList(PrintWriter pw,
13157            ActivityManagerService service, List<ProcessRecord> origList,
13158            String prefix, String normalLabel, String persistentLabel,
13159            boolean inclDetails, String dumpPackage) {
13160
13161        ArrayList<Pair<ProcessRecord, Integer>> list
13162                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13163        for (int i=0; i<origList.size(); i++) {
13164            ProcessRecord r = origList.get(i);
13165            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13166                continue;
13167            }
13168            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13169        }
13170
13171        if (list.size() <= 0) {
13172            return false;
13173        }
13174
13175        Comparator<Pair<ProcessRecord, Integer>> comparator
13176                = new Comparator<Pair<ProcessRecord, Integer>>() {
13177            @Override
13178            public int compare(Pair<ProcessRecord, Integer> object1,
13179                    Pair<ProcessRecord, Integer> object2) {
13180                if (object1.first.setAdj != object2.first.setAdj) {
13181                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13182                }
13183                if (object1.second.intValue() != object2.second.intValue()) {
13184                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13185                }
13186                return 0;
13187            }
13188        };
13189
13190        Collections.sort(list, comparator);
13191
13192        final long curRealtime = SystemClock.elapsedRealtime();
13193        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13194        final long curUptime = SystemClock.uptimeMillis();
13195        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13196
13197        for (int i=list.size()-1; i>=0; i--) {
13198            ProcessRecord r = list.get(i).first;
13199            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13200            char schedGroup;
13201            switch (r.setSchedGroup) {
13202                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13203                    schedGroup = 'B';
13204                    break;
13205                case Process.THREAD_GROUP_DEFAULT:
13206                    schedGroup = 'F';
13207                    break;
13208                default:
13209                    schedGroup = '?';
13210                    break;
13211            }
13212            char foreground;
13213            if (r.foregroundActivities) {
13214                foreground = 'A';
13215            } else if (r.foregroundServices) {
13216                foreground = 'S';
13217            } else {
13218                foreground = ' ';
13219            }
13220            String procState = ProcessList.makeProcStateString(r.curProcState);
13221            pw.print(prefix);
13222            pw.print(r.persistent ? persistentLabel : normalLabel);
13223            pw.print(" #");
13224            int num = (origList.size()-1)-list.get(i).second;
13225            if (num < 10) pw.print(' ');
13226            pw.print(num);
13227            pw.print(": ");
13228            pw.print(oomAdj);
13229            pw.print(' ');
13230            pw.print(schedGroup);
13231            pw.print('/');
13232            pw.print(foreground);
13233            pw.print('/');
13234            pw.print(procState);
13235            pw.print(" trm:");
13236            if (r.trimMemoryLevel < 10) pw.print(' ');
13237            pw.print(r.trimMemoryLevel);
13238            pw.print(' ');
13239            pw.print(r.toShortString());
13240            pw.print(" (");
13241            pw.print(r.adjType);
13242            pw.println(')');
13243            if (r.adjSource != null || r.adjTarget != null) {
13244                pw.print(prefix);
13245                pw.print("    ");
13246                if (r.adjTarget instanceof ComponentName) {
13247                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13248                } else if (r.adjTarget != null) {
13249                    pw.print(r.adjTarget.toString());
13250                } else {
13251                    pw.print("{null}");
13252                }
13253                pw.print("<=");
13254                if (r.adjSource instanceof ProcessRecord) {
13255                    pw.print("Proc{");
13256                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13257                    pw.println("}");
13258                } else if (r.adjSource != null) {
13259                    pw.println(r.adjSource.toString());
13260                } else {
13261                    pw.println("{null}");
13262                }
13263            }
13264            if (inclDetails) {
13265                pw.print(prefix);
13266                pw.print("    ");
13267                pw.print("oom: max="); pw.print(r.maxAdj);
13268                pw.print(" curRaw="); pw.print(r.curRawAdj);
13269                pw.print(" setRaw="); pw.print(r.setRawAdj);
13270                pw.print(" cur="); pw.print(r.curAdj);
13271                pw.print(" set="); pw.println(r.setAdj);
13272                pw.print(prefix);
13273                pw.print("    ");
13274                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13275                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13276                pw.print(" lastPss="); pw.print(r.lastPss);
13277                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13278                pw.print(prefix);
13279                pw.print("    ");
13280                pw.print("cached="); pw.print(r.cached);
13281                pw.print(" empty="); pw.print(r.empty);
13282                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13283
13284                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13285                    if (r.lastWakeTime != 0) {
13286                        long wtime;
13287                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13288                        synchronized (stats) {
13289                            wtime = stats.getProcessWakeTime(r.info.uid,
13290                                    r.pid, curRealtime);
13291                        }
13292                        long timeUsed = wtime - r.lastWakeTime;
13293                        pw.print(prefix);
13294                        pw.print("    ");
13295                        pw.print("keep awake over ");
13296                        TimeUtils.formatDuration(realtimeSince, pw);
13297                        pw.print(" used ");
13298                        TimeUtils.formatDuration(timeUsed, pw);
13299                        pw.print(" (");
13300                        pw.print((timeUsed*100)/realtimeSince);
13301                        pw.println("%)");
13302                    }
13303                    if (r.lastCpuTime != 0) {
13304                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13305                        pw.print(prefix);
13306                        pw.print("    ");
13307                        pw.print("run cpu over ");
13308                        TimeUtils.formatDuration(uptimeSince, pw);
13309                        pw.print(" used ");
13310                        TimeUtils.formatDuration(timeUsed, pw);
13311                        pw.print(" (");
13312                        pw.print((timeUsed*100)/uptimeSince);
13313                        pw.println("%)");
13314                    }
13315                }
13316            }
13317        }
13318        return true;
13319    }
13320
13321    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13322        ArrayList<ProcessRecord> procs;
13323        synchronized (this) {
13324            if (args != null && args.length > start
13325                    && args[start].charAt(0) != '-') {
13326                procs = new ArrayList<ProcessRecord>();
13327                int pid = -1;
13328                try {
13329                    pid = Integer.parseInt(args[start]);
13330                } catch (NumberFormatException e) {
13331                }
13332                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13333                    ProcessRecord proc = mLruProcesses.get(i);
13334                    if (proc.pid == pid) {
13335                        procs.add(proc);
13336                    } else if (proc.processName.equals(args[start])) {
13337                        procs.add(proc);
13338                    }
13339                }
13340                if (procs.size() <= 0) {
13341                    return null;
13342                }
13343            } else {
13344                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13345            }
13346        }
13347        return procs;
13348    }
13349
13350    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13351            PrintWriter pw, String[] args) {
13352        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13353        if (procs == null) {
13354            pw.println("No process found for: " + args[0]);
13355            return;
13356        }
13357
13358        long uptime = SystemClock.uptimeMillis();
13359        long realtime = SystemClock.elapsedRealtime();
13360        pw.println("Applications Graphics Acceleration Info:");
13361        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13362
13363        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13364            ProcessRecord r = procs.get(i);
13365            if (r.thread != null) {
13366                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13367                pw.flush();
13368                try {
13369                    TransferPipe tp = new TransferPipe();
13370                    try {
13371                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13372                        tp.go(fd);
13373                    } finally {
13374                        tp.kill();
13375                    }
13376                } catch (IOException e) {
13377                    pw.println("Failure while dumping the app: " + r);
13378                    pw.flush();
13379                } catch (RemoteException e) {
13380                    pw.println("Got a RemoteException while dumping the app " + r);
13381                    pw.flush();
13382                }
13383            }
13384        }
13385    }
13386
13387    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13388        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13389        if (procs == null) {
13390            pw.println("No process found for: " + args[0]);
13391            return;
13392        }
13393
13394        pw.println("Applications Database Info:");
13395
13396        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13397            ProcessRecord r = procs.get(i);
13398            if (r.thread != null) {
13399                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13400                pw.flush();
13401                try {
13402                    TransferPipe tp = new TransferPipe();
13403                    try {
13404                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13405                        tp.go(fd);
13406                    } finally {
13407                        tp.kill();
13408                    }
13409                } catch (IOException e) {
13410                    pw.println("Failure while dumping the app: " + r);
13411                    pw.flush();
13412                } catch (RemoteException e) {
13413                    pw.println("Got a RemoteException while dumping the app " + r);
13414                    pw.flush();
13415                }
13416            }
13417        }
13418    }
13419
13420    final static class MemItem {
13421        final boolean isProc;
13422        final String label;
13423        final String shortLabel;
13424        final long pss;
13425        final int id;
13426        final boolean hasActivities;
13427        ArrayList<MemItem> subitems;
13428
13429        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13430                boolean _hasActivities) {
13431            isProc = true;
13432            label = _label;
13433            shortLabel = _shortLabel;
13434            pss = _pss;
13435            id = _id;
13436            hasActivities = _hasActivities;
13437        }
13438
13439        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13440            isProc = false;
13441            label = _label;
13442            shortLabel = _shortLabel;
13443            pss = _pss;
13444            id = _id;
13445            hasActivities = false;
13446        }
13447    }
13448
13449    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13450            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13451        if (sort && !isCompact) {
13452            Collections.sort(items, new Comparator<MemItem>() {
13453                @Override
13454                public int compare(MemItem lhs, MemItem rhs) {
13455                    if (lhs.pss < rhs.pss) {
13456                        return 1;
13457                    } else if (lhs.pss > rhs.pss) {
13458                        return -1;
13459                    }
13460                    return 0;
13461                }
13462            });
13463        }
13464
13465        for (int i=0; i<items.size(); i++) {
13466            MemItem mi = items.get(i);
13467            if (!isCompact) {
13468                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13469            } else if (mi.isProc) {
13470                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13471                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13472                pw.println(mi.hasActivities ? ",a" : ",e");
13473            } else {
13474                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13475                pw.println(mi.pss);
13476            }
13477            if (mi.subitems != null) {
13478                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13479                        true, isCompact);
13480            }
13481        }
13482    }
13483
13484    // These are in KB.
13485    static final long[] DUMP_MEM_BUCKETS = new long[] {
13486        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13487        120*1024, 160*1024, 200*1024,
13488        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13489        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13490    };
13491
13492    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13493            boolean stackLike) {
13494        int start = label.lastIndexOf('.');
13495        if (start >= 0) start++;
13496        else start = 0;
13497        int end = label.length();
13498        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13499            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13500                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13501                out.append(bucket);
13502                out.append(stackLike ? "MB." : "MB ");
13503                out.append(label, start, end);
13504                return;
13505            }
13506        }
13507        out.append(memKB/1024);
13508        out.append(stackLike ? "MB." : "MB ");
13509        out.append(label, start, end);
13510    }
13511
13512    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13513            ProcessList.NATIVE_ADJ,
13514            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13515            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13516            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13517            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13518            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13519    };
13520    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13521            "Native",
13522            "System", "Persistent", "Foreground",
13523            "Visible", "Perceptible",
13524            "Heavy Weight", "Backup",
13525            "A Services", "Home",
13526            "Previous", "B Services", "Cached"
13527    };
13528    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13529            "native",
13530            "sys", "pers", "fore",
13531            "vis", "percept",
13532            "heavy", "backup",
13533            "servicea", "home",
13534            "prev", "serviceb", "cached"
13535    };
13536
13537    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13538            long realtime, boolean isCheckinRequest, boolean isCompact) {
13539        if (isCheckinRequest || isCompact) {
13540            // short checkin version
13541            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13542        } else {
13543            pw.println("Applications Memory Usage (kB):");
13544            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13545        }
13546    }
13547
13548    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13549            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13550        boolean dumpDetails = false;
13551        boolean dumpFullDetails = false;
13552        boolean dumpDalvik = false;
13553        boolean oomOnly = false;
13554        boolean isCompact = false;
13555        boolean localOnly = false;
13556
13557        int opti = 0;
13558        while (opti < args.length) {
13559            String opt = args[opti];
13560            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13561                break;
13562            }
13563            opti++;
13564            if ("-a".equals(opt)) {
13565                dumpDetails = true;
13566                dumpFullDetails = true;
13567                dumpDalvik = true;
13568            } else if ("-d".equals(opt)) {
13569                dumpDalvik = true;
13570            } else if ("-c".equals(opt)) {
13571                isCompact = true;
13572            } else if ("--oom".equals(opt)) {
13573                oomOnly = true;
13574            } else if ("--local".equals(opt)) {
13575                localOnly = true;
13576            } else if ("-h".equals(opt)) {
13577                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13578                pw.println("  -a: include all available information for each process.");
13579                pw.println("  -d: include dalvik details when dumping process details.");
13580                pw.println("  -c: dump in a compact machine-parseable representation.");
13581                pw.println("  --oom: only show processes organized by oom adj.");
13582                pw.println("  --local: only collect details locally, don't call process.");
13583                pw.println("If [process] is specified it can be the name or ");
13584                pw.println("pid of a specific process to dump.");
13585                return;
13586            } else {
13587                pw.println("Unknown argument: " + opt + "; use -h for help");
13588            }
13589        }
13590
13591        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13592        long uptime = SystemClock.uptimeMillis();
13593        long realtime = SystemClock.elapsedRealtime();
13594        final long[] tmpLong = new long[1];
13595
13596        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13597        if (procs == null) {
13598            // No Java processes.  Maybe they want to print a native process.
13599            if (args != null && args.length > opti
13600                    && args[opti].charAt(0) != '-') {
13601                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13602                        = new ArrayList<ProcessCpuTracker.Stats>();
13603                updateCpuStatsNow();
13604                int findPid = -1;
13605                try {
13606                    findPid = Integer.parseInt(args[opti]);
13607                } catch (NumberFormatException e) {
13608                }
13609                synchronized (mProcessCpuThread) {
13610                    final int N = mProcessCpuTracker.countStats();
13611                    for (int i=0; i<N; i++) {
13612                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13613                        if (st.pid == findPid || (st.baseName != null
13614                                && st.baseName.equals(args[opti]))) {
13615                            nativeProcs.add(st);
13616                        }
13617                    }
13618                }
13619                if (nativeProcs.size() > 0) {
13620                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13621                            isCompact);
13622                    Debug.MemoryInfo mi = null;
13623                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13624                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13625                        final int pid = r.pid;
13626                        if (!isCheckinRequest && dumpDetails) {
13627                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13628                        }
13629                        if (mi == null) {
13630                            mi = new Debug.MemoryInfo();
13631                        }
13632                        if (dumpDetails || (!brief && !oomOnly)) {
13633                            Debug.getMemoryInfo(pid, mi);
13634                        } else {
13635                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13636                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13637                        }
13638                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13639                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13640                        if (isCheckinRequest) {
13641                            pw.println();
13642                        }
13643                    }
13644                    return;
13645                }
13646            }
13647            pw.println("No process found for: " + args[opti]);
13648            return;
13649        }
13650
13651        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13652            dumpDetails = true;
13653        }
13654
13655        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13656
13657        String[] innerArgs = new String[args.length-opti];
13658        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13659
13660        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13661        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13662        long nativePss=0, dalvikPss=0, otherPss=0;
13663        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13664
13665        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13666        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13667                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13668
13669        long totalPss = 0;
13670        long cachedPss = 0;
13671
13672        Debug.MemoryInfo mi = null;
13673        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13674            final ProcessRecord r = procs.get(i);
13675            final IApplicationThread thread;
13676            final int pid;
13677            final int oomAdj;
13678            final boolean hasActivities;
13679            synchronized (this) {
13680                thread = r.thread;
13681                pid = r.pid;
13682                oomAdj = r.getSetAdjWithServices();
13683                hasActivities = r.activities.size() > 0;
13684            }
13685            if (thread != null) {
13686                if (!isCheckinRequest && dumpDetails) {
13687                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13688                }
13689                if (mi == null) {
13690                    mi = new Debug.MemoryInfo();
13691                }
13692                if (dumpDetails || (!brief && !oomOnly)) {
13693                    Debug.getMemoryInfo(pid, mi);
13694                } else {
13695                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13696                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13697                }
13698                if (dumpDetails) {
13699                    if (localOnly) {
13700                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13701                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13702                        if (isCheckinRequest) {
13703                            pw.println();
13704                        }
13705                    } else {
13706                        try {
13707                            pw.flush();
13708                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13709                                    dumpDalvik, innerArgs);
13710                        } catch (RemoteException e) {
13711                            if (!isCheckinRequest) {
13712                                pw.println("Got RemoteException!");
13713                                pw.flush();
13714                            }
13715                        }
13716                    }
13717                }
13718
13719                final long myTotalPss = mi.getTotalPss();
13720                final long myTotalUss = mi.getTotalUss();
13721
13722                synchronized (this) {
13723                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13724                        // Record this for posterity if the process has been stable.
13725                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13726                    }
13727                }
13728
13729                if (!isCheckinRequest && mi != null) {
13730                    totalPss += myTotalPss;
13731                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13732                            (hasActivities ? " / activities)" : ")"),
13733                            r.processName, myTotalPss, pid, hasActivities);
13734                    procMems.add(pssItem);
13735                    procMemsMap.put(pid, pssItem);
13736
13737                    nativePss += mi.nativePss;
13738                    dalvikPss += mi.dalvikPss;
13739                    otherPss += mi.otherPss;
13740                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13741                        long mem = mi.getOtherPss(j);
13742                        miscPss[j] += mem;
13743                        otherPss -= mem;
13744                    }
13745
13746                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13747                        cachedPss += myTotalPss;
13748                    }
13749
13750                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13751                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13752                                || oomIndex == (oomPss.length-1)) {
13753                            oomPss[oomIndex] += myTotalPss;
13754                            if (oomProcs[oomIndex] == null) {
13755                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13756                            }
13757                            oomProcs[oomIndex].add(pssItem);
13758                            break;
13759                        }
13760                    }
13761                }
13762            }
13763        }
13764
13765        long nativeProcTotalPss = 0;
13766
13767        if (!isCheckinRequest && procs.size() > 1) {
13768            // If we are showing aggregations, also look for native processes to
13769            // include so that our aggregations are more accurate.
13770            updateCpuStatsNow();
13771            synchronized (mProcessCpuThread) {
13772                final int N = mProcessCpuTracker.countStats();
13773                for (int i=0; i<N; i++) {
13774                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13775                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13776                        if (mi == null) {
13777                            mi = new Debug.MemoryInfo();
13778                        }
13779                        if (!brief && !oomOnly) {
13780                            Debug.getMemoryInfo(st.pid, mi);
13781                        } else {
13782                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13783                            mi.nativePrivateDirty = (int)tmpLong[0];
13784                        }
13785
13786                        final long myTotalPss = mi.getTotalPss();
13787                        totalPss += myTotalPss;
13788                        nativeProcTotalPss += myTotalPss;
13789
13790                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13791                                st.name, myTotalPss, st.pid, false);
13792                        procMems.add(pssItem);
13793
13794                        nativePss += mi.nativePss;
13795                        dalvikPss += mi.dalvikPss;
13796                        otherPss += mi.otherPss;
13797                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13798                            long mem = mi.getOtherPss(j);
13799                            miscPss[j] += mem;
13800                            otherPss -= mem;
13801                        }
13802                        oomPss[0] += myTotalPss;
13803                        if (oomProcs[0] == null) {
13804                            oomProcs[0] = new ArrayList<MemItem>();
13805                        }
13806                        oomProcs[0].add(pssItem);
13807                    }
13808                }
13809            }
13810
13811            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13812
13813            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13814            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13815            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13816            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13817                String label = Debug.MemoryInfo.getOtherLabel(j);
13818                catMems.add(new MemItem(label, label, miscPss[j], j));
13819            }
13820
13821            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13822            for (int j=0; j<oomPss.length; j++) {
13823                if (oomPss[j] != 0) {
13824                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13825                            : DUMP_MEM_OOM_LABEL[j];
13826                    MemItem item = new MemItem(label, label, oomPss[j],
13827                            DUMP_MEM_OOM_ADJ[j]);
13828                    item.subitems = oomProcs[j];
13829                    oomMems.add(item);
13830                }
13831            }
13832
13833            if (!brief && !oomOnly && !isCompact) {
13834                pw.println();
13835                pw.println("Total PSS by process:");
13836                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13837                pw.println();
13838            }
13839            if (!isCompact) {
13840                pw.println("Total PSS by OOM adjustment:");
13841            }
13842            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13843            if (!brief && !oomOnly) {
13844                PrintWriter out = categoryPw != null ? categoryPw : pw;
13845                if (!isCompact) {
13846                    out.println();
13847                    out.println("Total PSS by category:");
13848                }
13849                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13850            }
13851            if (!isCompact) {
13852                pw.println();
13853            }
13854            MemInfoReader memInfo = new MemInfoReader();
13855            memInfo.readMemInfo();
13856            if (nativeProcTotalPss > 0) {
13857                synchronized (this) {
13858                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13859                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13860                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13861                            nativeProcTotalPss);
13862                }
13863            }
13864            if (!brief) {
13865                if (!isCompact) {
13866                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13867                    pw.print(" kB (status ");
13868                    switch (mLastMemoryLevel) {
13869                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13870                            pw.println("normal)");
13871                            break;
13872                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13873                            pw.println("moderate)");
13874                            break;
13875                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13876                            pw.println("low)");
13877                            break;
13878                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13879                            pw.println("critical)");
13880                            break;
13881                        default:
13882                            pw.print(mLastMemoryLevel);
13883                            pw.println(")");
13884                            break;
13885                    }
13886                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13887                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13888                            pw.print(cachedPss); pw.print(" cached pss + ");
13889                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13890                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13891                } else {
13892                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13893                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13894                            + memInfo.getFreeSizeKb()); pw.print(",");
13895                    pw.println(totalPss - cachedPss);
13896                }
13897            }
13898            if (!isCompact) {
13899                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13900                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13901                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13902                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13903                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13904                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13905                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13906                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13907                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13908                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13909                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13910            }
13911            if (!brief) {
13912                if (memInfo.getZramTotalSizeKb() != 0) {
13913                    if (!isCompact) {
13914                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13915                                pw.print(" kB physical used for ");
13916                                pw.print(memInfo.getSwapTotalSizeKb()
13917                                        - memInfo.getSwapFreeSizeKb());
13918                                pw.print(" kB in swap (");
13919                                pw.print(memInfo.getSwapTotalSizeKb());
13920                                pw.println(" kB total swap)");
13921                    } else {
13922                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13923                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13924                                pw.println(memInfo.getSwapFreeSizeKb());
13925                    }
13926                }
13927                final int[] SINGLE_LONG_FORMAT = new int[] {
13928                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13929                };
13930                long[] longOut = new long[1];
13931                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13932                        SINGLE_LONG_FORMAT, null, longOut, null);
13933                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13934                longOut[0] = 0;
13935                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13936                        SINGLE_LONG_FORMAT, null, longOut, null);
13937                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13938                longOut[0] = 0;
13939                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13940                        SINGLE_LONG_FORMAT, null, longOut, null);
13941                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13942                longOut[0] = 0;
13943                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13944                        SINGLE_LONG_FORMAT, null, longOut, null);
13945                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13946                if (!isCompact) {
13947                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13948                        pw.print("      KSM: "); pw.print(sharing);
13949                                pw.print(" kB saved from shared ");
13950                                pw.print(shared); pw.println(" kB");
13951                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13952                                pw.print(voltile); pw.println(" kB volatile");
13953                    }
13954                    pw.print("   Tuning: ");
13955                    pw.print(ActivityManager.staticGetMemoryClass());
13956                    pw.print(" (large ");
13957                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13958                    pw.print("), oom ");
13959                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13960                    pw.print(" kB");
13961                    pw.print(", restore limit ");
13962                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13963                    pw.print(" kB");
13964                    if (ActivityManager.isLowRamDeviceStatic()) {
13965                        pw.print(" (low-ram)");
13966                    }
13967                    if (ActivityManager.isHighEndGfx()) {
13968                        pw.print(" (high-end-gfx)");
13969                    }
13970                    pw.println();
13971                } else {
13972                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13973                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13974                    pw.println(voltile);
13975                    pw.print("tuning,");
13976                    pw.print(ActivityManager.staticGetMemoryClass());
13977                    pw.print(',');
13978                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13979                    pw.print(',');
13980                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13981                    if (ActivityManager.isLowRamDeviceStatic()) {
13982                        pw.print(",low-ram");
13983                    }
13984                    if (ActivityManager.isHighEndGfx()) {
13985                        pw.print(",high-end-gfx");
13986                    }
13987                    pw.println();
13988                }
13989            }
13990        }
13991    }
13992
13993    /**
13994     * Searches array of arguments for the specified string
13995     * @param args array of argument strings
13996     * @param value value to search for
13997     * @return true if the value is contained in the array
13998     */
13999    private static boolean scanArgs(String[] args, String value) {
14000        if (args != null) {
14001            for (String arg : args) {
14002                if (value.equals(arg)) {
14003                    return true;
14004                }
14005            }
14006        }
14007        return false;
14008    }
14009
14010    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14011            ContentProviderRecord cpr, boolean always) {
14012        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14013
14014        if (!inLaunching || always) {
14015            synchronized (cpr) {
14016                cpr.launchingApp = null;
14017                cpr.notifyAll();
14018            }
14019            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14020            String names[] = cpr.info.authority.split(";");
14021            for (int j = 0; j < names.length; j++) {
14022                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14023            }
14024        }
14025
14026        for (int i=0; i<cpr.connections.size(); i++) {
14027            ContentProviderConnection conn = cpr.connections.get(i);
14028            if (conn.waiting) {
14029                // If this connection is waiting for the provider, then we don't
14030                // need to mess with its process unless we are always removing
14031                // or for some reason the provider is not currently launching.
14032                if (inLaunching && !always) {
14033                    continue;
14034                }
14035            }
14036            ProcessRecord capp = conn.client;
14037            conn.dead = true;
14038            if (conn.stableCount > 0) {
14039                if (!capp.persistent && capp.thread != null
14040                        && capp.pid != 0
14041                        && capp.pid != MY_PID) {
14042                    capp.kill("depends on provider "
14043                            + cpr.name.flattenToShortString()
14044                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14045                }
14046            } else if (capp.thread != null && conn.provider.provider != null) {
14047                try {
14048                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14049                } catch (RemoteException e) {
14050                }
14051                // In the protocol here, we don't expect the client to correctly
14052                // clean up this connection, we'll just remove it.
14053                cpr.connections.remove(i);
14054                conn.client.conProviders.remove(conn);
14055            }
14056        }
14057
14058        if (inLaunching && always) {
14059            mLaunchingProviders.remove(cpr);
14060        }
14061        return inLaunching;
14062    }
14063
14064    /**
14065     * Main code for cleaning up a process when it has gone away.  This is
14066     * called both as a result of the process dying, or directly when stopping
14067     * a process when running in single process mode.
14068     */
14069    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14070            boolean restarting, boolean allowRestart, int index) {
14071        if (index >= 0) {
14072            removeLruProcessLocked(app);
14073            ProcessList.remove(app.pid);
14074        }
14075
14076        mProcessesToGc.remove(app);
14077        mPendingPssProcesses.remove(app);
14078
14079        // Dismiss any open dialogs.
14080        if (app.crashDialog != null && !app.forceCrashReport) {
14081            app.crashDialog.dismiss();
14082            app.crashDialog = null;
14083        }
14084        if (app.anrDialog != null) {
14085            app.anrDialog.dismiss();
14086            app.anrDialog = null;
14087        }
14088        if (app.waitDialog != null) {
14089            app.waitDialog.dismiss();
14090            app.waitDialog = null;
14091        }
14092
14093        app.crashing = false;
14094        app.notResponding = false;
14095
14096        app.resetPackageList(mProcessStats);
14097        app.unlinkDeathRecipient();
14098        app.makeInactive(mProcessStats);
14099        app.waitingToKill = null;
14100        app.forcingToForeground = null;
14101        updateProcessForegroundLocked(app, false, false);
14102        app.foregroundActivities = false;
14103        app.hasShownUi = false;
14104        app.treatLikeActivity = false;
14105        app.hasAboveClient = false;
14106        app.hasClientActivities = false;
14107
14108        mServices.killServicesLocked(app, allowRestart);
14109
14110        boolean restart = false;
14111
14112        // Remove published content providers.
14113        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14114            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14115            final boolean always = app.bad || !allowRestart;
14116            if (removeDyingProviderLocked(app, cpr, always) || always) {
14117                // We left the provider in the launching list, need to
14118                // restart it.
14119                restart = true;
14120            }
14121
14122            cpr.provider = null;
14123            cpr.proc = null;
14124        }
14125        app.pubProviders.clear();
14126
14127        // Take care of any launching providers waiting for this process.
14128        if (checkAppInLaunchingProvidersLocked(app, false)) {
14129            restart = true;
14130        }
14131
14132        // Unregister from connected content providers.
14133        if (!app.conProviders.isEmpty()) {
14134            for (int i=0; i<app.conProviders.size(); i++) {
14135                ContentProviderConnection conn = app.conProviders.get(i);
14136                conn.provider.connections.remove(conn);
14137            }
14138            app.conProviders.clear();
14139        }
14140
14141        // At this point there may be remaining entries in mLaunchingProviders
14142        // where we were the only one waiting, so they are no longer of use.
14143        // Look for these and clean up if found.
14144        // XXX Commented out for now.  Trying to figure out a way to reproduce
14145        // the actual situation to identify what is actually going on.
14146        if (false) {
14147            for (int i=0; i<mLaunchingProviders.size(); i++) {
14148                ContentProviderRecord cpr = (ContentProviderRecord)
14149                        mLaunchingProviders.get(i);
14150                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14151                    synchronized (cpr) {
14152                        cpr.launchingApp = null;
14153                        cpr.notifyAll();
14154                    }
14155                }
14156            }
14157        }
14158
14159        skipCurrentReceiverLocked(app);
14160
14161        // Unregister any receivers.
14162        for (int i=app.receivers.size()-1; i>=0; i--) {
14163            removeReceiverLocked(app.receivers.valueAt(i));
14164        }
14165        app.receivers.clear();
14166
14167        // If the app is undergoing backup, tell the backup manager about it
14168        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14169            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14170                    + mBackupTarget.appInfo + " died during backup");
14171            try {
14172                IBackupManager bm = IBackupManager.Stub.asInterface(
14173                        ServiceManager.getService(Context.BACKUP_SERVICE));
14174                bm.agentDisconnected(app.info.packageName);
14175            } catch (RemoteException e) {
14176                // can't happen; backup manager is local
14177            }
14178        }
14179
14180        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14181            ProcessChangeItem item = mPendingProcessChanges.get(i);
14182            if (item.pid == app.pid) {
14183                mPendingProcessChanges.remove(i);
14184                mAvailProcessChanges.add(item);
14185            }
14186        }
14187        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14188
14189        // If the caller is restarting this app, then leave it in its
14190        // current lists and let the caller take care of it.
14191        if (restarting) {
14192            return;
14193        }
14194
14195        if (!app.persistent || app.isolated) {
14196            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14197                    "Removing non-persistent process during cleanup: " + app);
14198            mProcessNames.remove(app.processName, app.uid);
14199            mIsolatedProcesses.remove(app.uid);
14200            if (mHeavyWeightProcess == app) {
14201                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14202                        mHeavyWeightProcess.userId, 0));
14203                mHeavyWeightProcess = null;
14204            }
14205        } else if (!app.removed) {
14206            // This app is persistent, so we need to keep its record around.
14207            // If it is not already on the pending app list, add it there
14208            // and start a new process for it.
14209            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14210                mPersistentStartingProcesses.add(app);
14211                restart = true;
14212            }
14213        }
14214        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14215                "Clean-up removing on hold: " + app);
14216        mProcessesOnHold.remove(app);
14217
14218        if (app == mHomeProcess) {
14219            mHomeProcess = null;
14220        }
14221        if (app == mPreviousProcess) {
14222            mPreviousProcess = null;
14223        }
14224
14225        if (restart && !app.isolated) {
14226            // We have components that still need to be running in the
14227            // process, so re-launch it.
14228            mProcessNames.put(app.processName, app.uid, app);
14229            startProcessLocked(app, "restart", app.processName);
14230        } else if (app.pid > 0 && app.pid != MY_PID) {
14231            // Goodbye!
14232            boolean removed;
14233            synchronized (mPidsSelfLocked) {
14234                mPidsSelfLocked.remove(app.pid);
14235                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14236            }
14237            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14238            if (app.isolated) {
14239                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14240            }
14241            app.setPid(0);
14242        }
14243    }
14244
14245    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14246        // Look through the content providers we are waiting to have launched,
14247        // and if any run in this process then either schedule a restart of
14248        // the process or kill the client waiting for it if this process has
14249        // gone bad.
14250        int NL = mLaunchingProviders.size();
14251        boolean restart = false;
14252        for (int i=0; i<NL; i++) {
14253            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14254            if (cpr.launchingApp == app) {
14255                if (!alwaysBad && !app.bad) {
14256                    restart = true;
14257                } else {
14258                    removeDyingProviderLocked(app, cpr, true);
14259                    // cpr should have been removed from mLaunchingProviders
14260                    NL = mLaunchingProviders.size();
14261                    i--;
14262                }
14263            }
14264        }
14265        return restart;
14266    }
14267
14268    // =========================================================
14269    // SERVICES
14270    // =========================================================
14271
14272    @Override
14273    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14274            int flags) {
14275        enforceNotIsolatedCaller("getServices");
14276        synchronized (this) {
14277            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14278        }
14279    }
14280
14281    @Override
14282    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14283        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14284        synchronized (this) {
14285            return mServices.getRunningServiceControlPanelLocked(name);
14286        }
14287    }
14288
14289    @Override
14290    public ComponentName startService(IApplicationThread caller, Intent service,
14291            String resolvedType, int userId) {
14292        enforceNotIsolatedCaller("startService");
14293        // Refuse possible leaked file descriptors
14294        if (service != null && service.hasFileDescriptors() == true) {
14295            throw new IllegalArgumentException("File descriptors passed in Intent");
14296        }
14297
14298        if (DEBUG_SERVICE)
14299            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14300        synchronized(this) {
14301            final int callingPid = Binder.getCallingPid();
14302            final int callingUid = Binder.getCallingUid();
14303            final long origId = Binder.clearCallingIdentity();
14304            ComponentName res = mServices.startServiceLocked(caller, service,
14305                    resolvedType, callingPid, callingUid, userId);
14306            Binder.restoreCallingIdentity(origId);
14307            return res;
14308        }
14309    }
14310
14311    ComponentName startServiceInPackage(int uid,
14312            Intent service, String resolvedType, int userId) {
14313        synchronized(this) {
14314            if (DEBUG_SERVICE)
14315                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14316            final long origId = Binder.clearCallingIdentity();
14317            ComponentName res = mServices.startServiceLocked(null, service,
14318                    resolvedType, -1, uid, userId);
14319            Binder.restoreCallingIdentity(origId);
14320            return res;
14321        }
14322    }
14323
14324    @Override
14325    public int stopService(IApplicationThread caller, Intent service,
14326            String resolvedType, int userId) {
14327        enforceNotIsolatedCaller("stopService");
14328        // Refuse possible leaked file descriptors
14329        if (service != null && service.hasFileDescriptors() == true) {
14330            throw new IllegalArgumentException("File descriptors passed in Intent");
14331        }
14332
14333        synchronized(this) {
14334            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14335        }
14336    }
14337
14338    @Override
14339    public IBinder peekService(Intent service, String resolvedType) {
14340        enforceNotIsolatedCaller("peekService");
14341        // Refuse possible leaked file descriptors
14342        if (service != null && service.hasFileDescriptors() == true) {
14343            throw new IllegalArgumentException("File descriptors passed in Intent");
14344        }
14345        synchronized(this) {
14346            return mServices.peekServiceLocked(service, resolvedType);
14347        }
14348    }
14349
14350    @Override
14351    public boolean stopServiceToken(ComponentName className, IBinder token,
14352            int startId) {
14353        synchronized(this) {
14354            return mServices.stopServiceTokenLocked(className, token, startId);
14355        }
14356    }
14357
14358    @Override
14359    public void setServiceForeground(ComponentName className, IBinder token,
14360            int id, Notification notification, boolean removeNotification) {
14361        synchronized(this) {
14362            mServices.setServiceForegroundLocked(className, token, id, notification,
14363                    removeNotification);
14364        }
14365    }
14366
14367    @Override
14368    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14369            boolean requireFull, String name, String callerPackage) {
14370        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14371                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14372    }
14373
14374    int unsafeConvertIncomingUser(int userId) {
14375        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14376                ? mCurrentUserId : userId;
14377    }
14378
14379    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14380            int allowMode, String name, String callerPackage) {
14381        final int callingUserId = UserHandle.getUserId(callingUid);
14382        if (callingUserId == userId) {
14383            return userId;
14384        }
14385
14386        // Note that we may be accessing mCurrentUserId outside of a lock...
14387        // shouldn't be a big deal, if this is being called outside
14388        // of a locked context there is intrinsically a race with
14389        // the value the caller will receive and someone else changing it.
14390        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14391        // we will switch to the calling user if access to the current user fails.
14392        int targetUserId = unsafeConvertIncomingUser(userId);
14393
14394        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14395            final boolean allow;
14396            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14397                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14398                // If the caller has this permission, they always pass go.  And collect $200.
14399                allow = true;
14400            } else if (allowMode == ALLOW_FULL_ONLY) {
14401                // We require full access, sucks to be you.
14402                allow = false;
14403            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14404                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14405                // If the caller does not have either permission, they are always doomed.
14406                allow = false;
14407            } else if (allowMode == ALLOW_NON_FULL) {
14408                // We are blanket allowing non-full access, you lucky caller!
14409                allow = true;
14410            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14411                // We may or may not allow this depending on whether the two users are
14412                // in the same profile.
14413                synchronized (mUserProfileGroupIdsSelfLocked) {
14414                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14415                            UserInfo.NO_PROFILE_GROUP_ID);
14416                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14417                            UserInfo.NO_PROFILE_GROUP_ID);
14418                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14419                            && callingProfile == targetProfile;
14420                }
14421            } else {
14422                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14423            }
14424            if (!allow) {
14425                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14426                    // In this case, they would like to just execute as their
14427                    // owner user instead of failing.
14428                    targetUserId = callingUserId;
14429                } else {
14430                    StringBuilder builder = new StringBuilder(128);
14431                    builder.append("Permission Denial: ");
14432                    builder.append(name);
14433                    if (callerPackage != null) {
14434                        builder.append(" from ");
14435                        builder.append(callerPackage);
14436                    }
14437                    builder.append(" asks to run as user ");
14438                    builder.append(userId);
14439                    builder.append(" but is calling from user ");
14440                    builder.append(UserHandle.getUserId(callingUid));
14441                    builder.append("; this requires ");
14442                    builder.append(INTERACT_ACROSS_USERS_FULL);
14443                    if (allowMode != ALLOW_FULL_ONLY) {
14444                        builder.append(" or ");
14445                        builder.append(INTERACT_ACROSS_USERS);
14446                    }
14447                    String msg = builder.toString();
14448                    Slog.w(TAG, msg);
14449                    throw new SecurityException(msg);
14450                }
14451            }
14452        }
14453        if (!allowAll && targetUserId < 0) {
14454            throw new IllegalArgumentException(
14455                    "Call does not support special user #" + targetUserId);
14456        }
14457        return targetUserId;
14458    }
14459
14460    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14461            String className, int flags) {
14462        boolean result = false;
14463        // For apps that don't have pre-defined UIDs, check for permission
14464        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14465            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14466                if (ActivityManager.checkUidPermission(
14467                        INTERACT_ACROSS_USERS,
14468                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14469                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14470                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14471                            + " requests FLAG_SINGLE_USER, but app does not hold "
14472                            + INTERACT_ACROSS_USERS;
14473                    Slog.w(TAG, msg);
14474                    throw new SecurityException(msg);
14475                }
14476                // Permission passed
14477                result = true;
14478            }
14479        } else if ("system".equals(componentProcessName)) {
14480            result = true;
14481        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14482                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14483            // Phone app is allowed to export singleuser providers.
14484            result = true;
14485        } else {
14486            // App with pre-defined UID, check if it's a persistent app
14487            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14488        }
14489        if (DEBUG_MU) {
14490            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14491                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14492        }
14493        return result;
14494    }
14495
14496    /**
14497     * Checks to see if the caller is in the same app as the singleton
14498     * component, or the component is in a special app. It allows special apps
14499     * to export singleton components but prevents exporting singleton
14500     * components for regular apps.
14501     */
14502    boolean isValidSingletonCall(int callingUid, int componentUid) {
14503        int componentAppId = UserHandle.getAppId(componentUid);
14504        return UserHandle.isSameApp(callingUid, componentUid)
14505                || componentAppId == Process.SYSTEM_UID
14506                || componentAppId == Process.PHONE_UID
14507                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14508                        == PackageManager.PERMISSION_GRANTED;
14509    }
14510
14511    public int bindService(IApplicationThread caller, IBinder token,
14512            Intent service, String resolvedType,
14513            IServiceConnection connection, int flags, int userId) {
14514        enforceNotIsolatedCaller("bindService");
14515        // Refuse possible leaked file descriptors
14516        if (service != null && service.hasFileDescriptors() == true) {
14517            throw new IllegalArgumentException("File descriptors passed in Intent");
14518        }
14519
14520        synchronized(this) {
14521            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14522                    connection, flags, userId);
14523        }
14524    }
14525
14526    public boolean unbindService(IServiceConnection connection) {
14527        synchronized (this) {
14528            return mServices.unbindServiceLocked(connection);
14529        }
14530    }
14531
14532    public void publishService(IBinder token, Intent intent, IBinder service) {
14533        // Refuse possible leaked file descriptors
14534        if (intent != null && intent.hasFileDescriptors() == true) {
14535            throw new IllegalArgumentException("File descriptors passed in Intent");
14536        }
14537
14538        synchronized(this) {
14539            if (!(token instanceof ServiceRecord)) {
14540                throw new IllegalArgumentException("Invalid service token");
14541            }
14542            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14543        }
14544    }
14545
14546    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14547        // Refuse possible leaked file descriptors
14548        if (intent != null && intent.hasFileDescriptors() == true) {
14549            throw new IllegalArgumentException("File descriptors passed in Intent");
14550        }
14551
14552        synchronized(this) {
14553            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14554        }
14555    }
14556
14557    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14558        synchronized(this) {
14559            if (!(token instanceof ServiceRecord)) {
14560                throw new IllegalArgumentException("Invalid service token");
14561            }
14562            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14563        }
14564    }
14565
14566    // =========================================================
14567    // BACKUP AND RESTORE
14568    // =========================================================
14569
14570    // Cause the target app to be launched if necessary and its backup agent
14571    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14572    // activity manager to announce its creation.
14573    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14574        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14575        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14576
14577        synchronized(this) {
14578            // !!! TODO: currently no check here that we're already bound
14579            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14580            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14581            synchronized (stats) {
14582                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14583            }
14584
14585            // Backup agent is now in use, its package can't be stopped.
14586            try {
14587                AppGlobals.getPackageManager().setPackageStoppedState(
14588                        app.packageName, false, UserHandle.getUserId(app.uid));
14589            } catch (RemoteException e) {
14590            } catch (IllegalArgumentException e) {
14591                Slog.w(TAG, "Failed trying to unstop package "
14592                        + app.packageName + ": " + e);
14593            }
14594
14595            BackupRecord r = new BackupRecord(ss, app, backupMode);
14596            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14597                    ? new ComponentName(app.packageName, app.backupAgentName)
14598                    : new ComponentName("android", "FullBackupAgent");
14599            // startProcessLocked() returns existing proc's record if it's already running
14600            ProcessRecord proc = startProcessLocked(app.processName, app,
14601                    false, 0, "backup", hostingName, false, false, false);
14602            if (proc == null) {
14603                Slog.e(TAG, "Unable to start backup agent process " + r);
14604                return false;
14605            }
14606
14607            r.app = proc;
14608            mBackupTarget = r;
14609            mBackupAppName = app.packageName;
14610
14611            // Try not to kill the process during backup
14612            updateOomAdjLocked(proc);
14613
14614            // If the process is already attached, schedule the creation of the backup agent now.
14615            // If it is not yet live, this will be done when it attaches to the framework.
14616            if (proc.thread != null) {
14617                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14618                try {
14619                    proc.thread.scheduleCreateBackupAgent(app,
14620                            compatibilityInfoForPackageLocked(app), backupMode);
14621                } catch (RemoteException e) {
14622                    // Will time out on the backup manager side
14623                }
14624            } else {
14625                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14626            }
14627            // Invariants: at this point, the target app process exists and the application
14628            // is either already running or in the process of coming up.  mBackupTarget and
14629            // mBackupAppName describe the app, so that when it binds back to the AM we
14630            // know that it's scheduled for a backup-agent operation.
14631        }
14632
14633        return true;
14634    }
14635
14636    @Override
14637    public void clearPendingBackup() {
14638        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14639        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14640
14641        synchronized (this) {
14642            mBackupTarget = null;
14643            mBackupAppName = null;
14644        }
14645    }
14646
14647    // A backup agent has just come up
14648    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14649        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14650                + " = " + agent);
14651
14652        synchronized(this) {
14653            if (!agentPackageName.equals(mBackupAppName)) {
14654                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14655                return;
14656            }
14657        }
14658
14659        long oldIdent = Binder.clearCallingIdentity();
14660        try {
14661            IBackupManager bm = IBackupManager.Stub.asInterface(
14662                    ServiceManager.getService(Context.BACKUP_SERVICE));
14663            bm.agentConnected(agentPackageName, agent);
14664        } catch (RemoteException e) {
14665            // can't happen; the backup manager service is local
14666        } catch (Exception e) {
14667            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14668            e.printStackTrace();
14669        } finally {
14670            Binder.restoreCallingIdentity(oldIdent);
14671        }
14672    }
14673
14674    // done with this agent
14675    public void unbindBackupAgent(ApplicationInfo appInfo) {
14676        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14677        if (appInfo == null) {
14678            Slog.w(TAG, "unbind backup agent for null app");
14679            return;
14680        }
14681
14682        synchronized(this) {
14683            try {
14684                if (mBackupAppName == null) {
14685                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14686                    return;
14687                }
14688
14689                if (!mBackupAppName.equals(appInfo.packageName)) {
14690                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14691                    return;
14692                }
14693
14694                // Not backing this app up any more; reset its OOM adjustment
14695                final ProcessRecord proc = mBackupTarget.app;
14696                updateOomAdjLocked(proc);
14697
14698                // If the app crashed during backup, 'thread' will be null here
14699                if (proc.thread != null) {
14700                    try {
14701                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14702                                compatibilityInfoForPackageLocked(appInfo));
14703                    } catch (Exception e) {
14704                        Slog.e(TAG, "Exception when unbinding backup agent:");
14705                        e.printStackTrace();
14706                    }
14707                }
14708            } finally {
14709                mBackupTarget = null;
14710                mBackupAppName = null;
14711            }
14712        }
14713    }
14714    // =========================================================
14715    // BROADCASTS
14716    // =========================================================
14717
14718    private final List getStickiesLocked(String action, IntentFilter filter,
14719            List cur, int userId) {
14720        final ContentResolver resolver = mContext.getContentResolver();
14721        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14722        if (stickies == null) {
14723            return cur;
14724        }
14725        final ArrayList<Intent> list = stickies.get(action);
14726        if (list == null) {
14727            return cur;
14728        }
14729        int N = list.size();
14730        for (int i=0; i<N; i++) {
14731            Intent intent = list.get(i);
14732            if (filter.match(resolver, intent, true, TAG) >= 0) {
14733                if (cur == null) {
14734                    cur = new ArrayList<Intent>();
14735                }
14736                cur.add(intent);
14737            }
14738        }
14739        return cur;
14740    }
14741
14742    boolean isPendingBroadcastProcessLocked(int pid) {
14743        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14744                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14745    }
14746
14747    void skipPendingBroadcastLocked(int pid) {
14748            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14749            for (BroadcastQueue queue : mBroadcastQueues) {
14750                queue.skipPendingBroadcastLocked(pid);
14751            }
14752    }
14753
14754    // The app just attached; send any pending broadcasts that it should receive
14755    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14756        boolean didSomething = false;
14757        for (BroadcastQueue queue : mBroadcastQueues) {
14758            didSomething |= queue.sendPendingBroadcastsLocked(app);
14759        }
14760        return didSomething;
14761    }
14762
14763    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14764            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14765        enforceNotIsolatedCaller("registerReceiver");
14766        int callingUid;
14767        int callingPid;
14768        synchronized(this) {
14769            ProcessRecord callerApp = null;
14770            if (caller != null) {
14771                callerApp = getRecordForAppLocked(caller);
14772                if (callerApp == null) {
14773                    throw new SecurityException(
14774                            "Unable to find app for caller " + caller
14775                            + " (pid=" + Binder.getCallingPid()
14776                            + ") when registering receiver " + receiver);
14777                }
14778                if (callerApp.info.uid != Process.SYSTEM_UID &&
14779                        !callerApp.pkgList.containsKey(callerPackage) &&
14780                        !"android".equals(callerPackage)) {
14781                    throw new SecurityException("Given caller package " + callerPackage
14782                            + " is not running in process " + callerApp);
14783                }
14784                callingUid = callerApp.info.uid;
14785                callingPid = callerApp.pid;
14786            } else {
14787                callerPackage = null;
14788                callingUid = Binder.getCallingUid();
14789                callingPid = Binder.getCallingPid();
14790            }
14791
14792            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14793                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14794
14795            List allSticky = null;
14796
14797            // Look for any matching sticky broadcasts...
14798            Iterator actions = filter.actionsIterator();
14799            if (actions != null) {
14800                while (actions.hasNext()) {
14801                    String action = (String)actions.next();
14802                    allSticky = getStickiesLocked(action, filter, allSticky,
14803                            UserHandle.USER_ALL);
14804                    allSticky = getStickiesLocked(action, filter, allSticky,
14805                            UserHandle.getUserId(callingUid));
14806                }
14807            } else {
14808                allSticky = getStickiesLocked(null, filter, allSticky,
14809                        UserHandle.USER_ALL);
14810                allSticky = getStickiesLocked(null, filter, allSticky,
14811                        UserHandle.getUserId(callingUid));
14812            }
14813
14814            // The first sticky in the list is returned directly back to
14815            // the client.
14816            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14817
14818            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14819                    + ": " + sticky);
14820
14821            if (receiver == null) {
14822                return sticky;
14823            }
14824
14825            ReceiverList rl
14826                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14827            if (rl == null) {
14828                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14829                        userId, receiver);
14830                if (rl.app != null) {
14831                    rl.app.receivers.add(rl);
14832                } else {
14833                    try {
14834                        receiver.asBinder().linkToDeath(rl, 0);
14835                    } catch (RemoteException e) {
14836                        return sticky;
14837                    }
14838                    rl.linkedToDeath = true;
14839                }
14840                mRegisteredReceivers.put(receiver.asBinder(), rl);
14841            } else if (rl.uid != callingUid) {
14842                throw new IllegalArgumentException(
14843                        "Receiver requested to register for uid " + callingUid
14844                        + " was previously registered for uid " + rl.uid);
14845            } else if (rl.pid != callingPid) {
14846                throw new IllegalArgumentException(
14847                        "Receiver requested to register for pid " + callingPid
14848                        + " was previously registered for pid " + rl.pid);
14849            } else if (rl.userId != userId) {
14850                throw new IllegalArgumentException(
14851                        "Receiver requested to register for user " + userId
14852                        + " was previously registered for user " + rl.userId);
14853            }
14854            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14855                    permission, callingUid, userId);
14856            rl.add(bf);
14857            if (!bf.debugCheck()) {
14858                Slog.w(TAG, "==> For Dynamic broadast");
14859            }
14860            mReceiverResolver.addFilter(bf);
14861
14862            // Enqueue broadcasts for all existing stickies that match
14863            // this filter.
14864            if (allSticky != null) {
14865                ArrayList receivers = new ArrayList();
14866                receivers.add(bf);
14867
14868                int N = allSticky.size();
14869                for (int i=0; i<N; i++) {
14870                    Intent intent = (Intent)allSticky.get(i);
14871                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14872                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14873                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14874                            null, null, false, true, true, -1);
14875                    queue.enqueueParallelBroadcastLocked(r);
14876                    queue.scheduleBroadcastsLocked();
14877                }
14878            }
14879
14880            return sticky;
14881        }
14882    }
14883
14884    public void unregisterReceiver(IIntentReceiver receiver) {
14885        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14886
14887        final long origId = Binder.clearCallingIdentity();
14888        try {
14889            boolean doTrim = false;
14890
14891            synchronized(this) {
14892                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14893                if (rl != null) {
14894                    if (rl.curBroadcast != null) {
14895                        BroadcastRecord r = rl.curBroadcast;
14896                        final boolean doNext = finishReceiverLocked(
14897                                receiver.asBinder(), r.resultCode, r.resultData,
14898                                r.resultExtras, r.resultAbort);
14899                        if (doNext) {
14900                            doTrim = true;
14901                            r.queue.processNextBroadcast(false);
14902                        }
14903                    }
14904
14905                    if (rl.app != null) {
14906                        rl.app.receivers.remove(rl);
14907                    }
14908                    removeReceiverLocked(rl);
14909                    if (rl.linkedToDeath) {
14910                        rl.linkedToDeath = false;
14911                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14912                    }
14913                }
14914            }
14915
14916            // If we actually concluded any broadcasts, we might now be able
14917            // to trim the recipients' apps from our working set
14918            if (doTrim) {
14919                trimApplications();
14920                return;
14921            }
14922
14923        } finally {
14924            Binder.restoreCallingIdentity(origId);
14925        }
14926    }
14927
14928    void removeReceiverLocked(ReceiverList rl) {
14929        mRegisteredReceivers.remove(rl.receiver.asBinder());
14930        int N = rl.size();
14931        for (int i=0; i<N; i++) {
14932            mReceiverResolver.removeFilter(rl.get(i));
14933        }
14934    }
14935
14936    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14937        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14938            ProcessRecord r = mLruProcesses.get(i);
14939            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14940                try {
14941                    r.thread.dispatchPackageBroadcast(cmd, packages);
14942                } catch (RemoteException ex) {
14943                }
14944            }
14945        }
14946    }
14947
14948    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14949            int[] users) {
14950        List<ResolveInfo> receivers = null;
14951        try {
14952            HashSet<ComponentName> singleUserReceivers = null;
14953            boolean scannedFirstReceivers = false;
14954            for (int user : users) {
14955                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14956                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14957                if (user != 0 && newReceivers != null) {
14958                    // If this is not the primary user, we need to check for
14959                    // any receivers that should be filtered out.
14960                    for (int i=0; i<newReceivers.size(); i++) {
14961                        ResolveInfo ri = newReceivers.get(i);
14962                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14963                            newReceivers.remove(i);
14964                            i--;
14965                        }
14966                    }
14967                }
14968                if (newReceivers != null && newReceivers.size() == 0) {
14969                    newReceivers = null;
14970                }
14971                if (receivers == null) {
14972                    receivers = newReceivers;
14973                } else if (newReceivers != null) {
14974                    // We need to concatenate the additional receivers
14975                    // found with what we have do far.  This would be easy,
14976                    // but we also need to de-dup any receivers that are
14977                    // singleUser.
14978                    if (!scannedFirstReceivers) {
14979                        // Collect any single user receivers we had already retrieved.
14980                        scannedFirstReceivers = true;
14981                        for (int i=0; i<receivers.size(); i++) {
14982                            ResolveInfo ri = receivers.get(i);
14983                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14984                                ComponentName cn = new ComponentName(
14985                                        ri.activityInfo.packageName, ri.activityInfo.name);
14986                                if (singleUserReceivers == null) {
14987                                    singleUserReceivers = new HashSet<ComponentName>();
14988                                }
14989                                singleUserReceivers.add(cn);
14990                            }
14991                        }
14992                    }
14993                    // Add the new results to the existing results, tracking
14994                    // and de-dupping single user receivers.
14995                    for (int i=0; i<newReceivers.size(); i++) {
14996                        ResolveInfo ri = newReceivers.get(i);
14997                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14998                            ComponentName cn = new ComponentName(
14999                                    ri.activityInfo.packageName, ri.activityInfo.name);
15000                            if (singleUserReceivers == null) {
15001                                singleUserReceivers = new HashSet<ComponentName>();
15002                            }
15003                            if (!singleUserReceivers.contains(cn)) {
15004                                singleUserReceivers.add(cn);
15005                                receivers.add(ri);
15006                            }
15007                        } else {
15008                            receivers.add(ri);
15009                        }
15010                    }
15011                }
15012            }
15013        } catch (RemoteException ex) {
15014            // pm is in same process, this will never happen.
15015        }
15016        return receivers;
15017    }
15018
15019    private final int broadcastIntentLocked(ProcessRecord callerApp,
15020            String callerPackage, Intent intent, String resolvedType,
15021            IIntentReceiver resultTo, int resultCode, String resultData,
15022            Bundle map, String requiredPermission, int appOp,
15023            boolean ordered, boolean sticky, int callingPid, int callingUid,
15024            int userId) {
15025        intent = new Intent(intent);
15026
15027        // By default broadcasts do not go to stopped apps.
15028        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15029
15030        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15031            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15032            + " ordered=" + ordered + " userid=" + userId);
15033        if ((resultTo != null) && !ordered) {
15034            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15035        }
15036
15037        userId = handleIncomingUser(callingPid, callingUid, userId,
15038                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15039
15040        // Make sure that the user who is receiving this broadcast is started.
15041        // If not, we will just skip it.
15042
15043
15044        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15045            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15046                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15047                Slog.w(TAG, "Skipping broadcast of " + intent
15048                        + ": user " + userId + " is stopped");
15049                return ActivityManager.BROADCAST_SUCCESS;
15050            }
15051        }
15052
15053        /*
15054         * Prevent non-system code (defined here to be non-persistent
15055         * processes) from sending protected broadcasts.
15056         */
15057        int callingAppId = UserHandle.getAppId(callingUid);
15058        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15059            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15060            || callingAppId == Process.NFC_UID || callingUid == 0) {
15061            // Always okay.
15062        } else if (callerApp == null || !callerApp.persistent) {
15063            try {
15064                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15065                        intent.getAction())) {
15066                    String msg = "Permission Denial: not allowed to send broadcast "
15067                            + intent.getAction() + " from pid="
15068                            + callingPid + ", uid=" + callingUid;
15069                    Slog.w(TAG, msg);
15070                    throw new SecurityException(msg);
15071                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15072                    // Special case for compatibility: we don't want apps to send this,
15073                    // but historically it has not been protected and apps may be using it
15074                    // to poke their own app widget.  So, instead of making it protected,
15075                    // just limit it to the caller.
15076                    if (callerApp == null) {
15077                        String msg = "Permission Denial: not allowed to send broadcast "
15078                                + intent.getAction() + " from unknown caller.";
15079                        Slog.w(TAG, msg);
15080                        throw new SecurityException(msg);
15081                    } else if (intent.getComponent() != null) {
15082                        // They are good enough to send to an explicit component...  verify
15083                        // it is being sent to the calling app.
15084                        if (!intent.getComponent().getPackageName().equals(
15085                                callerApp.info.packageName)) {
15086                            String msg = "Permission Denial: not allowed to send broadcast "
15087                                    + intent.getAction() + " to "
15088                                    + intent.getComponent().getPackageName() + " from "
15089                                    + callerApp.info.packageName;
15090                            Slog.w(TAG, msg);
15091                            throw new SecurityException(msg);
15092                        }
15093                    } else {
15094                        // Limit broadcast to their own package.
15095                        intent.setPackage(callerApp.info.packageName);
15096                    }
15097                }
15098            } catch (RemoteException e) {
15099                Slog.w(TAG, "Remote exception", e);
15100                return ActivityManager.BROADCAST_SUCCESS;
15101            }
15102        }
15103
15104        // Handle special intents: if this broadcast is from the package
15105        // manager about a package being removed, we need to remove all of
15106        // its activities from the history stack.
15107        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15108                intent.getAction());
15109        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15110                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15111                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15112                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15113                || uidRemoved) {
15114            if (checkComponentPermission(
15115                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15116                    callingPid, callingUid, -1, true)
15117                    == PackageManager.PERMISSION_GRANTED) {
15118                if (uidRemoved) {
15119                    final Bundle intentExtras = intent.getExtras();
15120                    final int uid = intentExtras != null
15121                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15122                    if (uid >= 0) {
15123                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15124                        synchronized (bs) {
15125                            bs.removeUidStatsLocked(uid);
15126                        }
15127                        mAppOpsService.uidRemoved(uid);
15128                    }
15129                } else {
15130                    // If resources are unavailable just force stop all
15131                    // those packages and flush the attribute cache as well.
15132                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15133                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15134                        if (list != null && (list.length > 0)) {
15135                            for (String pkg : list) {
15136                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15137                                        "storage unmount");
15138                            }
15139                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15140                            sendPackageBroadcastLocked(
15141                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15142                        }
15143                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15144                            intent.getAction())) {
15145                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15146                    } else {
15147                        Uri data = intent.getData();
15148                        String ssp;
15149                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15150                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15151                                    intent.getAction());
15152                            boolean fullUninstall = removed &&
15153                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15154                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15155                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15156                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15157                                        false, fullUninstall, userId,
15158                                        removed ? "pkg removed" : "pkg changed");
15159                            }
15160                            if (removed) {
15161                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15162                                        new String[] {ssp}, userId);
15163                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15164                                    mAppOpsService.packageRemoved(
15165                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15166
15167                                    // Remove all permissions granted from/to this package
15168                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15169                                }
15170                            }
15171                        }
15172                    }
15173                }
15174            } else {
15175                String msg = "Permission Denial: " + intent.getAction()
15176                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15177                        + ", uid=" + callingUid + ")"
15178                        + " requires "
15179                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15180                Slog.w(TAG, msg);
15181                throw new SecurityException(msg);
15182            }
15183
15184        // Special case for adding a package: by default turn on compatibility
15185        // mode.
15186        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15187            Uri data = intent.getData();
15188            String ssp;
15189            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15190                mCompatModePackages.handlePackageAddedLocked(ssp,
15191                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15192            }
15193        }
15194
15195        /*
15196         * If this is the time zone changed action, queue up a message that will reset the timezone
15197         * of all currently running processes. This message will get queued up before the broadcast
15198         * happens.
15199         */
15200        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15201            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15202        }
15203
15204        /*
15205         * If the user set the time, let all running processes know.
15206         */
15207        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15208            final int is24Hour = intent.getBooleanExtra(
15209                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15210            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15211        }
15212
15213        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15214            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15215        }
15216
15217        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15218            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15219            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15220        }
15221
15222        // Add to the sticky list if requested.
15223        if (sticky) {
15224            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15225                    callingPid, callingUid)
15226                    != PackageManager.PERMISSION_GRANTED) {
15227                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15228                        + callingPid + ", uid=" + callingUid
15229                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15230                Slog.w(TAG, msg);
15231                throw new SecurityException(msg);
15232            }
15233            if (requiredPermission != null) {
15234                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15235                        + " and enforce permission " + requiredPermission);
15236                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15237            }
15238            if (intent.getComponent() != null) {
15239                throw new SecurityException(
15240                        "Sticky broadcasts can't target a specific component");
15241            }
15242            // We use userId directly here, since the "all" target is maintained
15243            // as a separate set of sticky broadcasts.
15244            if (userId != UserHandle.USER_ALL) {
15245                // But first, if this is not a broadcast to all users, then
15246                // make sure it doesn't conflict with an existing broadcast to
15247                // all users.
15248                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15249                        UserHandle.USER_ALL);
15250                if (stickies != null) {
15251                    ArrayList<Intent> list = stickies.get(intent.getAction());
15252                    if (list != null) {
15253                        int N = list.size();
15254                        int i;
15255                        for (i=0; i<N; i++) {
15256                            if (intent.filterEquals(list.get(i))) {
15257                                throw new IllegalArgumentException(
15258                                        "Sticky broadcast " + intent + " for user "
15259                                        + userId + " conflicts with existing global broadcast");
15260                            }
15261                        }
15262                    }
15263                }
15264            }
15265            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15266            if (stickies == null) {
15267                stickies = new ArrayMap<String, ArrayList<Intent>>();
15268                mStickyBroadcasts.put(userId, stickies);
15269            }
15270            ArrayList<Intent> list = stickies.get(intent.getAction());
15271            if (list == null) {
15272                list = new ArrayList<Intent>();
15273                stickies.put(intent.getAction(), list);
15274            }
15275            int N = list.size();
15276            int i;
15277            for (i=0; i<N; i++) {
15278                if (intent.filterEquals(list.get(i))) {
15279                    // This sticky already exists, replace it.
15280                    list.set(i, new Intent(intent));
15281                    break;
15282                }
15283            }
15284            if (i >= N) {
15285                list.add(new Intent(intent));
15286            }
15287        }
15288
15289        int[] users;
15290        if (userId == UserHandle.USER_ALL) {
15291            // Caller wants broadcast to go to all started users.
15292            users = mStartedUserArray;
15293        } else {
15294            // Caller wants broadcast to go to one specific user.
15295            users = new int[] {userId};
15296        }
15297
15298        // Figure out who all will receive this broadcast.
15299        List receivers = null;
15300        List<BroadcastFilter> registeredReceivers = null;
15301        // Need to resolve the intent to interested receivers...
15302        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15303                 == 0) {
15304            receivers = collectReceiverComponents(intent, resolvedType, users);
15305        }
15306        if (intent.getComponent() == null) {
15307            registeredReceivers = mReceiverResolver.queryIntent(intent,
15308                    resolvedType, false, userId);
15309        }
15310
15311        final boolean replacePending =
15312                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15313
15314        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15315                + " replacePending=" + replacePending);
15316
15317        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15318        if (!ordered && NR > 0) {
15319            // If we are not serializing this broadcast, then send the
15320            // registered receivers separately so they don't wait for the
15321            // components to be launched.
15322            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15323            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15324                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15325                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15326                    ordered, sticky, false, userId);
15327            if (DEBUG_BROADCAST) Slog.v(
15328                    TAG, "Enqueueing parallel broadcast " + r);
15329            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15330            if (!replaced) {
15331                queue.enqueueParallelBroadcastLocked(r);
15332                queue.scheduleBroadcastsLocked();
15333            }
15334            registeredReceivers = null;
15335            NR = 0;
15336        }
15337
15338        // Merge into one list.
15339        int ir = 0;
15340        if (receivers != null) {
15341            // A special case for PACKAGE_ADDED: do not allow the package
15342            // being added to see this broadcast.  This prevents them from
15343            // using this as a back door to get run as soon as they are
15344            // installed.  Maybe in the future we want to have a special install
15345            // broadcast or such for apps, but we'd like to deliberately make
15346            // this decision.
15347            String skipPackages[] = null;
15348            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15349                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15350                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15351                Uri data = intent.getData();
15352                if (data != null) {
15353                    String pkgName = data.getSchemeSpecificPart();
15354                    if (pkgName != null) {
15355                        skipPackages = new String[] { pkgName };
15356                    }
15357                }
15358            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15359                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15360            }
15361            if (skipPackages != null && (skipPackages.length > 0)) {
15362                for (String skipPackage : skipPackages) {
15363                    if (skipPackage != null) {
15364                        int NT = receivers.size();
15365                        for (int it=0; it<NT; it++) {
15366                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15367                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15368                                receivers.remove(it);
15369                                it--;
15370                                NT--;
15371                            }
15372                        }
15373                    }
15374                }
15375            }
15376
15377            int NT = receivers != null ? receivers.size() : 0;
15378            int it = 0;
15379            ResolveInfo curt = null;
15380            BroadcastFilter curr = null;
15381            while (it < NT && ir < NR) {
15382                if (curt == null) {
15383                    curt = (ResolveInfo)receivers.get(it);
15384                }
15385                if (curr == null) {
15386                    curr = registeredReceivers.get(ir);
15387                }
15388                if (curr.getPriority() >= curt.priority) {
15389                    // Insert this broadcast record into the final list.
15390                    receivers.add(it, curr);
15391                    ir++;
15392                    curr = null;
15393                    it++;
15394                    NT++;
15395                } else {
15396                    // Skip to the next ResolveInfo in the final list.
15397                    it++;
15398                    curt = null;
15399                }
15400            }
15401        }
15402        while (ir < NR) {
15403            if (receivers == null) {
15404                receivers = new ArrayList();
15405            }
15406            receivers.add(registeredReceivers.get(ir));
15407            ir++;
15408        }
15409
15410        if ((receivers != null && receivers.size() > 0)
15411                || resultTo != null) {
15412            BroadcastQueue queue = broadcastQueueForIntent(intent);
15413            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15414                    callerPackage, callingPid, callingUid, resolvedType,
15415                    requiredPermission, appOp, receivers, resultTo, resultCode,
15416                    resultData, map, ordered, sticky, false, userId);
15417            if (DEBUG_BROADCAST) Slog.v(
15418                    TAG, "Enqueueing ordered broadcast " + r
15419                    + ": prev had " + queue.mOrderedBroadcasts.size());
15420            if (DEBUG_BROADCAST) {
15421                int seq = r.intent.getIntExtra("seq", -1);
15422                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15423            }
15424            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15425            if (!replaced) {
15426                queue.enqueueOrderedBroadcastLocked(r);
15427                queue.scheduleBroadcastsLocked();
15428            }
15429        }
15430
15431        return ActivityManager.BROADCAST_SUCCESS;
15432    }
15433
15434    final Intent verifyBroadcastLocked(Intent intent) {
15435        // Refuse possible leaked file descriptors
15436        if (intent != null && intent.hasFileDescriptors() == true) {
15437            throw new IllegalArgumentException("File descriptors passed in Intent");
15438        }
15439
15440        int flags = intent.getFlags();
15441
15442        if (!mProcessesReady) {
15443            // if the caller really truly claims to know what they're doing, go
15444            // ahead and allow the broadcast without launching any receivers
15445            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15446                intent = new Intent(intent);
15447                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15448            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15449                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15450                        + " before boot completion");
15451                throw new IllegalStateException("Cannot broadcast before boot completed");
15452            }
15453        }
15454
15455        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15456            throw new IllegalArgumentException(
15457                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15458        }
15459
15460        return intent;
15461    }
15462
15463    public final int broadcastIntent(IApplicationThread caller,
15464            Intent intent, String resolvedType, IIntentReceiver resultTo,
15465            int resultCode, String resultData, Bundle map,
15466            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15467        enforceNotIsolatedCaller("broadcastIntent");
15468        synchronized(this) {
15469            intent = verifyBroadcastLocked(intent);
15470
15471            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15472            final int callingPid = Binder.getCallingPid();
15473            final int callingUid = Binder.getCallingUid();
15474            final long origId = Binder.clearCallingIdentity();
15475            int res = broadcastIntentLocked(callerApp,
15476                    callerApp != null ? callerApp.info.packageName : null,
15477                    intent, resolvedType, resultTo,
15478                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15479                    callingPid, callingUid, userId);
15480            Binder.restoreCallingIdentity(origId);
15481            return res;
15482        }
15483    }
15484
15485    int broadcastIntentInPackage(String packageName, int uid,
15486            Intent intent, String resolvedType, IIntentReceiver resultTo,
15487            int resultCode, String resultData, Bundle map,
15488            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15489        synchronized(this) {
15490            intent = verifyBroadcastLocked(intent);
15491
15492            final long origId = Binder.clearCallingIdentity();
15493            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15494                    resultTo, resultCode, resultData, map, requiredPermission,
15495                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15496            Binder.restoreCallingIdentity(origId);
15497            return res;
15498        }
15499    }
15500
15501    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15502        // Refuse possible leaked file descriptors
15503        if (intent != null && intent.hasFileDescriptors() == true) {
15504            throw new IllegalArgumentException("File descriptors passed in Intent");
15505        }
15506
15507        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15508                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15509
15510        synchronized(this) {
15511            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15512                    != PackageManager.PERMISSION_GRANTED) {
15513                String msg = "Permission Denial: unbroadcastIntent() from pid="
15514                        + Binder.getCallingPid()
15515                        + ", uid=" + Binder.getCallingUid()
15516                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15517                Slog.w(TAG, msg);
15518                throw new SecurityException(msg);
15519            }
15520            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15521            if (stickies != null) {
15522                ArrayList<Intent> list = stickies.get(intent.getAction());
15523                if (list != null) {
15524                    int N = list.size();
15525                    int i;
15526                    for (i=0; i<N; i++) {
15527                        if (intent.filterEquals(list.get(i))) {
15528                            list.remove(i);
15529                            break;
15530                        }
15531                    }
15532                    if (list.size() <= 0) {
15533                        stickies.remove(intent.getAction());
15534                    }
15535                }
15536                if (stickies.size() <= 0) {
15537                    mStickyBroadcasts.remove(userId);
15538                }
15539            }
15540        }
15541    }
15542
15543    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15544            String resultData, Bundle resultExtras, boolean resultAbort) {
15545        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15546        if (r == null) {
15547            Slog.w(TAG, "finishReceiver called but not found on queue");
15548            return false;
15549        }
15550
15551        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15552    }
15553
15554    void backgroundServicesFinishedLocked(int userId) {
15555        for (BroadcastQueue queue : mBroadcastQueues) {
15556            queue.backgroundServicesFinishedLocked(userId);
15557        }
15558    }
15559
15560    public void finishReceiver(IBinder who, int resultCode, String resultData,
15561            Bundle resultExtras, boolean resultAbort) {
15562        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15563
15564        // Refuse possible leaked file descriptors
15565        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15566            throw new IllegalArgumentException("File descriptors passed in Bundle");
15567        }
15568
15569        final long origId = Binder.clearCallingIdentity();
15570        try {
15571            boolean doNext = false;
15572            BroadcastRecord r;
15573
15574            synchronized(this) {
15575                r = broadcastRecordForReceiverLocked(who);
15576                if (r != null) {
15577                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15578                        resultData, resultExtras, resultAbort, true);
15579                }
15580            }
15581
15582            if (doNext) {
15583                r.queue.processNextBroadcast(false);
15584            }
15585            trimApplications();
15586        } finally {
15587            Binder.restoreCallingIdentity(origId);
15588        }
15589    }
15590
15591    // =========================================================
15592    // INSTRUMENTATION
15593    // =========================================================
15594
15595    public boolean startInstrumentation(ComponentName className,
15596            String profileFile, int flags, Bundle arguments,
15597            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15598            int userId, String abiOverride) {
15599        enforceNotIsolatedCaller("startInstrumentation");
15600        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15601                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15602        // Refuse possible leaked file descriptors
15603        if (arguments != null && arguments.hasFileDescriptors()) {
15604            throw new IllegalArgumentException("File descriptors passed in Bundle");
15605        }
15606
15607        synchronized(this) {
15608            InstrumentationInfo ii = null;
15609            ApplicationInfo ai = null;
15610            try {
15611                ii = mContext.getPackageManager().getInstrumentationInfo(
15612                    className, STOCK_PM_FLAGS);
15613                ai = AppGlobals.getPackageManager().getApplicationInfo(
15614                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15615            } catch (PackageManager.NameNotFoundException e) {
15616            } catch (RemoteException e) {
15617            }
15618            if (ii == null) {
15619                reportStartInstrumentationFailure(watcher, className,
15620                        "Unable to find instrumentation info for: " + className);
15621                return false;
15622            }
15623            if (ai == null) {
15624                reportStartInstrumentationFailure(watcher, className,
15625                        "Unable to find instrumentation target package: " + ii.targetPackage);
15626                return false;
15627            }
15628
15629            int match = mContext.getPackageManager().checkSignatures(
15630                    ii.targetPackage, ii.packageName);
15631            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15632                String msg = "Permission Denial: starting instrumentation "
15633                        + className + " from pid="
15634                        + Binder.getCallingPid()
15635                        + ", uid=" + Binder.getCallingPid()
15636                        + " not allowed because package " + ii.packageName
15637                        + " does not have a signature matching the target "
15638                        + ii.targetPackage;
15639                reportStartInstrumentationFailure(watcher, className, msg);
15640                throw new SecurityException(msg);
15641            }
15642
15643            final long origId = Binder.clearCallingIdentity();
15644            // Instrumentation can kill and relaunch even persistent processes
15645            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15646                    "start instr");
15647            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15648            app.instrumentationClass = className;
15649            app.instrumentationInfo = ai;
15650            app.instrumentationProfileFile = profileFile;
15651            app.instrumentationArguments = arguments;
15652            app.instrumentationWatcher = watcher;
15653            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15654            app.instrumentationResultClass = className;
15655            Binder.restoreCallingIdentity(origId);
15656        }
15657
15658        return true;
15659    }
15660
15661    /**
15662     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15663     * error to the logs, but if somebody is watching, send the report there too.  This enables
15664     * the "am" command to report errors with more information.
15665     *
15666     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15667     * @param cn The component name of the instrumentation.
15668     * @param report The error report.
15669     */
15670    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15671            ComponentName cn, String report) {
15672        Slog.w(TAG, report);
15673        try {
15674            if (watcher != null) {
15675                Bundle results = new Bundle();
15676                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15677                results.putString("Error", report);
15678                watcher.instrumentationStatus(cn, -1, results);
15679            }
15680        } catch (RemoteException e) {
15681            Slog.w(TAG, e);
15682        }
15683    }
15684
15685    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15686        if (app.instrumentationWatcher != null) {
15687            try {
15688                // NOTE:  IInstrumentationWatcher *must* be oneway here
15689                app.instrumentationWatcher.instrumentationFinished(
15690                    app.instrumentationClass,
15691                    resultCode,
15692                    results);
15693            } catch (RemoteException e) {
15694            }
15695        }
15696        if (app.instrumentationUiAutomationConnection != null) {
15697            try {
15698                app.instrumentationUiAutomationConnection.shutdown();
15699            } catch (RemoteException re) {
15700                /* ignore */
15701            }
15702            // Only a UiAutomation can set this flag and now that
15703            // it is finished we make sure it is reset to its default.
15704            mUserIsMonkey = false;
15705        }
15706        app.instrumentationWatcher = null;
15707        app.instrumentationUiAutomationConnection = null;
15708        app.instrumentationClass = null;
15709        app.instrumentationInfo = null;
15710        app.instrumentationProfileFile = null;
15711        app.instrumentationArguments = null;
15712
15713        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15714                "finished inst");
15715    }
15716
15717    public void finishInstrumentation(IApplicationThread target,
15718            int resultCode, Bundle results) {
15719        int userId = UserHandle.getCallingUserId();
15720        // Refuse possible leaked file descriptors
15721        if (results != null && results.hasFileDescriptors()) {
15722            throw new IllegalArgumentException("File descriptors passed in Intent");
15723        }
15724
15725        synchronized(this) {
15726            ProcessRecord app = getRecordForAppLocked(target);
15727            if (app == null) {
15728                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15729                return;
15730            }
15731            final long origId = Binder.clearCallingIdentity();
15732            finishInstrumentationLocked(app, resultCode, results);
15733            Binder.restoreCallingIdentity(origId);
15734        }
15735    }
15736
15737    // =========================================================
15738    // CONFIGURATION
15739    // =========================================================
15740
15741    public ConfigurationInfo getDeviceConfigurationInfo() {
15742        ConfigurationInfo config = new ConfigurationInfo();
15743        synchronized (this) {
15744            config.reqTouchScreen = mConfiguration.touchscreen;
15745            config.reqKeyboardType = mConfiguration.keyboard;
15746            config.reqNavigation = mConfiguration.navigation;
15747            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15748                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15749                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15750            }
15751            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15752                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15753                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15754            }
15755            config.reqGlEsVersion = GL_ES_VERSION;
15756        }
15757        return config;
15758    }
15759
15760    ActivityStack getFocusedStack() {
15761        return mStackSupervisor.getFocusedStack();
15762    }
15763
15764    public Configuration getConfiguration() {
15765        Configuration ci;
15766        synchronized(this) {
15767            ci = new Configuration(mConfiguration);
15768        }
15769        return ci;
15770    }
15771
15772    public void updatePersistentConfiguration(Configuration values) {
15773        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15774                "updateConfiguration()");
15775        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15776                "updateConfiguration()");
15777        if (values == null) {
15778            throw new NullPointerException("Configuration must not be null");
15779        }
15780
15781        synchronized(this) {
15782            final long origId = Binder.clearCallingIdentity();
15783            updateConfigurationLocked(values, null, true, false);
15784            Binder.restoreCallingIdentity(origId);
15785        }
15786    }
15787
15788    public void updateConfiguration(Configuration values) {
15789        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15790                "updateConfiguration()");
15791
15792        synchronized(this) {
15793            if (values == null && mWindowManager != null) {
15794                // sentinel: fetch the current configuration from the window manager
15795                values = mWindowManager.computeNewConfiguration();
15796            }
15797
15798            if (mWindowManager != null) {
15799                mProcessList.applyDisplaySize(mWindowManager);
15800            }
15801
15802            final long origId = Binder.clearCallingIdentity();
15803            if (values != null) {
15804                Settings.System.clearConfiguration(values);
15805            }
15806            updateConfigurationLocked(values, null, false, false);
15807            Binder.restoreCallingIdentity(origId);
15808        }
15809    }
15810
15811    /**
15812     * Do either or both things: (1) change the current configuration, and (2)
15813     * make sure the given activity is running with the (now) current
15814     * configuration.  Returns true if the activity has been left running, or
15815     * false if <var>starting</var> is being destroyed to match the new
15816     * configuration.
15817     * @param persistent TODO
15818     */
15819    boolean updateConfigurationLocked(Configuration values,
15820            ActivityRecord starting, boolean persistent, boolean initLocale) {
15821        int changes = 0;
15822
15823        if (values != null) {
15824            Configuration newConfig = new Configuration(mConfiguration);
15825            changes = newConfig.updateFrom(values);
15826            if (changes != 0) {
15827                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15828                    Slog.i(TAG, "Updating configuration to: " + values);
15829                }
15830
15831                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15832
15833                if (values.locale != null && !initLocale) {
15834                    saveLocaleLocked(values.locale,
15835                                     !values.locale.equals(mConfiguration.locale),
15836                                     values.userSetLocale);
15837                }
15838
15839                mConfigurationSeq++;
15840                if (mConfigurationSeq <= 0) {
15841                    mConfigurationSeq = 1;
15842                }
15843                newConfig.seq = mConfigurationSeq;
15844                mConfiguration = newConfig;
15845                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15846                //mUsageStatsService.noteStartConfig(newConfig);
15847
15848                final Configuration configCopy = new Configuration(mConfiguration);
15849
15850                // TODO: If our config changes, should we auto dismiss any currently
15851                // showing dialogs?
15852                mShowDialogs = shouldShowDialogs(newConfig);
15853
15854                AttributeCache ac = AttributeCache.instance();
15855                if (ac != null) {
15856                    ac.updateConfiguration(configCopy);
15857                }
15858
15859                // Make sure all resources in our process are updated
15860                // right now, so that anyone who is going to retrieve
15861                // resource values after we return will be sure to get
15862                // the new ones.  This is especially important during
15863                // boot, where the first config change needs to guarantee
15864                // all resources have that config before following boot
15865                // code is executed.
15866                mSystemThread.applyConfigurationToResources(configCopy);
15867
15868                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15869                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15870                    msg.obj = new Configuration(configCopy);
15871                    mHandler.sendMessage(msg);
15872                }
15873
15874                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15875                    ProcessRecord app = mLruProcesses.get(i);
15876                    try {
15877                        if (app.thread != null) {
15878                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15879                                    + app.processName + " new config " + mConfiguration);
15880                            app.thread.scheduleConfigurationChanged(configCopy);
15881                        }
15882                    } catch (Exception e) {
15883                    }
15884                }
15885                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15886                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15887                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15888                        | Intent.FLAG_RECEIVER_FOREGROUND);
15889                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15890                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15891                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15892                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15893                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15894                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15895                    broadcastIntentLocked(null, null, intent,
15896                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15897                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15898                }
15899            }
15900        }
15901
15902        boolean kept = true;
15903        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15904        // mainStack is null during startup.
15905        if (mainStack != null) {
15906            if (changes != 0 && starting == null) {
15907                // If the configuration changed, and the caller is not already
15908                // in the process of starting an activity, then find the top
15909                // activity to check if its configuration needs to change.
15910                starting = mainStack.topRunningActivityLocked(null);
15911            }
15912
15913            if (starting != null) {
15914                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15915                // And we need to make sure at this point that all other activities
15916                // are made visible with the correct configuration.
15917                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15918            }
15919        }
15920
15921        if (values != null && mWindowManager != null) {
15922            mWindowManager.setNewConfiguration(mConfiguration);
15923        }
15924
15925        return kept;
15926    }
15927
15928    /**
15929     * Decide based on the configuration whether we should shouw the ANR,
15930     * crash, etc dialogs.  The idea is that if there is no affordnace to
15931     * press the on-screen buttons, we shouldn't show the dialog.
15932     *
15933     * A thought: SystemUI might also want to get told about this, the Power
15934     * dialog / global actions also might want different behaviors.
15935     */
15936    private static final boolean shouldShowDialogs(Configuration config) {
15937        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15938                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15939    }
15940
15941    /**
15942     * Save the locale.  You must be inside a synchronized (this) block.
15943     */
15944    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15945        if(isDiff) {
15946            SystemProperties.set("user.language", l.getLanguage());
15947            SystemProperties.set("user.region", l.getCountry());
15948        }
15949
15950        if(isPersist) {
15951            SystemProperties.set("persist.sys.language", l.getLanguage());
15952            SystemProperties.set("persist.sys.country", l.getCountry());
15953            SystemProperties.set("persist.sys.localevar", l.getVariant());
15954        }
15955    }
15956
15957    @Override
15958    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
15959        synchronized (this) {
15960            ActivityRecord srec = ActivityRecord.forToken(token);
15961            if (srec.task != null && srec.task.stack != null) {
15962                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
15963            }
15964        }
15965        return false;
15966    }
15967
15968    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15969            Intent resultData) {
15970
15971        synchronized (this) {
15972            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15973            if (stack != null) {
15974                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15975            }
15976            return false;
15977        }
15978    }
15979
15980    public int getLaunchedFromUid(IBinder activityToken) {
15981        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15982        if (srec == null) {
15983            return -1;
15984        }
15985        return srec.launchedFromUid;
15986    }
15987
15988    public String getLaunchedFromPackage(IBinder activityToken) {
15989        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15990        if (srec == null) {
15991            return null;
15992        }
15993        return srec.launchedFromPackage;
15994    }
15995
15996    // =========================================================
15997    // LIFETIME MANAGEMENT
15998    // =========================================================
15999
16000    // Returns which broadcast queue the app is the current [or imminent] receiver
16001    // on, or 'null' if the app is not an active broadcast recipient.
16002    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16003        BroadcastRecord r = app.curReceiver;
16004        if (r != null) {
16005            return r.queue;
16006        }
16007
16008        // It's not the current receiver, but it might be starting up to become one
16009        synchronized (this) {
16010            for (BroadcastQueue queue : mBroadcastQueues) {
16011                r = queue.mPendingBroadcast;
16012                if (r != null && r.curApp == app) {
16013                    // found it; report which queue it's in
16014                    return queue;
16015                }
16016            }
16017        }
16018
16019        return null;
16020    }
16021
16022    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16023            boolean doingAll, long now) {
16024        if (mAdjSeq == app.adjSeq) {
16025            // This adjustment has already been computed.
16026            return app.curRawAdj;
16027        }
16028
16029        if (app.thread == null) {
16030            app.adjSeq = mAdjSeq;
16031            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16032            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16033            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16034        }
16035
16036        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16037        app.adjSource = null;
16038        app.adjTarget = null;
16039        app.empty = false;
16040        app.cached = false;
16041
16042        final int activitiesSize = app.activities.size();
16043
16044        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16045            // The max adjustment doesn't allow this app to be anything
16046            // below foreground, so it is not worth doing work for it.
16047            app.adjType = "fixed";
16048            app.adjSeq = mAdjSeq;
16049            app.curRawAdj = app.maxAdj;
16050            app.foregroundActivities = false;
16051            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16052            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16053            // System processes can do UI, and when they do we want to have
16054            // them trim their memory after the user leaves the UI.  To
16055            // facilitate this, here we need to determine whether or not it
16056            // is currently showing UI.
16057            app.systemNoUi = true;
16058            if (app == TOP_APP) {
16059                app.systemNoUi = false;
16060            } else if (activitiesSize > 0) {
16061                for (int j = 0; j < activitiesSize; j++) {
16062                    final ActivityRecord r = app.activities.get(j);
16063                    if (r.visible) {
16064                        app.systemNoUi = false;
16065                    }
16066                }
16067            }
16068            if (!app.systemNoUi) {
16069                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16070            }
16071            return (app.curAdj=app.maxAdj);
16072        }
16073
16074        app.systemNoUi = false;
16075
16076        // Determine the importance of the process, starting with most
16077        // important to least, and assign an appropriate OOM adjustment.
16078        int adj;
16079        int schedGroup;
16080        int procState;
16081        boolean foregroundActivities = false;
16082        BroadcastQueue queue;
16083        if (app == TOP_APP) {
16084            // The last app on the list is the foreground app.
16085            adj = ProcessList.FOREGROUND_APP_ADJ;
16086            schedGroup = Process.THREAD_GROUP_DEFAULT;
16087            app.adjType = "top-activity";
16088            foregroundActivities = true;
16089            procState = ActivityManager.PROCESS_STATE_TOP;
16090        } else if (app.instrumentationClass != null) {
16091            // Don't want to kill running instrumentation.
16092            adj = ProcessList.FOREGROUND_APP_ADJ;
16093            schedGroup = Process.THREAD_GROUP_DEFAULT;
16094            app.adjType = "instrumentation";
16095            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16096        } else if ((queue = isReceivingBroadcast(app)) != null) {
16097            // An app that is currently receiving a broadcast also
16098            // counts as being in the foreground for OOM killer purposes.
16099            // It's placed in a sched group based on the nature of the
16100            // broadcast as reflected by which queue it's active in.
16101            adj = ProcessList.FOREGROUND_APP_ADJ;
16102            schedGroup = (queue == mFgBroadcastQueue)
16103                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16104            app.adjType = "broadcast";
16105            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16106        } else if (app.executingServices.size() > 0) {
16107            // An app that is currently executing a service callback also
16108            // counts as being in the foreground.
16109            adj = ProcessList.FOREGROUND_APP_ADJ;
16110            schedGroup = app.execServicesFg ?
16111                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16112            app.adjType = "exec-service";
16113            procState = ActivityManager.PROCESS_STATE_SERVICE;
16114            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16115        } else {
16116            // As far as we know the process is empty.  We may change our mind later.
16117            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16118            // At this point we don't actually know the adjustment.  Use the cached adj
16119            // value that the caller wants us to.
16120            adj = cachedAdj;
16121            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16122            app.cached = true;
16123            app.empty = true;
16124            app.adjType = "cch-empty";
16125        }
16126
16127        // Examine all activities if not already foreground.
16128        if (!foregroundActivities && activitiesSize > 0) {
16129            for (int j = 0; j < activitiesSize; j++) {
16130                final ActivityRecord r = app.activities.get(j);
16131                if (r.app != app) {
16132                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16133                            + app + "?!?");
16134                    continue;
16135                }
16136                if (r.visible) {
16137                    // App has a visible activity; only upgrade adjustment.
16138                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16139                        adj = ProcessList.VISIBLE_APP_ADJ;
16140                        app.adjType = "visible";
16141                    }
16142                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16143                        procState = ActivityManager.PROCESS_STATE_TOP;
16144                    }
16145                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16146                    app.cached = false;
16147                    app.empty = false;
16148                    foregroundActivities = true;
16149                    break;
16150                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16151                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16152                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16153                        app.adjType = "pausing";
16154                    }
16155                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16156                        procState = ActivityManager.PROCESS_STATE_TOP;
16157                    }
16158                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16159                    app.cached = false;
16160                    app.empty = false;
16161                    foregroundActivities = true;
16162                } else if (r.state == ActivityState.STOPPING) {
16163                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16164                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16165                        app.adjType = "stopping";
16166                    }
16167                    // For the process state, we will at this point consider the
16168                    // process to be cached.  It will be cached either as an activity
16169                    // or empty depending on whether the activity is finishing.  We do
16170                    // this so that we can treat the process as cached for purposes of
16171                    // memory trimming (determing current memory level, trim command to
16172                    // send to process) since there can be an arbitrary number of stopping
16173                    // processes and they should soon all go into the cached state.
16174                    if (!r.finishing) {
16175                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16176                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16177                        }
16178                    }
16179                    app.cached = false;
16180                    app.empty = false;
16181                    foregroundActivities = true;
16182                } else {
16183                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16184                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16185                        app.adjType = "cch-act";
16186                    }
16187                }
16188            }
16189        }
16190
16191        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16192            if (app.foregroundServices) {
16193                // The user is aware of this app, so make it visible.
16194                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16195                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16196                app.cached = false;
16197                app.adjType = "fg-service";
16198                schedGroup = Process.THREAD_GROUP_DEFAULT;
16199            } else if (app.forcingToForeground != null) {
16200                // The user is aware of this app, so make it visible.
16201                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16202                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16203                app.cached = false;
16204                app.adjType = "force-fg";
16205                app.adjSource = app.forcingToForeground;
16206                schedGroup = Process.THREAD_GROUP_DEFAULT;
16207            }
16208        }
16209
16210        if (app == mHeavyWeightProcess) {
16211            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16212                // We don't want to kill the current heavy-weight process.
16213                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16214                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16215                app.cached = false;
16216                app.adjType = "heavy";
16217            }
16218            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16219                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16220            }
16221        }
16222
16223        if (app == mHomeProcess) {
16224            if (adj > ProcessList.HOME_APP_ADJ) {
16225                // This process is hosting what we currently consider to be the
16226                // home app, so we don't want to let it go into the background.
16227                adj = ProcessList.HOME_APP_ADJ;
16228                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16229                app.cached = false;
16230                app.adjType = "home";
16231            }
16232            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16233                procState = ActivityManager.PROCESS_STATE_HOME;
16234            }
16235        }
16236
16237        if (app == mPreviousProcess && app.activities.size() > 0) {
16238            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16239                // This was the previous process that showed UI to the user.
16240                // We want to try to keep it around more aggressively, to give
16241                // a good experience around switching between two apps.
16242                adj = ProcessList.PREVIOUS_APP_ADJ;
16243                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16244                app.cached = false;
16245                app.adjType = "previous";
16246            }
16247            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16248                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16249            }
16250        }
16251
16252        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16253                + " reason=" + app.adjType);
16254
16255        // By default, we use the computed adjustment.  It may be changed if
16256        // there are applications dependent on our services or providers, but
16257        // this gives us a baseline and makes sure we don't get into an
16258        // infinite recursion.
16259        app.adjSeq = mAdjSeq;
16260        app.curRawAdj = adj;
16261        app.hasStartedServices = false;
16262
16263        if (mBackupTarget != null && app == mBackupTarget.app) {
16264            // If possible we want to avoid killing apps while they're being backed up
16265            if (adj > ProcessList.BACKUP_APP_ADJ) {
16266                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16267                adj = ProcessList.BACKUP_APP_ADJ;
16268                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16269                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16270                }
16271                app.adjType = "backup";
16272                app.cached = false;
16273            }
16274            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16275                procState = ActivityManager.PROCESS_STATE_BACKUP;
16276            }
16277        }
16278
16279        boolean mayBeTop = false;
16280
16281        for (int is = app.services.size()-1;
16282                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16283                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16284                        || procState > ActivityManager.PROCESS_STATE_TOP);
16285                is--) {
16286            ServiceRecord s = app.services.valueAt(is);
16287            if (s.startRequested) {
16288                app.hasStartedServices = true;
16289                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16290                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16291                }
16292                if (app.hasShownUi && app != mHomeProcess) {
16293                    // If this process has shown some UI, let it immediately
16294                    // go to the LRU list because it may be pretty heavy with
16295                    // UI stuff.  We'll tag it with a label just to help
16296                    // debug and understand what is going on.
16297                    if (adj > ProcessList.SERVICE_ADJ) {
16298                        app.adjType = "cch-started-ui-services";
16299                    }
16300                } else {
16301                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16302                        // This service has seen some activity within
16303                        // recent memory, so we will keep its process ahead
16304                        // of the background processes.
16305                        if (adj > ProcessList.SERVICE_ADJ) {
16306                            adj = ProcessList.SERVICE_ADJ;
16307                            app.adjType = "started-services";
16308                            app.cached = false;
16309                        }
16310                    }
16311                    // If we have let the service slide into the background
16312                    // state, still have some text describing what it is doing
16313                    // even though the service no longer has an impact.
16314                    if (adj > ProcessList.SERVICE_ADJ) {
16315                        app.adjType = "cch-started-services";
16316                    }
16317                }
16318            }
16319            for (int conni = s.connections.size()-1;
16320                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16321                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16322                            || procState > ActivityManager.PROCESS_STATE_TOP);
16323                    conni--) {
16324                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16325                for (int i = 0;
16326                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16327                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16328                                || procState > ActivityManager.PROCESS_STATE_TOP);
16329                        i++) {
16330                    // XXX should compute this based on the max of
16331                    // all connected clients.
16332                    ConnectionRecord cr = clist.get(i);
16333                    if (cr.binding.client == app) {
16334                        // Binding to ourself is not interesting.
16335                        continue;
16336                    }
16337                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16338                        ProcessRecord client = cr.binding.client;
16339                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16340                                TOP_APP, doingAll, now);
16341                        int clientProcState = client.curProcState;
16342                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16343                            // If the other app is cached for any reason, for purposes here
16344                            // we are going to consider it empty.  The specific cached state
16345                            // doesn't propagate except under certain conditions.
16346                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16347                        }
16348                        String adjType = null;
16349                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16350                            // Not doing bind OOM management, so treat
16351                            // this guy more like a started service.
16352                            if (app.hasShownUi && app != mHomeProcess) {
16353                                // If this process has shown some UI, let it immediately
16354                                // go to the LRU list because it may be pretty heavy with
16355                                // UI stuff.  We'll tag it with a label just to help
16356                                // debug and understand what is going on.
16357                                if (adj > clientAdj) {
16358                                    adjType = "cch-bound-ui-services";
16359                                }
16360                                app.cached = false;
16361                                clientAdj = adj;
16362                                clientProcState = procState;
16363                            } else {
16364                                if (now >= (s.lastActivity
16365                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16366                                    // This service has not seen activity within
16367                                    // recent memory, so allow it to drop to the
16368                                    // LRU list if there is no other reason to keep
16369                                    // it around.  We'll also tag it with a label just
16370                                    // to help debug and undertand what is going on.
16371                                    if (adj > clientAdj) {
16372                                        adjType = "cch-bound-services";
16373                                    }
16374                                    clientAdj = adj;
16375                                }
16376                            }
16377                        }
16378                        if (adj > clientAdj) {
16379                            // If this process has recently shown UI, and
16380                            // the process that is binding to it is less
16381                            // important than being visible, then we don't
16382                            // care about the binding as much as we care
16383                            // about letting this process get into the LRU
16384                            // list to be killed and restarted if needed for
16385                            // memory.
16386                            if (app.hasShownUi && app != mHomeProcess
16387                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16388                                adjType = "cch-bound-ui-services";
16389                            } else {
16390                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16391                                        |Context.BIND_IMPORTANT)) != 0) {
16392                                    adj = clientAdj;
16393                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16394                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16395                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16396                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16397                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16398                                    adj = clientAdj;
16399                                } else {
16400                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16401                                        adj = ProcessList.VISIBLE_APP_ADJ;
16402                                    }
16403                                }
16404                                if (!client.cached) {
16405                                    app.cached = false;
16406                                }
16407                                adjType = "service";
16408                            }
16409                        }
16410                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16411                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16412                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16413                            }
16414                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16415                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16416                                    // Special handling of clients who are in the top state.
16417                                    // We *may* want to consider this process to be in the
16418                                    // top state as well, but only if there is not another
16419                                    // reason for it to be running.  Being on the top is a
16420                                    // special state, meaning you are specifically running
16421                                    // for the current top app.  If the process is already
16422                                    // running in the background for some other reason, it
16423                                    // is more important to continue considering it to be
16424                                    // in the background state.
16425                                    mayBeTop = true;
16426                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16427                                } else {
16428                                    // Special handling for above-top states (persistent
16429                                    // processes).  These should not bring the current process
16430                                    // into the top state, since they are not on top.  Instead
16431                                    // give them the best state after that.
16432                                    clientProcState =
16433                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16434                                }
16435                            }
16436                        } else {
16437                            if (clientProcState <
16438                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16439                                clientProcState =
16440                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16441                            }
16442                        }
16443                        if (procState > clientProcState) {
16444                            procState = clientProcState;
16445                        }
16446                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16447                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16448                            app.pendingUiClean = true;
16449                        }
16450                        if (adjType != null) {
16451                            app.adjType = adjType;
16452                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16453                                    .REASON_SERVICE_IN_USE;
16454                            app.adjSource = cr.binding.client;
16455                            app.adjSourceProcState = clientProcState;
16456                            app.adjTarget = s.name;
16457                        }
16458                    }
16459                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16460                        app.treatLikeActivity = true;
16461                    }
16462                    final ActivityRecord a = cr.activity;
16463                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16464                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16465                                (a.visible || a.state == ActivityState.RESUMED
16466                                 || a.state == ActivityState.PAUSING)) {
16467                            adj = ProcessList.FOREGROUND_APP_ADJ;
16468                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16469                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16470                            }
16471                            app.cached = false;
16472                            app.adjType = "service";
16473                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16474                                    .REASON_SERVICE_IN_USE;
16475                            app.adjSource = a;
16476                            app.adjSourceProcState = procState;
16477                            app.adjTarget = s.name;
16478                        }
16479                    }
16480                }
16481            }
16482        }
16483
16484        for (int provi = app.pubProviders.size()-1;
16485                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16486                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16487                        || procState > ActivityManager.PROCESS_STATE_TOP);
16488                provi--) {
16489            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16490            for (int i = cpr.connections.size()-1;
16491                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16492                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16493                            || procState > ActivityManager.PROCESS_STATE_TOP);
16494                    i--) {
16495                ContentProviderConnection conn = cpr.connections.get(i);
16496                ProcessRecord client = conn.client;
16497                if (client == app) {
16498                    // Being our own client is not interesting.
16499                    continue;
16500                }
16501                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16502                int clientProcState = client.curProcState;
16503                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16504                    // If the other app is cached for any reason, for purposes here
16505                    // we are going to consider it empty.
16506                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16507                }
16508                if (adj > clientAdj) {
16509                    if (app.hasShownUi && app != mHomeProcess
16510                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16511                        app.adjType = "cch-ui-provider";
16512                    } else {
16513                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16514                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16515                        app.adjType = "provider";
16516                    }
16517                    app.cached &= client.cached;
16518                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16519                            .REASON_PROVIDER_IN_USE;
16520                    app.adjSource = client;
16521                    app.adjSourceProcState = clientProcState;
16522                    app.adjTarget = cpr.name;
16523                }
16524                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16525                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16526                        // Special handling of clients who are in the top state.
16527                        // We *may* want to consider this process to be in the
16528                        // top state as well, but only if there is not another
16529                        // reason for it to be running.  Being on the top is a
16530                        // special state, meaning you are specifically running
16531                        // for the current top app.  If the process is already
16532                        // running in the background for some other reason, it
16533                        // is more important to continue considering it to be
16534                        // in the background state.
16535                        mayBeTop = true;
16536                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16537                    } else {
16538                        // Special handling for above-top states (persistent
16539                        // processes).  These should not bring the current process
16540                        // into the top state, since they are not on top.  Instead
16541                        // give them the best state after that.
16542                        clientProcState =
16543                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16544                    }
16545                }
16546                if (procState > clientProcState) {
16547                    procState = clientProcState;
16548                }
16549                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16550                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16551                }
16552            }
16553            // If the provider has external (non-framework) process
16554            // dependencies, ensure that its adjustment is at least
16555            // FOREGROUND_APP_ADJ.
16556            if (cpr.hasExternalProcessHandles()) {
16557                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16558                    adj = ProcessList.FOREGROUND_APP_ADJ;
16559                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16560                    app.cached = false;
16561                    app.adjType = "provider";
16562                    app.adjTarget = cpr.name;
16563                }
16564                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16565                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16566                }
16567            }
16568        }
16569
16570        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16571            // A client of one of our services or providers is in the top state.  We
16572            // *may* want to be in the top state, but not if we are already running in
16573            // the background for some other reason.  For the decision here, we are going
16574            // to pick out a few specific states that we want to remain in when a client
16575            // is top (states that tend to be longer-term) and otherwise allow it to go
16576            // to the top state.
16577            switch (procState) {
16578                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16579                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16580                case ActivityManager.PROCESS_STATE_SERVICE:
16581                    // These all are longer-term states, so pull them up to the top
16582                    // of the background states, but not all the way to the top state.
16583                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16584                    break;
16585                default:
16586                    // Otherwise, top is a better choice, so take it.
16587                    procState = ActivityManager.PROCESS_STATE_TOP;
16588                    break;
16589            }
16590        }
16591
16592        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16593            if (app.hasClientActivities) {
16594                // This is a cached process, but with client activities.  Mark it so.
16595                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16596                app.adjType = "cch-client-act";
16597            } else if (app.treatLikeActivity) {
16598                // This is a cached process, but somebody wants us to treat it like it has
16599                // an activity, okay!
16600                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16601                app.adjType = "cch-as-act";
16602            }
16603        }
16604
16605        if (adj == ProcessList.SERVICE_ADJ) {
16606            if (doingAll) {
16607                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16608                mNewNumServiceProcs++;
16609                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16610                if (!app.serviceb) {
16611                    // This service isn't far enough down on the LRU list to
16612                    // normally be a B service, but if we are low on RAM and it
16613                    // is large we want to force it down since we would prefer to
16614                    // keep launcher over it.
16615                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16616                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16617                        app.serviceHighRam = true;
16618                        app.serviceb = true;
16619                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16620                    } else {
16621                        mNewNumAServiceProcs++;
16622                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16623                    }
16624                } else {
16625                    app.serviceHighRam = false;
16626                }
16627            }
16628            if (app.serviceb) {
16629                adj = ProcessList.SERVICE_B_ADJ;
16630            }
16631        }
16632
16633        app.curRawAdj = adj;
16634
16635        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16636        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16637        if (adj > app.maxAdj) {
16638            adj = app.maxAdj;
16639            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16640                schedGroup = Process.THREAD_GROUP_DEFAULT;
16641            }
16642        }
16643
16644        // Do final modification to adj.  Everything we do between here and applying
16645        // the final setAdj must be done in this function, because we will also use
16646        // it when computing the final cached adj later.  Note that we don't need to
16647        // worry about this for max adj above, since max adj will always be used to
16648        // keep it out of the cached vaues.
16649        app.curAdj = app.modifyRawOomAdj(adj);
16650        app.curSchedGroup = schedGroup;
16651        app.curProcState = procState;
16652        app.foregroundActivities = foregroundActivities;
16653
16654        return app.curRawAdj;
16655    }
16656
16657    /**
16658     * Schedule PSS collection of a process.
16659     */
16660    void requestPssLocked(ProcessRecord proc, int procState) {
16661        if (mPendingPssProcesses.contains(proc)) {
16662            return;
16663        }
16664        if (mPendingPssProcesses.size() == 0) {
16665            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16666        }
16667        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16668        proc.pssProcState = procState;
16669        mPendingPssProcesses.add(proc);
16670    }
16671
16672    /**
16673     * Schedule PSS collection of all processes.
16674     */
16675    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16676        if (!always) {
16677            if (now < (mLastFullPssTime +
16678                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16679                return;
16680            }
16681        }
16682        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16683        mLastFullPssTime = now;
16684        mFullPssPending = true;
16685        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16686        mPendingPssProcesses.clear();
16687        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16688            ProcessRecord app = mLruProcesses.get(i);
16689            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16690                app.pssProcState = app.setProcState;
16691                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16692                        isSleeping(), now);
16693                mPendingPssProcesses.add(app);
16694            }
16695        }
16696        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16697    }
16698
16699    /**
16700     * Ask a given process to GC right now.
16701     */
16702    final void performAppGcLocked(ProcessRecord app) {
16703        try {
16704            app.lastRequestedGc = SystemClock.uptimeMillis();
16705            if (app.thread != null) {
16706                if (app.reportLowMemory) {
16707                    app.reportLowMemory = false;
16708                    app.thread.scheduleLowMemory();
16709                } else {
16710                    app.thread.processInBackground();
16711                }
16712            }
16713        } catch (Exception e) {
16714            // whatever.
16715        }
16716    }
16717
16718    /**
16719     * Returns true if things are idle enough to perform GCs.
16720     */
16721    private final boolean canGcNowLocked() {
16722        boolean processingBroadcasts = false;
16723        for (BroadcastQueue q : mBroadcastQueues) {
16724            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16725                processingBroadcasts = true;
16726            }
16727        }
16728        return !processingBroadcasts
16729                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16730    }
16731
16732    /**
16733     * Perform GCs on all processes that are waiting for it, but only
16734     * if things are idle.
16735     */
16736    final void performAppGcsLocked() {
16737        final int N = mProcessesToGc.size();
16738        if (N <= 0) {
16739            return;
16740        }
16741        if (canGcNowLocked()) {
16742            while (mProcessesToGc.size() > 0) {
16743                ProcessRecord proc = mProcessesToGc.remove(0);
16744                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16745                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16746                            <= SystemClock.uptimeMillis()) {
16747                        // To avoid spamming the system, we will GC processes one
16748                        // at a time, waiting a few seconds between each.
16749                        performAppGcLocked(proc);
16750                        scheduleAppGcsLocked();
16751                        return;
16752                    } else {
16753                        // It hasn't been long enough since we last GCed this
16754                        // process...  put it in the list to wait for its time.
16755                        addProcessToGcListLocked(proc);
16756                        break;
16757                    }
16758                }
16759            }
16760
16761            scheduleAppGcsLocked();
16762        }
16763    }
16764
16765    /**
16766     * If all looks good, perform GCs on all processes waiting for them.
16767     */
16768    final void performAppGcsIfAppropriateLocked() {
16769        if (canGcNowLocked()) {
16770            performAppGcsLocked();
16771            return;
16772        }
16773        // Still not idle, wait some more.
16774        scheduleAppGcsLocked();
16775    }
16776
16777    /**
16778     * Schedule the execution of all pending app GCs.
16779     */
16780    final void scheduleAppGcsLocked() {
16781        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16782
16783        if (mProcessesToGc.size() > 0) {
16784            // Schedule a GC for the time to the next process.
16785            ProcessRecord proc = mProcessesToGc.get(0);
16786            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16787
16788            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16789            long now = SystemClock.uptimeMillis();
16790            if (when < (now+GC_TIMEOUT)) {
16791                when = now + GC_TIMEOUT;
16792            }
16793            mHandler.sendMessageAtTime(msg, when);
16794        }
16795    }
16796
16797    /**
16798     * Add a process to the array of processes waiting to be GCed.  Keeps the
16799     * list in sorted order by the last GC time.  The process can't already be
16800     * on the list.
16801     */
16802    final void addProcessToGcListLocked(ProcessRecord proc) {
16803        boolean added = false;
16804        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16805            if (mProcessesToGc.get(i).lastRequestedGc <
16806                    proc.lastRequestedGc) {
16807                added = true;
16808                mProcessesToGc.add(i+1, proc);
16809                break;
16810            }
16811        }
16812        if (!added) {
16813            mProcessesToGc.add(0, proc);
16814        }
16815    }
16816
16817    /**
16818     * Set up to ask a process to GC itself.  This will either do it
16819     * immediately, or put it on the list of processes to gc the next
16820     * time things are idle.
16821     */
16822    final void scheduleAppGcLocked(ProcessRecord app) {
16823        long now = SystemClock.uptimeMillis();
16824        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16825            return;
16826        }
16827        if (!mProcessesToGc.contains(app)) {
16828            addProcessToGcListLocked(app);
16829            scheduleAppGcsLocked();
16830        }
16831    }
16832
16833    final void checkExcessivePowerUsageLocked(boolean doKills) {
16834        updateCpuStatsNow();
16835
16836        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16837        boolean doWakeKills = doKills;
16838        boolean doCpuKills = doKills;
16839        if (mLastPowerCheckRealtime == 0) {
16840            doWakeKills = false;
16841        }
16842        if (mLastPowerCheckUptime == 0) {
16843            doCpuKills = false;
16844        }
16845        if (stats.isScreenOn()) {
16846            doWakeKills = false;
16847        }
16848        final long curRealtime = SystemClock.elapsedRealtime();
16849        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16850        final long curUptime = SystemClock.uptimeMillis();
16851        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16852        mLastPowerCheckRealtime = curRealtime;
16853        mLastPowerCheckUptime = curUptime;
16854        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16855            doWakeKills = false;
16856        }
16857        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16858            doCpuKills = false;
16859        }
16860        int i = mLruProcesses.size();
16861        while (i > 0) {
16862            i--;
16863            ProcessRecord app = mLruProcesses.get(i);
16864            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16865                long wtime;
16866                synchronized (stats) {
16867                    wtime = stats.getProcessWakeTime(app.info.uid,
16868                            app.pid, curRealtime);
16869                }
16870                long wtimeUsed = wtime - app.lastWakeTime;
16871                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16872                if (DEBUG_POWER) {
16873                    StringBuilder sb = new StringBuilder(128);
16874                    sb.append("Wake for ");
16875                    app.toShortString(sb);
16876                    sb.append(": over ");
16877                    TimeUtils.formatDuration(realtimeSince, sb);
16878                    sb.append(" used ");
16879                    TimeUtils.formatDuration(wtimeUsed, sb);
16880                    sb.append(" (");
16881                    sb.append((wtimeUsed*100)/realtimeSince);
16882                    sb.append("%)");
16883                    Slog.i(TAG, sb.toString());
16884                    sb.setLength(0);
16885                    sb.append("CPU for ");
16886                    app.toShortString(sb);
16887                    sb.append(": over ");
16888                    TimeUtils.formatDuration(uptimeSince, sb);
16889                    sb.append(" used ");
16890                    TimeUtils.formatDuration(cputimeUsed, sb);
16891                    sb.append(" (");
16892                    sb.append((cputimeUsed*100)/uptimeSince);
16893                    sb.append("%)");
16894                    Slog.i(TAG, sb.toString());
16895                }
16896                // If a process has held a wake lock for more
16897                // than 50% of the time during this period,
16898                // that sounds bad.  Kill!
16899                if (doWakeKills && realtimeSince > 0
16900                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16901                    synchronized (stats) {
16902                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16903                                realtimeSince, wtimeUsed);
16904                    }
16905                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16906                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16907                } else if (doCpuKills && uptimeSince > 0
16908                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16909                    synchronized (stats) {
16910                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16911                                uptimeSince, cputimeUsed);
16912                    }
16913                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16914                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16915                } else {
16916                    app.lastWakeTime = wtime;
16917                    app.lastCpuTime = app.curCpuTime;
16918                }
16919            }
16920        }
16921    }
16922
16923    private final boolean applyOomAdjLocked(ProcessRecord app,
16924            ProcessRecord TOP_APP, boolean doingAll, long now) {
16925        boolean success = true;
16926
16927        if (app.curRawAdj != app.setRawAdj) {
16928            app.setRawAdj = app.curRawAdj;
16929        }
16930
16931        int changes = 0;
16932
16933        if (app.curAdj != app.setAdj) {
16934            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16935            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16936                TAG, "Set " + app.pid + " " + app.processName +
16937                " adj " + app.curAdj + ": " + app.adjType);
16938            app.setAdj = app.curAdj;
16939        }
16940
16941        if (app.setSchedGroup != app.curSchedGroup) {
16942            app.setSchedGroup = app.curSchedGroup;
16943            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16944                    "Setting process group of " + app.processName
16945                    + " to " + app.curSchedGroup);
16946            if (app.waitingToKill != null &&
16947                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16948                app.kill(app.waitingToKill, true);
16949                success = false;
16950            } else {
16951                if (true) {
16952                    long oldId = Binder.clearCallingIdentity();
16953                    try {
16954                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16955                    } catch (Exception e) {
16956                        Slog.w(TAG, "Failed setting process group of " + app.pid
16957                                + " to " + app.curSchedGroup);
16958                        e.printStackTrace();
16959                    } finally {
16960                        Binder.restoreCallingIdentity(oldId);
16961                    }
16962                } else {
16963                    if (app.thread != null) {
16964                        try {
16965                            app.thread.setSchedulingGroup(app.curSchedGroup);
16966                        } catch (RemoteException e) {
16967                        }
16968                    }
16969                }
16970                Process.setSwappiness(app.pid,
16971                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16972            }
16973        }
16974        if (app.repForegroundActivities != app.foregroundActivities) {
16975            app.repForegroundActivities = app.foregroundActivities;
16976            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16977        }
16978        if (app.repProcState != app.curProcState) {
16979            app.repProcState = app.curProcState;
16980            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16981            if (app.thread != null) {
16982                try {
16983                    if (false) {
16984                        //RuntimeException h = new RuntimeException("here");
16985                        Slog.i(TAG, "Sending new process state " + app.repProcState
16986                                + " to " + app /*, h*/);
16987                    }
16988                    app.thread.setProcessState(app.repProcState);
16989                } catch (RemoteException e) {
16990                }
16991            }
16992        }
16993        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16994                app.setProcState)) {
16995            app.lastStateTime = now;
16996            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16997                    isSleeping(), now);
16998            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16999                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17000                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17001                    + (app.nextPssTime-now) + ": " + app);
17002        } else {
17003            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17004                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17005                requestPssLocked(app, app.setProcState);
17006                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17007                        isSleeping(), now);
17008            } else if (false && DEBUG_PSS) {
17009                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17010            }
17011        }
17012        if (app.setProcState != app.curProcState) {
17013            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17014                    "Proc state change of " + app.processName
17015                    + " to " + app.curProcState);
17016            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17017            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17018            if (setImportant && !curImportant) {
17019                // This app is no longer something we consider important enough to allow to
17020                // use arbitrary amounts of battery power.  Note
17021                // its current wake lock time to later know to kill it if
17022                // it is not behaving well.
17023                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17024                synchronized (stats) {
17025                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17026                            app.pid, SystemClock.elapsedRealtime());
17027                }
17028                app.lastCpuTime = app.curCpuTime;
17029
17030            }
17031            app.setProcState = app.curProcState;
17032            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17033                app.notCachedSinceIdle = false;
17034            }
17035            if (!doingAll) {
17036                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17037            } else {
17038                app.procStateChanged = true;
17039            }
17040        }
17041
17042        if (changes != 0) {
17043            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17044            int i = mPendingProcessChanges.size()-1;
17045            ProcessChangeItem item = null;
17046            while (i >= 0) {
17047                item = mPendingProcessChanges.get(i);
17048                if (item.pid == app.pid) {
17049                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17050                    break;
17051                }
17052                i--;
17053            }
17054            if (i < 0) {
17055                // No existing item in pending changes; need a new one.
17056                final int NA = mAvailProcessChanges.size();
17057                if (NA > 0) {
17058                    item = mAvailProcessChanges.remove(NA-1);
17059                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17060                } else {
17061                    item = new ProcessChangeItem();
17062                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17063                }
17064                item.changes = 0;
17065                item.pid = app.pid;
17066                item.uid = app.info.uid;
17067                if (mPendingProcessChanges.size() == 0) {
17068                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17069                            "*** Enqueueing dispatch processes changed!");
17070                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17071                }
17072                mPendingProcessChanges.add(item);
17073            }
17074            item.changes |= changes;
17075            item.processState = app.repProcState;
17076            item.foregroundActivities = app.repForegroundActivities;
17077            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17078                    + Integer.toHexString(System.identityHashCode(item))
17079                    + " " + app.toShortString() + ": changes=" + item.changes
17080                    + " procState=" + item.processState
17081                    + " foreground=" + item.foregroundActivities
17082                    + " type=" + app.adjType + " source=" + app.adjSource
17083                    + " target=" + app.adjTarget);
17084        }
17085
17086        return success;
17087    }
17088
17089    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17090        if (proc.thread != null) {
17091            if (proc.baseProcessTracker != null) {
17092                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17093            }
17094            if (proc.repProcState >= 0) {
17095                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17096                        proc.repProcState);
17097            }
17098        }
17099    }
17100
17101    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17102            ProcessRecord TOP_APP, boolean doingAll, long now) {
17103        if (app.thread == null) {
17104            return false;
17105        }
17106
17107        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17108
17109        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17110    }
17111
17112    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17113            boolean oomAdj) {
17114        if (isForeground != proc.foregroundServices) {
17115            proc.foregroundServices = isForeground;
17116            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17117                    proc.info.uid);
17118            if (isForeground) {
17119                if (curProcs == null) {
17120                    curProcs = new ArrayList<ProcessRecord>();
17121                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17122                }
17123                if (!curProcs.contains(proc)) {
17124                    curProcs.add(proc);
17125                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17126                            proc.info.packageName, proc.info.uid);
17127                }
17128            } else {
17129                if (curProcs != null) {
17130                    if (curProcs.remove(proc)) {
17131                        mBatteryStatsService.noteEvent(
17132                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17133                                proc.info.packageName, proc.info.uid);
17134                        if (curProcs.size() <= 0) {
17135                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17136                        }
17137                    }
17138                }
17139            }
17140            if (oomAdj) {
17141                updateOomAdjLocked();
17142            }
17143        }
17144    }
17145
17146    private final ActivityRecord resumedAppLocked() {
17147        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17148        String pkg;
17149        int uid;
17150        if (act != null) {
17151            pkg = act.packageName;
17152            uid = act.info.applicationInfo.uid;
17153        } else {
17154            pkg = null;
17155            uid = -1;
17156        }
17157        // Has the UID or resumed package name changed?
17158        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17159                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17160            if (mCurResumedPackage != null) {
17161                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17162                        mCurResumedPackage, mCurResumedUid);
17163            }
17164            mCurResumedPackage = pkg;
17165            mCurResumedUid = uid;
17166            if (mCurResumedPackage != null) {
17167                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17168                        mCurResumedPackage, mCurResumedUid);
17169            }
17170        }
17171        return act;
17172    }
17173
17174    final boolean updateOomAdjLocked(ProcessRecord app) {
17175        final ActivityRecord TOP_ACT = resumedAppLocked();
17176        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17177        final boolean wasCached = app.cached;
17178
17179        mAdjSeq++;
17180
17181        // This is the desired cached adjusment we want to tell it to use.
17182        // If our app is currently cached, we know it, and that is it.  Otherwise,
17183        // we don't know it yet, and it needs to now be cached we will then
17184        // need to do a complete oom adj.
17185        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17186                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17187        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17188                SystemClock.uptimeMillis());
17189        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17190            // Changed to/from cached state, so apps after it in the LRU
17191            // list may also be changed.
17192            updateOomAdjLocked();
17193        }
17194        return success;
17195    }
17196
17197    final void updateOomAdjLocked() {
17198        final ActivityRecord TOP_ACT = resumedAppLocked();
17199        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17200        final long now = SystemClock.uptimeMillis();
17201        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17202        final int N = mLruProcesses.size();
17203
17204        if (false) {
17205            RuntimeException e = new RuntimeException();
17206            e.fillInStackTrace();
17207            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17208        }
17209
17210        mAdjSeq++;
17211        mNewNumServiceProcs = 0;
17212        mNewNumAServiceProcs = 0;
17213
17214        final int emptyProcessLimit;
17215        final int cachedProcessLimit;
17216        if (mProcessLimit <= 0) {
17217            emptyProcessLimit = cachedProcessLimit = 0;
17218        } else if (mProcessLimit == 1) {
17219            emptyProcessLimit = 1;
17220            cachedProcessLimit = 0;
17221        } else {
17222            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17223            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17224        }
17225
17226        // Let's determine how many processes we have running vs.
17227        // how many slots we have for background processes; we may want
17228        // to put multiple processes in a slot of there are enough of
17229        // them.
17230        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17231                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17232        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17233        if (numEmptyProcs > cachedProcessLimit) {
17234            // If there are more empty processes than our limit on cached
17235            // processes, then use the cached process limit for the factor.
17236            // This ensures that the really old empty processes get pushed
17237            // down to the bottom, so if we are running low on memory we will
17238            // have a better chance at keeping around more cached processes
17239            // instead of a gazillion empty processes.
17240            numEmptyProcs = cachedProcessLimit;
17241        }
17242        int emptyFactor = numEmptyProcs/numSlots;
17243        if (emptyFactor < 1) emptyFactor = 1;
17244        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17245        if (cachedFactor < 1) cachedFactor = 1;
17246        int stepCached = 0;
17247        int stepEmpty = 0;
17248        int numCached = 0;
17249        int numEmpty = 0;
17250        int numTrimming = 0;
17251
17252        mNumNonCachedProcs = 0;
17253        mNumCachedHiddenProcs = 0;
17254
17255        // First update the OOM adjustment for each of the
17256        // application processes based on their current state.
17257        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17258        int nextCachedAdj = curCachedAdj+1;
17259        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17260        int nextEmptyAdj = curEmptyAdj+2;
17261        for (int i=N-1; i>=0; i--) {
17262            ProcessRecord app = mLruProcesses.get(i);
17263            if (!app.killedByAm && app.thread != null) {
17264                app.procStateChanged = false;
17265                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17266
17267                // If we haven't yet assigned the final cached adj
17268                // to the process, do that now.
17269                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17270                    switch (app.curProcState) {
17271                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17272                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17273                            // This process is a cached process holding activities...
17274                            // assign it the next cached value for that type, and then
17275                            // step that cached level.
17276                            app.curRawAdj = curCachedAdj;
17277                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17278                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17279                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17280                                    + ")");
17281                            if (curCachedAdj != nextCachedAdj) {
17282                                stepCached++;
17283                                if (stepCached >= cachedFactor) {
17284                                    stepCached = 0;
17285                                    curCachedAdj = nextCachedAdj;
17286                                    nextCachedAdj += 2;
17287                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17288                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17289                                    }
17290                                }
17291                            }
17292                            break;
17293                        default:
17294                            // For everything else, assign next empty cached process
17295                            // level and bump that up.  Note that this means that
17296                            // long-running services that have dropped down to the
17297                            // cached level will be treated as empty (since their process
17298                            // state is still as a service), which is what we want.
17299                            app.curRawAdj = curEmptyAdj;
17300                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17301                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17302                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17303                                    + ")");
17304                            if (curEmptyAdj != nextEmptyAdj) {
17305                                stepEmpty++;
17306                                if (stepEmpty >= emptyFactor) {
17307                                    stepEmpty = 0;
17308                                    curEmptyAdj = nextEmptyAdj;
17309                                    nextEmptyAdj += 2;
17310                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17311                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17312                                    }
17313                                }
17314                            }
17315                            break;
17316                    }
17317                }
17318
17319                applyOomAdjLocked(app, TOP_APP, true, now);
17320
17321                // Count the number of process types.
17322                switch (app.curProcState) {
17323                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17324                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17325                        mNumCachedHiddenProcs++;
17326                        numCached++;
17327                        if (numCached > cachedProcessLimit) {
17328                            app.kill("cached #" + numCached, true);
17329                        }
17330                        break;
17331                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17332                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17333                                && app.lastActivityTime < oldTime) {
17334                            app.kill("empty for "
17335                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17336                                    / 1000) + "s", true);
17337                        } else {
17338                            numEmpty++;
17339                            if (numEmpty > emptyProcessLimit) {
17340                                app.kill("empty #" + numEmpty, true);
17341                            }
17342                        }
17343                        break;
17344                    default:
17345                        mNumNonCachedProcs++;
17346                        break;
17347                }
17348
17349                if (app.isolated && app.services.size() <= 0) {
17350                    // If this is an isolated process, and there are no
17351                    // services running in it, then the process is no longer
17352                    // needed.  We agressively kill these because we can by
17353                    // definition not re-use the same process again, and it is
17354                    // good to avoid having whatever code was running in them
17355                    // left sitting around after no longer needed.
17356                    app.kill("isolated not needed", true);
17357                }
17358
17359                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17360                        && !app.killedByAm) {
17361                    numTrimming++;
17362                }
17363            }
17364        }
17365
17366        mNumServiceProcs = mNewNumServiceProcs;
17367
17368        // Now determine the memory trimming level of background processes.
17369        // Unfortunately we need to start at the back of the list to do this
17370        // properly.  We only do this if the number of background apps we
17371        // are managing to keep around is less than half the maximum we desire;
17372        // if we are keeping a good number around, we'll let them use whatever
17373        // memory they want.
17374        final int numCachedAndEmpty = numCached + numEmpty;
17375        int memFactor;
17376        if (numCached <= ProcessList.TRIM_CACHED_APPS
17377                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17378            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17379                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17380            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17381                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17382            } else {
17383                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17384            }
17385        } else {
17386            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17387        }
17388        // We always allow the memory level to go up (better).  We only allow it to go
17389        // down if we are in a state where that is allowed, *and* the total number of processes
17390        // has gone down since last time.
17391        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17392                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17393                + " last=" + mLastNumProcesses);
17394        if (memFactor > mLastMemoryLevel) {
17395            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17396                memFactor = mLastMemoryLevel;
17397                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17398            }
17399        }
17400        mLastMemoryLevel = memFactor;
17401        mLastNumProcesses = mLruProcesses.size();
17402        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17403        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17404        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17405            if (mLowRamStartTime == 0) {
17406                mLowRamStartTime = now;
17407            }
17408            int step = 0;
17409            int fgTrimLevel;
17410            switch (memFactor) {
17411                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17412                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17413                    break;
17414                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17415                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17416                    break;
17417                default:
17418                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17419                    break;
17420            }
17421            int factor = numTrimming/3;
17422            int minFactor = 2;
17423            if (mHomeProcess != null) minFactor++;
17424            if (mPreviousProcess != null) minFactor++;
17425            if (factor < minFactor) factor = minFactor;
17426            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17427            for (int i=N-1; i>=0; i--) {
17428                ProcessRecord app = mLruProcesses.get(i);
17429                if (allChanged || app.procStateChanged) {
17430                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17431                    app.procStateChanged = false;
17432                }
17433                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17434                        && !app.killedByAm) {
17435                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17436                        try {
17437                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17438                                    "Trimming memory of " + app.processName
17439                                    + " to " + curLevel);
17440                            app.thread.scheduleTrimMemory(curLevel);
17441                        } catch (RemoteException e) {
17442                        }
17443                        if (false) {
17444                            // For now we won't do this; our memory trimming seems
17445                            // to be good enough at this point that destroying
17446                            // activities causes more harm than good.
17447                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17448                                    && app != mHomeProcess && app != mPreviousProcess) {
17449                                // Need to do this on its own message because the stack may not
17450                                // be in a consistent state at this point.
17451                                // For these apps we will also finish their activities
17452                                // to help them free memory.
17453                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17454                            }
17455                        }
17456                    }
17457                    app.trimMemoryLevel = curLevel;
17458                    step++;
17459                    if (step >= factor) {
17460                        step = 0;
17461                        switch (curLevel) {
17462                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17463                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17464                                break;
17465                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17466                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17467                                break;
17468                        }
17469                    }
17470                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17471                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17472                            && app.thread != null) {
17473                        try {
17474                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17475                                    "Trimming memory of heavy-weight " + app.processName
17476                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17477                            app.thread.scheduleTrimMemory(
17478                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17479                        } catch (RemoteException e) {
17480                        }
17481                    }
17482                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17483                } else {
17484                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17485                            || app.systemNoUi) && app.pendingUiClean) {
17486                        // If this application is now in the background and it
17487                        // had done UI, then give it the special trim level to
17488                        // have it free UI resources.
17489                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17490                        if (app.trimMemoryLevel < level && app.thread != null) {
17491                            try {
17492                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17493                                        "Trimming memory of bg-ui " + app.processName
17494                                        + " to " + level);
17495                                app.thread.scheduleTrimMemory(level);
17496                            } catch (RemoteException e) {
17497                            }
17498                        }
17499                        app.pendingUiClean = false;
17500                    }
17501                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17502                        try {
17503                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17504                                    "Trimming memory of fg " + app.processName
17505                                    + " to " + fgTrimLevel);
17506                            app.thread.scheduleTrimMemory(fgTrimLevel);
17507                        } catch (RemoteException e) {
17508                        }
17509                    }
17510                    app.trimMemoryLevel = fgTrimLevel;
17511                }
17512            }
17513        } else {
17514            if (mLowRamStartTime != 0) {
17515                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17516                mLowRamStartTime = 0;
17517            }
17518            for (int i=N-1; i>=0; i--) {
17519                ProcessRecord app = mLruProcesses.get(i);
17520                if (allChanged || app.procStateChanged) {
17521                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17522                    app.procStateChanged = false;
17523                }
17524                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17525                        || app.systemNoUi) && app.pendingUiClean) {
17526                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17527                            && app.thread != null) {
17528                        try {
17529                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17530                                    "Trimming memory of ui hidden " + app.processName
17531                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17532                            app.thread.scheduleTrimMemory(
17533                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17534                        } catch (RemoteException e) {
17535                        }
17536                    }
17537                    app.pendingUiClean = false;
17538                }
17539                app.trimMemoryLevel = 0;
17540            }
17541        }
17542
17543        if (mAlwaysFinishActivities) {
17544            // Need to do this on its own message because the stack may not
17545            // be in a consistent state at this point.
17546            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17547        }
17548
17549        if (allChanged) {
17550            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17551        }
17552
17553        if (mProcessStats.shouldWriteNowLocked(now)) {
17554            mHandler.post(new Runnable() {
17555                @Override public void run() {
17556                    synchronized (ActivityManagerService.this) {
17557                        mProcessStats.writeStateAsyncLocked();
17558                    }
17559                }
17560            });
17561        }
17562
17563        if (DEBUG_OOM_ADJ) {
17564            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17565        }
17566    }
17567
17568    final void trimApplications() {
17569        synchronized (this) {
17570            int i;
17571
17572            // First remove any unused application processes whose package
17573            // has been removed.
17574            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17575                final ProcessRecord app = mRemovedProcesses.get(i);
17576                if (app.activities.size() == 0
17577                        && app.curReceiver == null && app.services.size() == 0) {
17578                    Slog.i(
17579                        TAG, "Exiting empty application process "
17580                        + app.processName + " ("
17581                        + (app.thread != null ? app.thread.asBinder() : null)
17582                        + ")\n");
17583                    if (app.pid > 0 && app.pid != MY_PID) {
17584                        app.kill("empty", false);
17585                    } else {
17586                        try {
17587                            app.thread.scheduleExit();
17588                        } catch (Exception e) {
17589                            // Ignore exceptions.
17590                        }
17591                    }
17592                    cleanUpApplicationRecordLocked(app, false, true, -1);
17593                    mRemovedProcesses.remove(i);
17594
17595                    if (app.persistent) {
17596                        addAppLocked(app.info, false, null /* ABI override */);
17597                    }
17598                }
17599            }
17600
17601            // Now update the oom adj for all processes.
17602            updateOomAdjLocked();
17603        }
17604    }
17605
17606    /** This method sends the specified signal to each of the persistent apps */
17607    public void signalPersistentProcesses(int sig) throws RemoteException {
17608        if (sig != Process.SIGNAL_USR1) {
17609            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17610        }
17611
17612        synchronized (this) {
17613            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17614                    != PackageManager.PERMISSION_GRANTED) {
17615                throw new SecurityException("Requires permission "
17616                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17617            }
17618
17619            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17620                ProcessRecord r = mLruProcesses.get(i);
17621                if (r.thread != null && r.persistent) {
17622                    Process.sendSignal(r.pid, sig);
17623                }
17624            }
17625        }
17626    }
17627
17628    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17629        if (proc == null || proc == mProfileProc) {
17630            proc = mProfileProc;
17631            profileType = mProfileType;
17632            clearProfilerLocked();
17633        }
17634        if (proc == null) {
17635            return;
17636        }
17637        try {
17638            proc.thread.profilerControl(false, null, profileType);
17639        } catch (RemoteException e) {
17640            throw new IllegalStateException("Process disappeared");
17641        }
17642    }
17643
17644    private void clearProfilerLocked() {
17645        if (mProfileFd != null) {
17646            try {
17647                mProfileFd.close();
17648            } catch (IOException e) {
17649            }
17650        }
17651        mProfileApp = null;
17652        mProfileProc = null;
17653        mProfileFile = null;
17654        mProfileType = 0;
17655        mAutoStopProfiler = false;
17656        mSamplingInterval = 0;
17657    }
17658
17659    public boolean profileControl(String process, int userId, boolean start,
17660            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17661
17662        try {
17663            synchronized (this) {
17664                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17665                // its own permission.
17666                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17667                        != PackageManager.PERMISSION_GRANTED) {
17668                    throw new SecurityException("Requires permission "
17669                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17670                }
17671
17672                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17673                    throw new IllegalArgumentException("null profile info or fd");
17674                }
17675
17676                ProcessRecord proc = null;
17677                if (process != null) {
17678                    proc = findProcessLocked(process, userId, "profileControl");
17679                }
17680
17681                if (start && (proc == null || proc.thread == null)) {
17682                    throw new IllegalArgumentException("Unknown process: " + process);
17683                }
17684
17685                if (start) {
17686                    stopProfilerLocked(null, 0);
17687                    setProfileApp(proc.info, proc.processName, profilerInfo);
17688                    mProfileProc = proc;
17689                    mProfileType = profileType;
17690                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17691                    try {
17692                        fd = fd.dup();
17693                    } catch (IOException e) {
17694                        fd = null;
17695                    }
17696                    profilerInfo.profileFd = fd;
17697                    proc.thread.profilerControl(start, profilerInfo, profileType);
17698                    fd = null;
17699                    mProfileFd = null;
17700                } else {
17701                    stopProfilerLocked(proc, profileType);
17702                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17703                        try {
17704                            profilerInfo.profileFd.close();
17705                        } catch (IOException e) {
17706                        }
17707                    }
17708                }
17709
17710                return true;
17711            }
17712        } catch (RemoteException e) {
17713            throw new IllegalStateException("Process disappeared");
17714        } finally {
17715            if (profilerInfo != null && profilerInfo.profileFd != null) {
17716                try {
17717                    profilerInfo.profileFd.close();
17718                } catch (IOException e) {
17719                }
17720            }
17721        }
17722    }
17723
17724    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17725        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17726                userId, true, ALLOW_FULL_ONLY, callName, null);
17727        ProcessRecord proc = null;
17728        try {
17729            int pid = Integer.parseInt(process);
17730            synchronized (mPidsSelfLocked) {
17731                proc = mPidsSelfLocked.get(pid);
17732            }
17733        } catch (NumberFormatException e) {
17734        }
17735
17736        if (proc == null) {
17737            ArrayMap<String, SparseArray<ProcessRecord>> all
17738                    = mProcessNames.getMap();
17739            SparseArray<ProcessRecord> procs = all.get(process);
17740            if (procs != null && procs.size() > 0) {
17741                proc = procs.valueAt(0);
17742                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17743                    for (int i=1; i<procs.size(); i++) {
17744                        ProcessRecord thisProc = procs.valueAt(i);
17745                        if (thisProc.userId == userId) {
17746                            proc = thisProc;
17747                            break;
17748                        }
17749                    }
17750                }
17751            }
17752        }
17753
17754        return proc;
17755    }
17756
17757    public boolean dumpHeap(String process, int userId, boolean managed,
17758            String path, ParcelFileDescriptor fd) throws RemoteException {
17759
17760        try {
17761            synchronized (this) {
17762                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17763                // its own permission (same as profileControl).
17764                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17765                        != PackageManager.PERMISSION_GRANTED) {
17766                    throw new SecurityException("Requires permission "
17767                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17768                }
17769
17770                if (fd == null) {
17771                    throw new IllegalArgumentException("null fd");
17772                }
17773
17774                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17775                if (proc == null || proc.thread == null) {
17776                    throw new IllegalArgumentException("Unknown process: " + process);
17777                }
17778
17779                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17780                if (!isDebuggable) {
17781                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17782                        throw new SecurityException("Process not debuggable: " + proc);
17783                    }
17784                }
17785
17786                proc.thread.dumpHeap(managed, path, fd);
17787                fd = null;
17788                return true;
17789            }
17790        } catch (RemoteException e) {
17791            throw new IllegalStateException("Process disappeared");
17792        } finally {
17793            if (fd != null) {
17794                try {
17795                    fd.close();
17796                } catch (IOException e) {
17797                }
17798            }
17799        }
17800    }
17801
17802    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17803    public void monitor() {
17804        synchronized (this) { }
17805    }
17806
17807    void onCoreSettingsChange(Bundle settings) {
17808        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17809            ProcessRecord processRecord = mLruProcesses.get(i);
17810            try {
17811                if (processRecord.thread != null) {
17812                    processRecord.thread.setCoreSettings(settings);
17813                }
17814            } catch (RemoteException re) {
17815                /* ignore */
17816            }
17817        }
17818    }
17819
17820    // Multi-user methods
17821
17822    /**
17823     * Start user, if its not already running, but don't bring it to foreground.
17824     */
17825    @Override
17826    public boolean startUserInBackground(final int userId) {
17827        return startUser(userId, /* foreground */ false);
17828    }
17829
17830    /**
17831     * Start user, if its not already running, and bring it to foreground.
17832     */
17833    boolean startUserInForeground(final int userId, Dialog dlg) {
17834        boolean result = startUser(userId, /* foreground */ true);
17835        dlg.dismiss();
17836        return result;
17837    }
17838
17839    /**
17840     * Refreshes the list of users related to the current user when either a
17841     * user switch happens or when a new related user is started in the
17842     * background.
17843     */
17844    private void updateCurrentProfileIdsLocked() {
17845        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17846                mCurrentUserId, false /* enabledOnly */);
17847        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17848        for (int i = 0; i < currentProfileIds.length; i++) {
17849            currentProfileIds[i] = profiles.get(i).id;
17850        }
17851        mCurrentProfileIds = currentProfileIds;
17852
17853        synchronized (mUserProfileGroupIdsSelfLocked) {
17854            mUserProfileGroupIdsSelfLocked.clear();
17855            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17856            for (int i = 0; i < users.size(); i++) {
17857                UserInfo user = users.get(i);
17858                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17859                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17860                }
17861            }
17862        }
17863    }
17864
17865    private Set getProfileIdsLocked(int userId) {
17866        Set userIds = new HashSet<Integer>();
17867        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17868                userId, false /* enabledOnly */);
17869        for (UserInfo user : profiles) {
17870            userIds.add(Integer.valueOf(user.id));
17871        }
17872        return userIds;
17873    }
17874
17875    @Override
17876    public boolean switchUser(final int userId) {
17877        String userName;
17878        synchronized (this) {
17879            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17880            if (userInfo == null) {
17881                Slog.w(TAG, "No user info for user #" + userId);
17882                return false;
17883            }
17884            if (userInfo.isManagedProfile()) {
17885                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17886                return false;
17887            }
17888            userName = userInfo.name;
17889        }
17890        mHandler.removeMessages(START_USER_SWITCH_MSG);
17891        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17892        return true;
17893    }
17894
17895    private void showUserSwitchDialog(int userId, String userName) {
17896        // The dialog will show and then initiate the user switch by calling startUserInForeground
17897        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17898                true /* above system */);
17899        d.show();
17900    }
17901
17902    private boolean startUser(final int userId, final boolean foreground) {
17903        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17904                != PackageManager.PERMISSION_GRANTED) {
17905            String msg = "Permission Denial: switchUser() from pid="
17906                    + Binder.getCallingPid()
17907                    + ", uid=" + Binder.getCallingUid()
17908                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17909            Slog.w(TAG, msg);
17910            throw new SecurityException(msg);
17911        }
17912
17913        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17914
17915        final long ident = Binder.clearCallingIdentity();
17916        try {
17917            synchronized (this) {
17918                final int oldUserId = mCurrentUserId;
17919                if (oldUserId == userId) {
17920                    return true;
17921                }
17922
17923                mStackSupervisor.setLockTaskModeLocked(null, false);
17924
17925                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17926                if (userInfo == null) {
17927                    Slog.w(TAG, "No user info for user #" + userId);
17928                    return false;
17929                }
17930                if (foreground && userInfo.isManagedProfile()) {
17931                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17932                    return false;
17933                }
17934
17935                if (foreground) {
17936                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17937                            R.anim.screen_user_enter);
17938                }
17939
17940                boolean needStart = false;
17941
17942                // If the user we are switching to is not currently started, then
17943                // we need to start it now.
17944                if (mStartedUsers.get(userId) == null) {
17945                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17946                    updateStartedUserArrayLocked();
17947                    needStart = true;
17948                }
17949
17950                final Integer userIdInt = Integer.valueOf(userId);
17951                mUserLru.remove(userIdInt);
17952                mUserLru.add(userIdInt);
17953
17954                if (foreground) {
17955                    mCurrentUserId = userId;
17956                    updateCurrentProfileIdsLocked();
17957                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17958                    // Once the internal notion of the active user has switched, we lock the device
17959                    // with the option to show the user switcher on the keyguard.
17960                    mWindowManager.lockNow(null);
17961                } else {
17962                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17963                    updateCurrentProfileIdsLocked();
17964                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17965                    mUserLru.remove(currentUserIdInt);
17966                    mUserLru.add(currentUserIdInt);
17967                }
17968
17969                final UserStartedState uss = mStartedUsers.get(userId);
17970
17971                // Make sure user is in the started state.  If it is currently
17972                // stopping, we need to knock that off.
17973                if (uss.mState == UserStartedState.STATE_STOPPING) {
17974                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17975                    // so we can just fairly silently bring the user back from
17976                    // the almost-dead.
17977                    uss.mState = UserStartedState.STATE_RUNNING;
17978                    updateStartedUserArrayLocked();
17979                    needStart = true;
17980                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17981                    // This means ACTION_SHUTDOWN has been sent, so we will
17982                    // need to treat this as a new boot of the user.
17983                    uss.mState = UserStartedState.STATE_BOOTING;
17984                    updateStartedUserArrayLocked();
17985                    needStart = true;
17986                }
17987
17988                if (uss.mState == UserStartedState.STATE_BOOTING) {
17989                    // Booting up a new user, need to tell system services about it.
17990                    // Note that this is on the same handler as scheduling of broadcasts,
17991                    // which is important because it needs to go first.
17992                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17993                }
17994
17995                if (foreground) {
17996                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17997                            oldUserId));
17998                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17999                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18000                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18001                            oldUserId, userId, uss));
18002                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18003                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18004                }
18005
18006                if (needStart) {
18007                    // Send USER_STARTED broadcast
18008                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18009                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18010                            | Intent.FLAG_RECEIVER_FOREGROUND);
18011                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18012                    broadcastIntentLocked(null, null, intent,
18013                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18014                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18015                }
18016
18017                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18018                    if (userId != UserHandle.USER_OWNER) {
18019                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18020                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18021                        broadcastIntentLocked(null, null, intent, null,
18022                                new IIntentReceiver.Stub() {
18023                                    public void performReceive(Intent intent, int resultCode,
18024                                            String data, Bundle extras, boolean ordered,
18025                                            boolean sticky, int sendingUser) {
18026                                        onUserInitialized(uss, foreground, oldUserId, userId);
18027                                    }
18028                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18029                                true, false, MY_PID, Process.SYSTEM_UID,
18030                                userId);
18031                        uss.initializing = true;
18032                    } else {
18033                        getUserManagerLocked().makeInitialized(userInfo.id);
18034                    }
18035                }
18036
18037                if (foreground) {
18038                    if (!uss.initializing) {
18039                        moveUserToForeground(uss, oldUserId, userId);
18040                    }
18041                } else {
18042                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18043                }
18044
18045                if (needStart) {
18046                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18047                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18048                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18049                    broadcastIntentLocked(null, null, intent,
18050                            null, new IIntentReceiver.Stub() {
18051                                @Override
18052                                public void performReceive(Intent intent, int resultCode, String data,
18053                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18054                                        throws RemoteException {
18055                                }
18056                            }, 0, null, null,
18057                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18058                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18059                }
18060            }
18061        } finally {
18062            Binder.restoreCallingIdentity(ident);
18063        }
18064
18065        return true;
18066    }
18067
18068    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18069        long ident = Binder.clearCallingIdentity();
18070        try {
18071            Intent intent;
18072            if (oldUserId >= 0) {
18073                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18074                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18075                int count = profiles.size();
18076                for (int i = 0; i < count; i++) {
18077                    int profileUserId = profiles.get(i).id;
18078                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18079                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18080                            | Intent.FLAG_RECEIVER_FOREGROUND);
18081                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18082                    broadcastIntentLocked(null, null, intent,
18083                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18084                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18085                }
18086            }
18087            if (newUserId >= 0) {
18088                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18089                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18090                int count = profiles.size();
18091                for (int i = 0; i < count; i++) {
18092                    int profileUserId = profiles.get(i).id;
18093                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18094                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18095                            | Intent.FLAG_RECEIVER_FOREGROUND);
18096                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18097                    broadcastIntentLocked(null, null, intent,
18098                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18099                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18100                }
18101                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18102                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18103                        | Intent.FLAG_RECEIVER_FOREGROUND);
18104                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18105                broadcastIntentLocked(null, null, intent,
18106                        null, null, 0, null, null,
18107                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18108                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18109            }
18110        } finally {
18111            Binder.restoreCallingIdentity(ident);
18112        }
18113    }
18114
18115    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18116            final int newUserId) {
18117        final int N = mUserSwitchObservers.beginBroadcast();
18118        if (N > 0) {
18119            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18120                int mCount = 0;
18121                @Override
18122                public void sendResult(Bundle data) throws RemoteException {
18123                    synchronized (ActivityManagerService.this) {
18124                        if (mCurUserSwitchCallback == this) {
18125                            mCount++;
18126                            if (mCount == N) {
18127                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18128                            }
18129                        }
18130                    }
18131                }
18132            };
18133            synchronized (this) {
18134                uss.switching = true;
18135                mCurUserSwitchCallback = callback;
18136            }
18137            for (int i=0; i<N; i++) {
18138                try {
18139                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18140                            newUserId, callback);
18141                } catch (RemoteException e) {
18142                }
18143            }
18144        } else {
18145            synchronized (this) {
18146                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18147            }
18148        }
18149        mUserSwitchObservers.finishBroadcast();
18150    }
18151
18152    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18153        synchronized (this) {
18154            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18155            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18156        }
18157    }
18158
18159    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18160        mCurUserSwitchCallback = null;
18161        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18162        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18163                oldUserId, newUserId, uss));
18164    }
18165
18166    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18167        synchronized (this) {
18168            if (foreground) {
18169                moveUserToForeground(uss, oldUserId, newUserId);
18170            }
18171        }
18172
18173        completeSwitchAndInitalize(uss, newUserId, true, false);
18174    }
18175
18176    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18177        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18178        if (homeInFront) {
18179            startHomeActivityLocked(newUserId);
18180        } else {
18181            mStackSupervisor.resumeTopActivitiesLocked();
18182        }
18183        EventLogTags.writeAmSwitchUser(newUserId);
18184        getUserManagerLocked().userForeground(newUserId);
18185        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18186    }
18187
18188    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18189        completeSwitchAndInitalize(uss, newUserId, false, true);
18190    }
18191
18192    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18193            boolean clearInitializing, boolean clearSwitching) {
18194        boolean unfrozen = false;
18195        synchronized (this) {
18196            if (clearInitializing) {
18197                uss.initializing = false;
18198                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18199            }
18200            if (clearSwitching) {
18201                uss.switching = false;
18202            }
18203            if (!uss.switching && !uss.initializing) {
18204                mWindowManager.stopFreezingScreen();
18205                unfrozen = true;
18206            }
18207        }
18208        if (unfrozen) {
18209            final int N = mUserSwitchObservers.beginBroadcast();
18210            for (int i=0; i<N; i++) {
18211                try {
18212                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18213                } catch (RemoteException e) {
18214                }
18215            }
18216            mUserSwitchObservers.finishBroadcast();
18217        }
18218    }
18219
18220    void scheduleStartProfilesLocked() {
18221        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18222            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18223                    DateUtils.SECOND_IN_MILLIS);
18224        }
18225    }
18226
18227    void startProfilesLocked() {
18228        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18229        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18230                mCurrentUserId, false /* enabledOnly */);
18231        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18232        for (UserInfo user : profiles) {
18233            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18234                    && user.id != mCurrentUserId) {
18235                toStart.add(user);
18236            }
18237        }
18238        final int n = toStart.size();
18239        int i = 0;
18240        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18241            startUserInBackground(toStart.get(i).id);
18242        }
18243        if (i < n) {
18244            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18245        }
18246    }
18247
18248    void finishUserBoot(UserStartedState uss) {
18249        synchronized (this) {
18250            if (uss.mState == UserStartedState.STATE_BOOTING
18251                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18252                uss.mState = UserStartedState.STATE_RUNNING;
18253                final int userId = uss.mHandle.getIdentifier();
18254                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18255                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18256                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18257                broadcastIntentLocked(null, null, intent,
18258                        null, null, 0, null, null,
18259                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18260                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18261            }
18262        }
18263    }
18264
18265    void finishUserSwitch(UserStartedState uss) {
18266        synchronized (this) {
18267            finishUserBoot(uss);
18268
18269            startProfilesLocked();
18270
18271            int num = mUserLru.size();
18272            int i = 0;
18273            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18274                Integer oldUserId = mUserLru.get(i);
18275                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18276                if (oldUss == null) {
18277                    // Shouldn't happen, but be sane if it does.
18278                    mUserLru.remove(i);
18279                    num--;
18280                    continue;
18281                }
18282                if (oldUss.mState == UserStartedState.STATE_STOPPING
18283                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18284                    // This user is already stopping, doesn't count.
18285                    num--;
18286                    i++;
18287                    continue;
18288                }
18289                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18290                    // Owner and current can't be stopped, but count as running.
18291                    i++;
18292                    continue;
18293                }
18294                // This is a user to be stopped.
18295                stopUserLocked(oldUserId, null);
18296                num--;
18297                i++;
18298            }
18299        }
18300    }
18301
18302    @Override
18303    public int stopUser(final int userId, final IStopUserCallback callback) {
18304        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18305                != PackageManager.PERMISSION_GRANTED) {
18306            String msg = "Permission Denial: switchUser() from pid="
18307                    + Binder.getCallingPid()
18308                    + ", uid=" + Binder.getCallingUid()
18309                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18310            Slog.w(TAG, msg);
18311            throw new SecurityException(msg);
18312        }
18313        if (userId <= 0) {
18314            throw new IllegalArgumentException("Can't stop primary user " + userId);
18315        }
18316        synchronized (this) {
18317            return stopUserLocked(userId, callback);
18318        }
18319    }
18320
18321    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18322        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18323        if (mCurrentUserId == userId) {
18324            return ActivityManager.USER_OP_IS_CURRENT;
18325        }
18326
18327        final UserStartedState uss = mStartedUsers.get(userId);
18328        if (uss == null) {
18329            // User is not started, nothing to do...  but we do need to
18330            // callback if requested.
18331            if (callback != null) {
18332                mHandler.post(new Runnable() {
18333                    @Override
18334                    public void run() {
18335                        try {
18336                            callback.userStopped(userId);
18337                        } catch (RemoteException e) {
18338                        }
18339                    }
18340                });
18341            }
18342            return ActivityManager.USER_OP_SUCCESS;
18343        }
18344
18345        if (callback != null) {
18346            uss.mStopCallbacks.add(callback);
18347        }
18348
18349        if (uss.mState != UserStartedState.STATE_STOPPING
18350                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18351            uss.mState = UserStartedState.STATE_STOPPING;
18352            updateStartedUserArrayLocked();
18353
18354            long ident = Binder.clearCallingIdentity();
18355            try {
18356                // We are going to broadcast ACTION_USER_STOPPING and then
18357                // once that is done send a final ACTION_SHUTDOWN and then
18358                // stop the user.
18359                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18360                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18361                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18362                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18363                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18364                // This is the result receiver for the final shutdown broadcast.
18365                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18366                    @Override
18367                    public void performReceive(Intent intent, int resultCode, String data,
18368                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18369                        finishUserStop(uss);
18370                    }
18371                };
18372                // This is the result receiver for the initial stopping broadcast.
18373                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18374                    @Override
18375                    public void performReceive(Intent intent, int resultCode, String data,
18376                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18377                        // On to the next.
18378                        synchronized (ActivityManagerService.this) {
18379                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18380                                // Whoops, we are being started back up.  Abort, abort!
18381                                return;
18382                            }
18383                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18384                        }
18385                        mBatteryStatsService.noteEvent(
18386                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18387                                Integer.toString(userId), userId);
18388                        mSystemServiceManager.stopUser(userId);
18389                        broadcastIntentLocked(null, null, shutdownIntent,
18390                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18391                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18392                    }
18393                };
18394                // Kick things off.
18395                broadcastIntentLocked(null, null, stoppingIntent,
18396                        null, stoppingReceiver, 0, null, null,
18397                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18398                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18399            } finally {
18400                Binder.restoreCallingIdentity(ident);
18401            }
18402        }
18403
18404        return ActivityManager.USER_OP_SUCCESS;
18405    }
18406
18407    void finishUserStop(UserStartedState uss) {
18408        final int userId = uss.mHandle.getIdentifier();
18409        boolean stopped;
18410        ArrayList<IStopUserCallback> callbacks;
18411        synchronized (this) {
18412            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18413            if (mStartedUsers.get(userId) != uss) {
18414                stopped = false;
18415            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18416                stopped = false;
18417            } else {
18418                stopped = true;
18419                // User can no longer run.
18420                mStartedUsers.remove(userId);
18421                mUserLru.remove(Integer.valueOf(userId));
18422                updateStartedUserArrayLocked();
18423
18424                // Clean up all state and processes associated with the user.
18425                // Kill all the processes for the user.
18426                forceStopUserLocked(userId, "finish user");
18427            }
18428
18429            // Explicitly remove the old information in mRecentTasks.
18430            removeRecentTasksForUserLocked(userId);
18431        }
18432
18433        for (int i=0; i<callbacks.size(); i++) {
18434            try {
18435                if (stopped) callbacks.get(i).userStopped(userId);
18436                else callbacks.get(i).userStopAborted(userId);
18437            } catch (RemoteException e) {
18438            }
18439        }
18440
18441        if (stopped) {
18442            mSystemServiceManager.cleanupUser(userId);
18443            synchronized (this) {
18444                mStackSupervisor.removeUserLocked(userId);
18445            }
18446        }
18447    }
18448
18449    @Override
18450    public UserInfo getCurrentUser() {
18451        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18452                != PackageManager.PERMISSION_GRANTED) && (
18453                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18454                != PackageManager.PERMISSION_GRANTED)) {
18455            String msg = "Permission Denial: getCurrentUser() from pid="
18456                    + Binder.getCallingPid()
18457                    + ", uid=" + Binder.getCallingUid()
18458                    + " requires " + INTERACT_ACROSS_USERS;
18459            Slog.w(TAG, msg);
18460            throw new SecurityException(msg);
18461        }
18462        synchronized (this) {
18463            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18464        }
18465    }
18466
18467    int getCurrentUserIdLocked() {
18468        return mCurrentUserId;
18469    }
18470
18471    @Override
18472    public boolean isUserRunning(int userId, boolean orStopped) {
18473        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18474                != PackageManager.PERMISSION_GRANTED) {
18475            String msg = "Permission Denial: isUserRunning() from pid="
18476                    + Binder.getCallingPid()
18477                    + ", uid=" + Binder.getCallingUid()
18478                    + " requires " + INTERACT_ACROSS_USERS;
18479            Slog.w(TAG, msg);
18480            throw new SecurityException(msg);
18481        }
18482        synchronized (this) {
18483            return isUserRunningLocked(userId, orStopped);
18484        }
18485    }
18486
18487    boolean isUserRunningLocked(int userId, boolean orStopped) {
18488        UserStartedState state = mStartedUsers.get(userId);
18489        if (state == null) {
18490            return false;
18491        }
18492        if (orStopped) {
18493            return true;
18494        }
18495        return state.mState != UserStartedState.STATE_STOPPING
18496                && state.mState != UserStartedState.STATE_SHUTDOWN;
18497    }
18498
18499    @Override
18500    public int[] getRunningUserIds() {
18501        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18502                != PackageManager.PERMISSION_GRANTED) {
18503            String msg = "Permission Denial: isUserRunning() from pid="
18504                    + Binder.getCallingPid()
18505                    + ", uid=" + Binder.getCallingUid()
18506                    + " requires " + INTERACT_ACROSS_USERS;
18507            Slog.w(TAG, msg);
18508            throw new SecurityException(msg);
18509        }
18510        synchronized (this) {
18511            return mStartedUserArray;
18512        }
18513    }
18514
18515    private void updateStartedUserArrayLocked() {
18516        int num = 0;
18517        for (int i=0; i<mStartedUsers.size();  i++) {
18518            UserStartedState uss = mStartedUsers.valueAt(i);
18519            // This list does not include stopping users.
18520            if (uss.mState != UserStartedState.STATE_STOPPING
18521                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18522                num++;
18523            }
18524        }
18525        mStartedUserArray = new int[num];
18526        num = 0;
18527        for (int i=0; i<mStartedUsers.size();  i++) {
18528            UserStartedState uss = mStartedUsers.valueAt(i);
18529            if (uss.mState != UserStartedState.STATE_STOPPING
18530                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18531                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18532                num++;
18533            }
18534        }
18535    }
18536
18537    @Override
18538    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18539        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18540                != PackageManager.PERMISSION_GRANTED) {
18541            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18542                    + Binder.getCallingPid()
18543                    + ", uid=" + Binder.getCallingUid()
18544                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18545            Slog.w(TAG, msg);
18546            throw new SecurityException(msg);
18547        }
18548
18549        mUserSwitchObservers.register(observer);
18550    }
18551
18552    @Override
18553    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18554        mUserSwitchObservers.unregister(observer);
18555    }
18556
18557    private boolean userExists(int userId) {
18558        if (userId == 0) {
18559            return true;
18560        }
18561        UserManagerService ums = getUserManagerLocked();
18562        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18563    }
18564
18565    int[] getUsersLocked() {
18566        UserManagerService ums = getUserManagerLocked();
18567        return ums != null ? ums.getUserIds() : new int[] { 0 };
18568    }
18569
18570    UserManagerService getUserManagerLocked() {
18571        if (mUserManager == null) {
18572            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18573            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18574        }
18575        return mUserManager;
18576    }
18577
18578    private int applyUserId(int uid, int userId) {
18579        return UserHandle.getUid(userId, uid);
18580    }
18581
18582    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18583        if (info == null) return null;
18584        ApplicationInfo newInfo = new ApplicationInfo(info);
18585        newInfo.uid = applyUserId(info.uid, userId);
18586        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18587                + info.packageName;
18588        return newInfo;
18589    }
18590
18591    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18592        if (aInfo == null
18593                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18594            return aInfo;
18595        }
18596
18597        ActivityInfo info = new ActivityInfo(aInfo);
18598        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18599        return info;
18600    }
18601
18602    private final class LocalService extends ActivityManagerInternal {
18603        @Override
18604        public void goingToSleep() {
18605            ActivityManagerService.this.goingToSleep();
18606        }
18607
18608        @Override
18609        public void wakingUp() {
18610            ActivityManagerService.this.wakingUp();
18611        }
18612
18613        @Override
18614        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18615                String processName, String abiOverride, int uid, Runnable crashHandler) {
18616            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18617                    processName, abiOverride, uid, crashHandler);
18618        }
18619    }
18620
18621    /**
18622     * An implementation of IAppTask, that allows an app to manage its own tasks via
18623     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18624     * only the process that calls getAppTasks() can call the AppTask methods.
18625     */
18626    class AppTaskImpl extends IAppTask.Stub {
18627        private int mTaskId;
18628        private int mCallingUid;
18629
18630        public AppTaskImpl(int taskId, int callingUid) {
18631            mTaskId = taskId;
18632            mCallingUid = callingUid;
18633        }
18634
18635        private void checkCaller() {
18636            if (mCallingUid != Binder.getCallingUid()) {
18637                throw new SecurityException("Caller " + mCallingUid
18638                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18639            }
18640        }
18641
18642        @Override
18643        public void finishAndRemoveTask() {
18644            checkCaller();
18645
18646            synchronized (ActivityManagerService.this) {
18647                long origId = Binder.clearCallingIdentity();
18648                try {
18649                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18650                    if (tr == null) {
18651                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18652                    }
18653                    // Only kill the process if we are not a new document
18654                    int flags = tr.getBaseIntent().getFlags();
18655                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18656                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18657                    removeTaskByIdLocked(mTaskId,
18658                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18659                } finally {
18660                    Binder.restoreCallingIdentity(origId);
18661                }
18662            }
18663        }
18664
18665        @Override
18666        public ActivityManager.RecentTaskInfo getTaskInfo() {
18667            checkCaller();
18668
18669            synchronized (ActivityManagerService.this) {
18670                long origId = Binder.clearCallingIdentity();
18671                try {
18672                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18673                    if (tr == null) {
18674                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18675                    }
18676                    return createRecentTaskInfoFromTaskRecord(tr);
18677                } finally {
18678                    Binder.restoreCallingIdentity(origId);
18679                }
18680            }
18681        }
18682
18683        @Override
18684        public void moveToFront() {
18685            checkCaller();
18686
18687            final TaskRecord tr;
18688            synchronized (ActivityManagerService.this) {
18689                tr = recentTaskForIdLocked(mTaskId);
18690                if (tr == null) {
18691                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18692                }
18693                if (tr.getRootActivity() != null) {
18694                    long origId = Binder.clearCallingIdentity();
18695                    try {
18696                        moveTaskToFrontLocked(tr.taskId, 0, null);
18697                        return;
18698                    } finally {
18699                        Binder.restoreCallingIdentity(origId);
18700                    }
18701                }
18702            }
18703
18704            startActivityFromRecentsInner(tr.taskId, null);
18705        }
18706
18707        @Override
18708        public int startActivity(IBinder whoThread, String callingPackage,
18709                Intent intent, String resolvedType, Bundle options) {
18710            checkCaller();
18711
18712            int callingUser = UserHandle.getCallingUserId();
18713            TaskRecord tr;
18714            IApplicationThread appThread;
18715            synchronized (ActivityManagerService.this) {
18716                tr = recentTaskForIdLocked(mTaskId);
18717                if (tr == null) {
18718                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18719                }
18720                appThread = ApplicationThreadNative.asInterface(whoThread);
18721                if (appThread == null) {
18722                    throw new IllegalArgumentException("Bad app thread " + appThread);
18723                }
18724            }
18725            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18726                    resolvedType, null, null, null, null, 0, 0, null, null,
18727                    null, options, callingUser, null, tr);
18728        }
18729
18730        @Override
18731        public void setExcludeFromRecents(boolean exclude) {
18732            checkCaller();
18733
18734            synchronized (ActivityManagerService.this) {
18735                long origId = Binder.clearCallingIdentity();
18736                try {
18737                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18738                    if (tr == null) {
18739                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18740                    }
18741                    Intent intent = tr.getBaseIntent();
18742                    if (exclude) {
18743                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18744                    } else {
18745                        intent.setFlags(intent.getFlags()
18746                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18747                    }
18748                } finally {
18749                    Binder.restoreCallingIdentity(origId);
18750                }
18751            }
18752        }
18753    }
18754}
18755