ActivityManagerService.java revision a7a61594df2f0b6ee9e3577f3d928e5f01ab4a75
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.provider.Settings;
184import android.text.format.DateUtils;
185import android.text.format.Time;
186import android.util.AtomicFile;
187import android.util.EventLog;
188import android.util.Log;
189import android.util.Pair;
190import android.util.PrintWriterPrinter;
191import android.util.Slog;
192import android.util.SparseArray;
193import android.util.TimeUtils;
194import android.util.Xml;
195import android.view.Gravity;
196import android.view.LayoutInflater;
197import android.view.View;
198import android.view.WindowManager;
199
200import java.io.BufferedInputStream;
201import java.io.BufferedOutputStream;
202import java.io.DataInputStream;
203import java.io.DataOutputStream;
204import java.io.File;
205import java.io.FileDescriptor;
206import java.io.FileInputStream;
207import java.io.FileNotFoundException;
208import java.io.FileOutputStream;
209import java.io.IOException;
210import java.io.InputStreamReader;
211import java.io.PrintWriter;
212import java.io.StringWriter;
213import java.lang.ref.WeakReference;
214import java.util.ArrayList;
215import java.util.Arrays;
216import java.util.Collections;
217import java.util.Comparator;
218import java.util.HashMap;
219import java.util.HashSet;
220import java.util.Iterator;
221import java.util.List;
222import java.util.Locale;
223import java.util.Map;
224import java.util.Set;
225import java.util.concurrent.atomic.AtomicBoolean;
226import java.util.concurrent.atomic.AtomicLong;
227
228public final class ActivityManagerService extends ActivityManagerNative
229        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
230
231    private static final String USER_DATA_DIR = "/data/user/";
232    // File that stores last updated system version and called preboot receivers
233    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
234
235    static final String TAG = "ActivityManager";
236    static final String TAG_MU = "ActivityManagerServiceMU";
237    static final boolean DEBUG = false;
238    static final boolean localLOGV = DEBUG;
239    static final boolean DEBUG_BACKUP = localLOGV || false;
240    static final boolean DEBUG_BROADCAST = localLOGV || false;
241    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
242    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
243    static final boolean DEBUG_CLEANUP = localLOGV || false;
244    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
245    static final boolean DEBUG_FOCUS = false;
246    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
247    static final boolean DEBUG_MU = localLOGV || false;
248    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
249    static final boolean DEBUG_LRU = localLOGV || false;
250    static final boolean DEBUG_PAUSE = localLOGV || false;
251    static final boolean DEBUG_POWER = localLOGV || false;
252    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
253    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
254    static final boolean DEBUG_PROCESSES = localLOGV || false;
255    static final boolean DEBUG_PROVIDER = localLOGV || false;
256    static final boolean DEBUG_RESULTS = localLOGV || false;
257    static final boolean DEBUG_SERVICE = localLOGV || false;
258    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
259    static final boolean DEBUG_STACK = localLOGV || false;
260    static final boolean DEBUG_SWITCH = localLOGV || false;
261    static final boolean DEBUG_TASKS = localLOGV || false;
262    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
263    static final boolean DEBUG_TRANSITION = localLOGV || false;
264    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
265    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
266    static final boolean DEBUG_VISBILITY = localLOGV || false;
267    static final boolean DEBUG_PSS = localLOGV || false;
268    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
269    static final boolean DEBUG_RECENTS = localLOGV || false;
270    static final boolean VALIDATE_TOKENS = false;
271    static final boolean SHOW_ACTIVITY_START_TIME = true;
272
273    // Control over CPU and battery monitoring.
274    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
275    static final boolean MONITOR_CPU_USAGE = true;
276    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
277    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
278    static final boolean MONITOR_THREAD_CPU_USAGE = false;
279
280    // The flags that are set for all calls we make to the package manager.
281    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
282
283    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
284
285    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
286
287    // Maximum number recent bitmaps to keep in memory.
288    static final int MAX_RECENT_BITMAPS = 5;
289
290    // Amount of time after a call to stopAppSwitches() during which we will
291    // prevent further untrusted switches from happening.
292    static final long APP_SWITCH_DELAY_TIME = 5*1000;
293
294    // How long we wait for a launched process to attach to the activity manager
295    // before we decide it's never going to come up for real.
296    static final int PROC_START_TIMEOUT = 10*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real, when the process was
300    // started with a wrapper for instrumentation (such as Valgrind) because it
301    // could take much longer than usual.
302    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
303
304    // How long to wait after going idle before forcing apps to GC.
305    static final int GC_TIMEOUT = 5*1000;
306
307    // The minimum amount of time between successive GC requests for a process.
308    static final int GC_MIN_INTERVAL = 60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process.
311    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
312
313    // The minimum amount of time between successive PSS requests for a process
314    // when the request is due to the memory state being lowered.
315    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
316
317    // The rate at which we check for apps using excessive power -- 15 mins.
318    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
319
320    // The minimum sample duration we will allow before deciding we have
321    // enough data on wake locks to start killing things.
322    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on CPU usage to start killing things.
326    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // How long we allow a receiver to run before giving up on it.
329    static final int BROADCAST_FG_TIMEOUT = 10*1000;
330    static final int BROADCAST_BG_TIMEOUT = 60*1000;
331
332    // How long we wait until we timeout on key dispatching.
333    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
334
335    // How long we wait until we timeout on key dispatching during instrumentation.
336    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
337
338    // Amount of time we wait for observers to handle a user switch before
339    // giving up on them and unfreezing the screen.
340    static final int USER_SWITCH_TIMEOUT = 2*1000;
341
342    // Maximum number of users we allow to be running at a time.
343    static final int MAX_RUNNING_USERS = 3;
344
345    // How long to wait in getAssistContextExtras for the activity and foreground services
346    // to respond with the result.
347    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
348
349    // Maximum number of persisted Uri grants a package is allowed
350    static final int MAX_PERSISTED_URI_GRANTS = 128;
351
352    static final int MY_PID = Process.myPid();
353
354    static final String[] EMPTY_STRING_ARRAY = new String[0];
355
356    // How many bytes to write into the dropbox log before truncating
357    static final int DROPBOX_MAX_SIZE = 256 * 1024;
358
359    // Access modes for handleIncomingUser.
360    static final int ALLOW_NON_FULL = 0;
361    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
362    static final int ALLOW_FULL_ONLY = 2;
363
364    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
365
366    /** All system services */
367    SystemServiceManager mSystemServiceManager;
368
369    /** Run all ActivityStacks through this */
370    ActivityStackSupervisor mStackSupervisor;
371
372    public IntentFirewall mIntentFirewall;
373
374    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
375    // default actuion automatically.  Important for devices without direct input
376    // devices.
377    private boolean mShowDialogs = true;
378
379    BroadcastQueue mFgBroadcastQueue;
380    BroadcastQueue mBgBroadcastQueue;
381    // Convenient for easy iteration over the queues. Foreground is first
382    // so that dispatch of foreground broadcasts gets precedence.
383    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
384
385    BroadcastQueue broadcastQueueForIntent(Intent intent) {
386        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
387        if (DEBUG_BACKGROUND_BROADCAST) {
388            Slog.i(TAG, "Broadcast intent " + intent + " on "
389                    + (isFg ? "foreground" : "background")
390                    + " queue");
391        }
392        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
393    }
394
395    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
396        for (BroadcastQueue queue : mBroadcastQueues) {
397            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
398            if (r != null) {
399                return r;
400            }
401        }
402        return null;
403    }
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    ActivityRecord mFocusedActivity = null;
409
410    /**
411     * List of intents that were used to start the most recent tasks.
412     */
413    ArrayList<TaskRecord> mRecentTasks;
414    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
415
416    /**
417     * For addAppTask: cached of the last activity component that was added.
418     */
419    ComponentName mLastAddedTaskComponent;
420
421    /**
422     * For addAppTask: cached of the last activity uid that was added.
423     */
424    int mLastAddedTaskUid;
425
426    /**
427     * For addAppTask: cached of the last ActivityInfo that was added.
428     */
429    ActivityInfo mLastAddedTaskActivity;
430
431    public class PendingAssistExtras extends Binder implements Runnable {
432        public final ActivityRecord activity;
433        public boolean haveResult = false;
434        public Bundle result = null;
435        public PendingAssistExtras(ActivityRecord _activity) {
436            activity = _activity;
437        }
438        @Override
439        public void run() {
440            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
441            synchronized (this) {
442                haveResult = true;
443                notifyAll();
444            }
445        }
446    }
447
448    final ArrayList<PendingAssistExtras> mPendingAssistExtras
449            = new ArrayList<PendingAssistExtras>();
450
451    /**
452     * Process management.
453     */
454    final ProcessList mProcessList = new ProcessList();
455
456    /**
457     * All of the applications we currently have running organized by name.
458     * The keys are strings of the application package name (as
459     * returned by the package manager), and the keys are ApplicationRecord
460     * objects.
461     */
462    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
463
464    /**
465     * Tracking long-term execution of processes to look for abuse and other
466     * bad app behavior.
467     */
468    final ProcessStatsService mProcessStats;
469
470    /**
471     * The currently running isolated processes.
472     */
473    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
474
475    /**
476     * Counter for assigning isolated process uids, to avoid frequently reusing the
477     * same ones.
478     */
479    int mNextIsolatedProcessUid = 0;
480
481    /**
482     * The currently running heavy-weight process, if any.
483     */
484    ProcessRecord mHeavyWeightProcess = null;
485
486    /**
487     * The last time that various processes have crashed.
488     */
489    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
490
491    /**
492     * Information about a process that is currently marked as bad.
493     */
494    static final class BadProcessInfo {
495        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
496            this.time = time;
497            this.shortMsg = shortMsg;
498            this.longMsg = longMsg;
499            this.stack = stack;
500        }
501
502        final long time;
503        final String shortMsg;
504        final String longMsg;
505        final String stack;
506    }
507
508    /**
509     * Set of applications that we consider to be bad, and will reject
510     * incoming broadcasts from (which the user has no control over).
511     * Processes are added to this set when they have crashed twice within
512     * a minimum amount of time; they are removed from it when they are
513     * later restarted (hopefully due to some user action).  The value is the
514     * time it was added to the list.
515     */
516    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
517
518    /**
519     * All of the processes we currently have running organized by pid.
520     * The keys are the pid running the application.
521     *
522     * <p>NOTE: This object is protected by its own lock, NOT the global
523     * activity manager lock!
524     */
525    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
526
527    /**
528     * All of the processes that have been forced to be foreground.  The key
529     * is the pid of the caller who requested it (we hold a death
530     * link on it).
531     */
532    abstract class ForegroundToken implements IBinder.DeathRecipient {
533        int pid;
534        IBinder token;
535    }
536    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
537
538    /**
539     * List of records for processes that someone had tried to start before the
540     * system was ready.  We don't start them at that point, but ensure they
541     * are started by the time booting is complete.
542     */
543    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
544
545    /**
546     * List of persistent applications that are in the process
547     * of being started.
548     */
549    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
550
551    /**
552     * Processes that are being forcibly torn down.
553     */
554    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
555
556    /**
557     * List of running applications, sorted by recent usage.
558     * The first entry in the list is the least recently used.
559     */
560    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
561
562    /**
563     * Where in mLruProcesses that the processes hosting activities start.
564     */
565    int mLruProcessActivityStart = 0;
566
567    /**
568     * Where in mLruProcesses that the processes hosting services start.
569     * This is after (lower index) than mLruProcessesActivityStart.
570     */
571    int mLruProcessServiceStart = 0;
572
573    /**
574     * List of processes that should gc as soon as things are idle.
575     */
576    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes we want to collect PSS data from.
580     */
581    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * Last time we requested PSS data of all processes.
585     */
586    long mLastFullPssTime = SystemClock.uptimeMillis();
587
588    /**
589     * If set, the next time we collect PSS data we should do a full collection
590     * with data from native processes and the kernel.
591     */
592    boolean mFullPssPending = false;
593
594    /**
595     * This is the process holding what we currently consider to be
596     * the "home" activity.
597     */
598    ProcessRecord mHomeProcess;
599
600    /**
601     * This is the process holding the activity the user last visited that
602     * is in a different process from the one they are currently in.
603     */
604    ProcessRecord mPreviousProcess;
605
606    /**
607     * The time at which the previous process was last visible.
608     */
609    long mPreviousProcessVisibleTime;
610
611    /**
612     * Which uses have been started, so are allowed to run code.
613     */
614    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
615
616    /**
617     * LRU list of history of current users.  Most recently current is at the end.
618     */
619    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
620
621    /**
622     * Constant array of the users that are currently started.
623     */
624    int[] mStartedUserArray = new int[] { 0 };
625
626    /**
627     * Registered observers of the user switching mechanics.
628     */
629    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
630            = new RemoteCallbackList<IUserSwitchObserver>();
631
632    /**
633     * Currently active user switch.
634     */
635    Object mCurUserSwitchCallback;
636
637    /**
638     * Packages that the user has asked to have run in screen size
639     * compatibility mode instead of filling the screen.
640     */
641    final CompatModePackages mCompatModePackages;
642
643    /**
644     * Set of IntentSenderRecord objects that are currently active.
645     */
646    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
647            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
648
649    /**
650     * Fingerprints (hashCode()) of stack traces that we've
651     * already logged DropBox entries for.  Guarded by itself.  If
652     * something (rogue user app) forces this over
653     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
654     */
655    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
656    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
657
658    /**
659     * Strict Mode background batched logging state.
660     *
661     * The string buffer is guarded by itself, and its lock is also
662     * used to determine if another batched write is already
663     * in-flight.
664     */
665    private final StringBuilder mStrictModeBuffer = new StringBuilder();
666
667    /**
668     * Keeps track of all IIntentReceivers that have been registered for
669     * broadcasts.  Hash keys are the receiver IBinder, hash value is
670     * a ReceiverList.
671     */
672    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
673            new HashMap<IBinder, ReceiverList>();
674
675    /**
676     * Resolver for broadcast intents to registered receivers.
677     * Holds BroadcastFilter (subclass of IntentFilter).
678     */
679    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
680            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
681        @Override
682        protected boolean allowFilterResult(
683                BroadcastFilter filter, List<BroadcastFilter> dest) {
684            IBinder target = filter.receiverList.receiver.asBinder();
685            for (int i=dest.size()-1; i>=0; i--) {
686                if (dest.get(i).receiverList.receiver.asBinder() == target) {
687                    return false;
688                }
689            }
690            return true;
691        }
692
693        @Override
694        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
695            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
696                    || userId == filter.owningUserId) {
697                return super.newResult(filter, match, userId);
698            }
699            return null;
700        }
701
702        @Override
703        protected BroadcastFilter[] newArray(int size) {
704            return new BroadcastFilter[size];
705        }
706
707        @Override
708        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
709            return packageName.equals(filter.packageName);
710        }
711    };
712
713    /**
714     * State of all active sticky broadcasts per user.  Keys are the action of the
715     * sticky Intent, values are an ArrayList of all broadcasted intents with
716     * that action (which should usually be one).  The SparseArray is keyed
717     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
718     * for stickies that are sent to all users.
719     */
720    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
721            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
722
723    final ActiveServices mServices;
724
725    /**
726     * Backup/restore process management
727     */
728    String mBackupAppName = null;
729    BackupRecord mBackupTarget = null;
730
731    final ProviderMap mProviderMap;
732
733    /**
734     * List of content providers who have clients waiting for them.  The
735     * application is currently being launched and the provider will be
736     * removed from this list once it is published.
737     */
738    final ArrayList<ContentProviderRecord> mLaunchingProviders
739            = new ArrayList<ContentProviderRecord>();
740
741    /**
742     * File storing persisted {@link #mGrantedUriPermissions}.
743     */
744    private final AtomicFile mGrantFile;
745
746    /** XML constants used in {@link #mGrantFile} */
747    private static final String TAG_URI_GRANTS = "uri-grants";
748    private static final String TAG_URI_GRANT = "uri-grant";
749    private static final String ATTR_USER_HANDLE = "userHandle";
750    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
751    private static final String ATTR_TARGET_USER_ID = "targetUserId";
752    private static final String ATTR_SOURCE_PKG = "sourcePkg";
753    private static final String ATTR_TARGET_PKG = "targetPkg";
754    private static final String ATTR_URI = "uri";
755    private static final String ATTR_MODE_FLAGS = "modeFlags";
756    private static final String ATTR_CREATED_TIME = "createdTime";
757    private static final String ATTR_PREFIX = "prefix";
758
759    /**
760     * Global set of specific {@link Uri} permissions that have been granted.
761     * This optimized lookup structure maps from {@link UriPermission#targetUid}
762     * to {@link UriPermission#uri} to {@link UriPermission}.
763     */
764    @GuardedBy("this")
765    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
766            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
767
768    public static class GrantUri {
769        public final int sourceUserId;
770        public final Uri uri;
771        public boolean prefix;
772
773        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
774            this.sourceUserId = sourceUserId;
775            this.uri = uri;
776            this.prefix = prefix;
777        }
778
779        @Override
780        public int hashCode() {
781            return toString().hashCode();
782        }
783
784        @Override
785        public boolean equals(Object o) {
786            if (o instanceof GrantUri) {
787                GrantUri other = (GrantUri) o;
788                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
789                        && prefix == other.prefix;
790            }
791            return false;
792        }
793
794        @Override
795        public String toString() {
796            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
797            if (prefix) result += " [prefix]";
798            return result;
799        }
800
801        public String toSafeString() {
802            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
803            if (prefix) result += " [prefix]";
804            return result;
805        }
806
807        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
808            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
809                    ContentProvider.getUriWithoutUserId(uri), false);
810        }
811    }
812
813    CoreSettingsObserver mCoreSettingsObserver;
814
815    /**
816     * Thread-local storage used to carry caller permissions over through
817     * indirect content-provider access.
818     */
819    private class Identity {
820        public int pid;
821        public int uid;
822
823        Identity(int _pid, int _uid) {
824            pid = _pid;
825            uid = _uid;
826        }
827    }
828
829    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
830
831    /**
832     * All information we have collected about the runtime performance of
833     * any user id that can impact battery performance.
834     */
835    final BatteryStatsService mBatteryStatsService;
836
837    /**
838     * Information about component usage
839     */
840    UsageStatsManagerInternal mUsageStatsService;
841
842    /**
843     * Information about and control over application operations
844     */
845    final AppOpsService mAppOpsService;
846
847    /**
848     * Save recent tasks information across reboots.
849     */
850    final TaskPersister mTaskPersister;
851
852    /**
853     * Current configuration information.  HistoryRecord objects are given
854     * a reference to this object to indicate which configuration they are
855     * currently running in, so this object must be kept immutable.
856     */
857    Configuration mConfiguration = new Configuration();
858
859    /**
860     * Current sequencing integer of the configuration, for skipping old
861     * configurations.
862     */
863    int mConfigurationSeq = 0;
864
865    /**
866     * Hardware-reported OpenGLES version.
867     */
868    final int GL_ES_VERSION;
869
870    /**
871     * List of initialization arguments to pass to all processes when binding applications to them.
872     * For example, references to the commonly used services.
873     */
874    HashMap<String, IBinder> mAppBindArgs;
875
876    /**
877     * Temporary to avoid allocations.  Protected by main lock.
878     */
879    final StringBuilder mStringBuilder = new StringBuilder(256);
880
881    /**
882     * Used to control how we initialize the service.
883     */
884    ComponentName mTopComponent;
885    String mTopAction = Intent.ACTION_MAIN;
886    String mTopData;
887    boolean mProcessesReady = false;
888    boolean mSystemReady = false;
889    boolean mBooting = false;
890    boolean mWaitingUpdate = false;
891    boolean mDidUpdate = false;
892    boolean mOnBattery = false;
893    boolean mLaunchWarningShown = false;
894
895    Context mContext;
896
897    int mFactoryTest;
898
899    boolean mCheckedForSetup;
900
901    /**
902     * The time at which we will allow normal application switches again,
903     * after a call to {@link #stopAppSwitches()}.
904     */
905    long mAppSwitchesAllowedTime;
906
907    /**
908     * This is set to true after the first switch after mAppSwitchesAllowedTime
909     * is set; any switches after that will clear the time.
910     */
911    boolean mDidAppSwitch;
912
913    /**
914     * Last time (in realtime) at which we checked for power usage.
915     */
916    long mLastPowerCheckRealtime;
917
918    /**
919     * Last time (in uptime) at which we checked for power usage.
920     */
921    long mLastPowerCheckUptime;
922
923    /**
924     * Set while we are wanting to sleep, to prevent any
925     * activities from being started/resumed.
926     */
927    private boolean mSleeping = false;
928
929    /**
930     * Set while we are running a voice interaction.  This overrides
931     * sleeping while it is active.
932     */
933    private boolean mRunningVoice = false;
934
935    /**
936     * State of external calls telling us if the device is asleep.
937     */
938    private boolean mWentToSleep = false;
939
940    /**
941     * State of external call telling us if the lock screen is shown.
942     */
943    private boolean mLockScreenShown = false;
944
945    /**
946     * Set if we are shutting down the system, similar to sleeping.
947     */
948    boolean mShuttingDown = false;
949
950    /**
951     * Current sequence id for oom_adj computation traversal.
952     */
953    int mAdjSeq = 0;
954
955    /**
956     * Current sequence id for process LRU updating.
957     */
958    int mLruSeq = 0;
959
960    /**
961     * Keep track of the non-cached/empty process we last found, to help
962     * determine how to distribute cached/empty processes next time.
963     */
964    int mNumNonCachedProcs = 0;
965
966    /**
967     * Keep track of the number of cached hidden procs, to balance oom adj
968     * distribution between those and empty procs.
969     */
970    int mNumCachedHiddenProcs = 0;
971
972    /**
973     * Keep track of the number of service processes we last found, to
974     * determine on the next iteration which should be B services.
975     */
976    int mNumServiceProcs = 0;
977    int mNewNumAServiceProcs = 0;
978    int mNewNumServiceProcs = 0;
979
980    /**
981     * Allow the current computed overall memory level of the system to go down?
982     * This is set to false when we are killing processes for reasons other than
983     * memory management, so that the now smaller process list will not be taken as
984     * an indication that memory is tighter.
985     */
986    boolean mAllowLowerMemLevel = false;
987
988    /**
989     * The last computed memory level, for holding when we are in a state that
990     * processes are going away for other reasons.
991     */
992    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
993
994    /**
995     * The last total number of process we have, to determine if changes actually look
996     * like a shrinking number of process due to lower RAM.
997     */
998    int mLastNumProcesses;
999
1000    /**
1001     * The uptime of the last time we performed idle maintenance.
1002     */
1003    long mLastIdleTime = SystemClock.uptimeMillis();
1004
1005    /**
1006     * Total time spent with RAM that has been added in the past since the last idle time.
1007     */
1008    long mLowRamTimeSinceLastIdle = 0;
1009
1010    /**
1011     * If RAM is currently low, when that horrible situation started.
1012     */
1013    long mLowRamStartTime = 0;
1014
1015    /**
1016     * For reporting to battery stats the current top application.
1017     */
1018    private String mCurResumedPackage = null;
1019    private int mCurResumedUid = -1;
1020
1021    /**
1022     * For reporting to battery stats the apps currently running foreground
1023     * service.  The ProcessMap is package/uid tuples; each of these contain
1024     * an array of the currently foreground processes.
1025     */
1026    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1027            = new ProcessMap<ArrayList<ProcessRecord>>();
1028
1029    /**
1030     * This is set if we had to do a delayed dexopt of an app before launching
1031     * it, to increase the ANR timeouts in that case.
1032     */
1033    boolean mDidDexOpt;
1034
1035    /**
1036     * Set if the systemServer made a call to enterSafeMode.
1037     */
1038    boolean mSafeMode;
1039
1040    String mDebugApp = null;
1041    boolean mWaitForDebugger = false;
1042    boolean mDebugTransient = false;
1043    String mOrigDebugApp = null;
1044    boolean mOrigWaitForDebugger = false;
1045    boolean mAlwaysFinishActivities = false;
1046    IActivityController mController = null;
1047    String mProfileApp = null;
1048    ProcessRecord mProfileProc = null;
1049    String mProfileFile;
1050    ParcelFileDescriptor mProfileFd;
1051    int mSamplingInterval = 0;
1052    boolean mAutoStopProfiler = false;
1053    int mProfileType = 0;
1054    String mOpenGlTraceApp = null;
1055
1056    static class ProcessChangeItem {
1057        static final int CHANGE_ACTIVITIES = 1<<0;
1058        static final int CHANGE_PROCESS_STATE = 1<<1;
1059        int changes;
1060        int uid;
1061        int pid;
1062        int processState;
1063        boolean foregroundActivities;
1064    }
1065
1066    final RemoteCallbackList<IProcessObserver> mProcessObservers
1067            = new RemoteCallbackList<IProcessObserver>();
1068    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1069
1070    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1071            = new ArrayList<ProcessChangeItem>();
1072    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1073            = new ArrayList<ProcessChangeItem>();
1074
1075    /**
1076     * Runtime CPU use collection thread.  This object's lock is used to
1077     * protect all related state.
1078     */
1079    final Thread mProcessCpuThread;
1080
1081    /**
1082     * Used to collect process stats when showing not responding dialog.
1083     * Protected by mProcessCpuThread.
1084     */
1085    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1086            MONITOR_THREAD_CPU_USAGE);
1087    final AtomicLong mLastCpuTime = new AtomicLong(0);
1088    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1089
1090    long mLastWriteTime = 0;
1091
1092    /**
1093     * Used to retain an update lock when the foreground activity is in
1094     * immersive mode.
1095     */
1096    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1097
1098    /**
1099     * Set to true after the system has finished booting.
1100     */
1101    boolean mBooted = false;
1102
1103    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1104    int mProcessLimitOverride = -1;
1105
1106    WindowManagerService mWindowManager;
1107
1108    final ActivityThread mSystemThread;
1109
1110    // Holds the current foreground user's id
1111    int mCurrentUserId = 0;
1112    // Holds the target user's id during a user switch
1113    int mTargetUserId = UserHandle.USER_NULL;
1114    // If there are multiple profiles for the current user, their ids are here
1115    // Currently only the primary user can have managed profiles
1116    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1117
1118    /**
1119     * Mapping from each known user ID to the profile group ID it is associated with.
1120     */
1121    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1122
1123    private UserManagerService mUserManager;
1124
1125    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1126        final ProcessRecord mApp;
1127        final int mPid;
1128        final IApplicationThread mAppThread;
1129
1130        AppDeathRecipient(ProcessRecord app, int pid,
1131                IApplicationThread thread) {
1132            if (localLOGV) Slog.v(
1133                TAG, "New death recipient " + this
1134                + " for thread " + thread.asBinder());
1135            mApp = app;
1136            mPid = pid;
1137            mAppThread = thread;
1138        }
1139
1140        @Override
1141        public void binderDied() {
1142            if (localLOGV) Slog.v(
1143                TAG, "Death received in " + this
1144                + " for thread " + mAppThread.asBinder());
1145            synchronized(ActivityManagerService.this) {
1146                appDiedLocked(mApp, mPid, mAppThread);
1147            }
1148        }
1149    }
1150
1151    static final int SHOW_ERROR_MSG = 1;
1152    static final int SHOW_NOT_RESPONDING_MSG = 2;
1153    static final int SHOW_FACTORY_ERROR_MSG = 3;
1154    static final int UPDATE_CONFIGURATION_MSG = 4;
1155    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1156    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1157    static final int SERVICE_TIMEOUT_MSG = 12;
1158    static final int UPDATE_TIME_ZONE = 13;
1159    static final int SHOW_UID_ERROR_MSG = 14;
1160    static final int IM_FEELING_LUCKY_MSG = 15;
1161    static final int PROC_START_TIMEOUT_MSG = 20;
1162    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1163    static final int KILL_APPLICATION_MSG = 22;
1164    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1165    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1166    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1167    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1168    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1169    static final int CLEAR_DNS_CACHE_MSG = 28;
1170    static final int UPDATE_HTTP_PROXY_MSG = 29;
1171    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1172    static final int DISPATCH_PROCESSES_CHANGED = 31;
1173    static final int DISPATCH_PROCESS_DIED = 32;
1174    static final int REPORT_MEM_USAGE_MSG = 33;
1175    static final int REPORT_USER_SWITCH_MSG = 34;
1176    static final int CONTINUE_USER_SWITCH_MSG = 35;
1177    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1178    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1179    static final int PERSIST_URI_GRANTS_MSG = 38;
1180    static final int REQUEST_ALL_PSS_MSG = 39;
1181    static final int START_PROFILES_MSG = 40;
1182    static final int UPDATE_TIME = 41;
1183    static final int SYSTEM_USER_START_MSG = 42;
1184    static final int SYSTEM_USER_CURRENT_MSG = 43;
1185    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1186    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1187    static final int START_USER_SWITCH_MSG = 46;
1188
1189    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1190    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1191    static final int FIRST_COMPAT_MODE_MSG = 300;
1192    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1193
1194    AlertDialog mUidAlert;
1195    CompatModeDialog mCompatModeDialog;
1196    long mLastMemUsageReportTime = 0;
1197
1198    private LockToAppRequestDialog mLockToAppRequest;
1199
1200    /**
1201     * Flag whether the current user is a "monkey", i.e. whether
1202     * the UI is driven by a UI automation tool.
1203     */
1204    private boolean mUserIsMonkey;
1205
1206    /** Flag whether the device has a Recents UI */
1207    boolean mHasRecents;
1208
1209    /** The dimensions of the thumbnails in the Recents UI. */
1210    int mThumbnailWidth;
1211    int mThumbnailHeight;
1212
1213    final ServiceThread mHandlerThread;
1214    final MainHandler mHandler;
1215
1216    final class MainHandler extends Handler {
1217        public MainHandler(Looper looper) {
1218            super(looper, null, true);
1219        }
1220
1221        @Override
1222        public void handleMessage(Message msg) {
1223            switch (msg.what) {
1224            case SHOW_ERROR_MSG: {
1225                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1226                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1227                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1228                synchronized (ActivityManagerService.this) {
1229                    ProcessRecord proc = (ProcessRecord)data.get("app");
1230                    AppErrorResult res = (AppErrorResult) data.get("result");
1231                    if (proc != null && proc.crashDialog != null) {
1232                        Slog.e(TAG, "App already has crash dialog: " + proc);
1233                        if (res != null) {
1234                            res.set(0);
1235                        }
1236                        return;
1237                    }
1238                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1239                            >= Process.FIRST_APPLICATION_UID
1240                            && proc.pid != MY_PID);
1241                    for (int userId : mCurrentProfileIds) {
1242                        isBackground &= (proc.userId != userId);
1243                    }
1244                    if (isBackground && !showBackground) {
1245                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1246                        if (res != null) {
1247                            res.set(0);
1248                        }
1249                        return;
1250                    }
1251                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1252                        Dialog d = new AppErrorDialog(mContext,
1253                                ActivityManagerService.this, res, proc);
1254                        d.show();
1255                        proc.crashDialog = d;
1256                    } else {
1257                        // The device is asleep, so just pretend that the user
1258                        // saw a crash dialog and hit "force quit".
1259                        if (res != null) {
1260                            res.set(0);
1261                        }
1262                    }
1263                }
1264
1265                ensureBootCompleted();
1266            } break;
1267            case SHOW_NOT_RESPONDING_MSG: {
1268                synchronized (ActivityManagerService.this) {
1269                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1270                    ProcessRecord proc = (ProcessRecord)data.get("app");
1271                    if (proc != null && proc.anrDialog != null) {
1272                        Slog.e(TAG, "App already has anr dialog: " + proc);
1273                        return;
1274                    }
1275
1276                    Intent intent = new Intent("android.intent.action.ANR");
1277                    if (!mProcessesReady) {
1278                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1279                                | Intent.FLAG_RECEIVER_FOREGROUND);
1280                    }
1281                    broadcastIntentLocked(null, null, intent,
1282                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1283                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1284
1285                    if (mShowDialogs) {
1286                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1287                                mContext, proc, (ActivityRecord)data.get("activity"),
1288                                msg.arg1 != 0);
1289                        d.show();
1290                        proc.anrDialog = d;
1291                    } else {
1292                        // Just kill the app if there is no dialog to be shown.
1293                        killAppAtUsersRequest(proc, null);
1294                    }
1295                }
1296
1297                ensureBootCompleted();
1298            } break;
1299            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1300                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1301                synchronized (ActivityManagerService.this) {
1302                    ProcessRecord proc = (ProcessRecord) data.get("app");
1303                    if (proc == null) {
1304                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1305                        break;
1306                    }
1307                    if (proc.crashDialog != null) {
1308                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1309                        return;
1310                    }
1311                    AppErrorResult res = (AppErrorResult) data.get("result");
1312                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1313                        Dialog d = new StrictModeViolationDialog(mContext,
1314                                ActivityManagerService.this, res, proc);
1315                        d.show();
1316                        proc.crashDialog = d;
1317                    } else {
1318                        // The device is asleep, so just pretend that the user
1319                        // saw a crash dialog and hit "force quit".
1320                        res.set(0);
1321                    }
1322                }
1323                ensureBootCompleted();
1324            } break;
1325            case SHOW_FACTORY_ERROR_MSG: {
1326                Dialog d = new FactoryErrorDialog(
1327                    mContext, msg.getData().getCharSequence("msg"));
1328                d.show();
1329                ensureBootCompleted();
1330            } break;
1331            case UPDATE_CONFIGURATION_MSG: {
1332                final ContentResolver resolver = mContext.getContentResolver();
1333                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1334            } break;
1335            case GC_BACKGROUND_PROCESSES_MSG: {
1336                synchronized (ActivityManagerService.this) {
1337                    performAppGcsIfAppropriateLocked();
1338                }
1339            } break;
1340            case WAIT_FOR_DEBUGGER_MSG: {
1341                synchronized (ActivityManagerService.this) {
1342                    ProcessRecord app = (ProcessRecord)msg.obj;
1343                    if (msg.arg1 != 0) {
1344                        if (!app.waitedForDebugger) {
1345                            Dialog d = new AppWaitingForDebuggerDialog(
1346                                    ActivityManagerService.this,
1347                                    mContext, app);
1348                            app.waitDialog = d;
1349                            app.waitedForDebugger = true;
1350                            d.show();
1351                        }
1352                    } else {
1353                        if (app.waitDialog != null) {
1354                            app.waitDialog.dismiss();
1355                            app.waitDialog = null;
1356                        }
1357                    }
1358                }
1359            } break;
1360            case SERVICE_TIMEOUT_MSG: {
1361                if (mDidDexOpt) {
1362                    mDidDexOpt = false;
1363                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1364                    nmsg.obj = msg.obj;
1365                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1366                    return;
1367                }
1368                mServices.serviceTimeout((ProcessRecord)msg.obj);
1369            } break;
1370            case UPDATE_TIME_ZONE: {
1371                synchronized (ActivityManagerService.this) {
1372                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1373                        ProcessRecord r = mLruProcesses.get(i);
1374                        if (r.thread != null) {
1375                            try {
1376                                r.thread.updateTimeZone();
1377                            } catch (RemoteException ex) {
1378                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1379                            }
1380                        }
1381                    }
1382                }
1383            } break;
1384            case CLEAR_DNS_CACHE_MSG: {
1385                synchronized (ActivityManagerService.this) {
1386                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1387                        ProcessRecord r = mLruProcesses.get(i);
1388                        if (r.thread != null) {
1389                            try {
1390                                r.thread.clearDnsCache();
1391                            } catch (RemoteException ex) {
1392                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1393                            }
1394                        }
1395                    }
1396                }
1397            } break;
1398            case UPDATE_HTTP_PROXY_MSG: {
1399                ProxyInfo proxy = (ProxyInfo)msg.obj;
1400                String host = "";
1401                String port = "";
1402                String exclList = "";
1403                Uri pacFileUrl = Uri.EMPTY;
1404                if (proxy != null) {
1405                    host = proxy.getHost();
1406                    port = Integer.toString(proxy.getPort());
1407                    exclList = proxy.getExclusionListAsString();
1408                    pacFileUrl = proxy.getPacFileUrl();
1409                }
1410                synchronized (ActivityManagerService.this) {
1411                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1412                        ProcessRecord r = mLruProcesses.get(i);
1413                        if (r.thread != null) {
1414                            try {
1415                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1416                            } catch (RemoteException ex) {
1417                                Slog.w(TAG, "Failed to update http proxy for: " +
1418                                        r.info.processName);
1419                            }
1420                        }
1421                    }
1422                }
1423            } break;
1424            case SHOW_UID_ERROR_MSG: {
1425                String title = "System UIDs Inconsistent";
1426                String text = "UIDs on the system are inconsistent, you need to wipe your"
1427                        + " data partition or your device will be unstable.";
1428                Log.e(TAG, title + ": " + text);
1429                if (mShowDialogs) {
1430                    // XXX This is a temporary dialog, no need to localize.
1431                    AlertDialog d = new BaseErrorDialog(mContext);
1432                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1433                    d.setCancelable(false);
1434                    d.setTitle(title);
1435                    d.setMessage(text);
1436                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1437                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1438                    mUidAlert = d;
1439                    d.show();
1440                }
1441            } break;
1442            case IM_FEELING_LUCKY_MSG: {
1443                if (mUidAlert != null) {
1444                    mUidAlert.dismiss();
1445                    mUidAlert = null;
1446                }
1447            } break;
1448            case PROC_START_TIMEOUT_MSG: {
1449                if (mDidDexOpt) {
1450                    mDidDexOpt = false;
1451                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1452                    nmsg.obj = msg.obj;
1453                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1454                    return;
1455                }
1456                ProcessRecord app = (ProcessRecord)msg.obj;
1457                synchronized (ActivityManagerService.this) {
1458                    processStartTimedOutLocked(app);
1459                }
1460            } break;
1461            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1462                synchronized (ActivityManagerService.this) {
1463                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1464                }
1465            } break;
1466            case KILL_APPLICATION_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    int appid = msg.arg1;
1469                    boolean restart = (msg.arg2 == 1);
1470                    Bundle bundle = (Bundle)msg.obj;
1471                    String pkg = bundle.getString("pkg");
1472                    String reason = bundle.getString("reason");
1473                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1474                            false, UserHandle.USER_ALL, reason);
1475                }
1476            } break;
1477            case FINALIZE_PENDING_INTENT_MSG: {
1478                ((PendingIntentRecord)msg.obj).completeFinalize();
1479            } break;
1480            case POST_HEAVY_NOTIFICATION_MSG: {
1481                INotificationManager inm = NotificationManager.getService();
1482                if (inm == null) {
1483                    return;
1484                }
1485
1486                ActivityRecord root = (ActivityRecord)msg.obj;
1487                ProcessRecord process = root.app;
1488                if (process == null) {
1489                    return;
1490                }
1491
1492                try {
1493                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1494                    String text = mContext.getString(R.string.heavy_weight_notification,
1495                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1496                    Notification notification = new Notification();
1497                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1498                    notification.when = 0;
1499                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1500                    notification.tickerText = text;
1501                    notification.defaults = 0; // please be quiet
1502                    notification.sound = null;
1503                    notification.vibrate = null;
1504                    notification.color = mContext.getResources().getColor(
1505                            com.android.internal.R.color.system_notification_accent_color);
1506                    notification.setLatestEventInfo(context, text,
1507                            mContext.getText(R.string.heavy_weight_notification_detail),
1508                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1509                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1510                                    new UserHandle(root.userId)));
1511
1512                    try {
1513                        int[] outId = new int[1];
1514                        inm.enqueueNotificationWithTag("android", "android", null,
1515                                R.string.heavy_weight_notification,
1516                                notification, outId, root.userId);
1517                    } catch (RuntimeException e) {
1518                        Slog.w(ActivityManagerService.TAG,
1519                                "Error showing notification for heavy-weight app", e);
1520                    } catch (RemoteException e) {
1521                    }
1522                } catch (NameNotFoundException e) {
1523                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1524                }
1525            } break;
1526            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1527                INotificationManager inm = NotificationManager.getService();
1528                if (inm == null) {
1529                    return;
1530                }
1531                try {
1532                    inm.cancelNotificationWithTag("android", null,
1533                            R.string.heavy_weight_notification,  msg.arg1);
1534                } catch (RuntimeException e) {
1535                    Slog.w(ActivityManagerService.TAG,
1536                            "Error canceling notification for service", e);
1537                } catch (RemoteException e) {
1538                }
1539            } break;
1540            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1541                synchronized (ActivityManagerService.this) {
1542                    checkExcessivePowerUsageLocked(true);
1543                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1544                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1545                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1546                }
1547            } break;
1548            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1549                synchronized (ActivityManagerService.this) {
1550                    ActivityRecord ar = (ActivityRecord)msg.obj;
1551                    if (mCompatModeDialog != null) {
1552                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1553                                ar.info.applicationInfo.packageName)) {
1554                            return;
1555                        }
1556                        mCompatModeDialog.dismiss();
1557                        mCompatModeDialog = null;
1558                    }
1559                    if (ar != null && false) {
1560                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1561                                ar.packageName)) {
1562                            int mode = mCompatModePackages.computeCompatModeLocked(
1563                                    ar.info.applicationInfo);
1564                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1565                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1566                                mCompatModeDialog = new CompatModeDialog(
1567                                        ActivityManagerService.this, mContext,
1568                                        ar.info.applicationInfo);
1569                                mCompatModeDialog.show();
1570                            }
1571                        }
1572                    }
1573                }
1574                break;
1575            }
1576            case DISPATCH_PROCESSES_CHANGED: {
1577                dispatchProcessesChanged();
1578                break;
1579            }
1580            case DISPATCH_PROCESS_DIED: {
1581                final int pid = msg.arg1;
1582                final int uid = msg.arg2;
1583                dispatchProcessDied(pid, uid);
1584                break;
1585            }
1586            case REPORT_MEM_USAGE_MSG: {
1587                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1588                Thread thread = new Thread() {
1589                    @Override public void run() {
1590                        final SparseArray<ProcessMemInfo> infoMap
1591                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1592                        for (int i=0, N=memInfos.size(); i<N; i++) {
1593                            ProcessMemInfo mi = memInfos.get(i);
1594                            infoMap.put(mi.pid, mi);
1595                        }
1596                        updateCpuStatsNow();
1597                        synchronized (mProcessCpuThread) {
1598                            final int N = mProcessCpuTracker.countStats();
1599                            for (int i=0; i<N; i++) {
1600                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1601                                if (st.vsize > 0) {
1602                                    long pss = Debug.getPss(st.pid, null);
1603                                    if (pss > 0) {
1604                                        if (infoMap.indexOfKey(st.pid) < 0) {
1605                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1606                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1607                                            mi.pss = pss;
1608                                            memInfos.add(mi);
1609                                        }
1610                                    }
1611                                }
1612                            }
1613                        }
1614
1615                        long totalPss = 0;
1616                        for (int i=0, N=memInfos.size(); i<N; i++) {
1617                            ProcessMemInfo mi = memInfos.get(i);
1618                            if (mi.pss == 0) {
1619                                mi.pss = Debug.getPss(mi.pid, null);
1620                            }
1621                            totalPss += mi.pss;
1622                        }
1623                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1624                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1625                                if (lhs.oomAdj != rhs.oomAdj) {
1626                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1627                                }
1628                                if (lhs.pss != rhs.pss) {
1629                                    return lhs.pss < rhs.pss ? 1 : -1;
1630                                }
1631                                return 0;
1632                            }
1633                        });
1634
1635                        StringBuilder tag = new StringBuilder(128);
1636                        StringBuilder stack = new StringBuilder(128);
1637                        tag.append("Low on memory -- ");
1638                        appendMemBucket(tag, totalPss, "total", false);
1639                        appendMemBucket(stack, totalPss, "total", true);
1640
1641                        StringBuilder logBuilder = new StringBuilder(1024);
1642                        logBuilder.append("Low on memory:\n");
1643
1644                        boolean firstLine = true;
1645                        int lastOomAdj = Integer.MIN_VALUE;
1646                        for (int i=0, N=memInfos.size(); i<N; i++) {
1647                            ProcessMemInfo mi = memInfos.get(i);
1648
1649                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1650                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1651                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1652                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1653                                if (lastOomAdj != mi.oomAdj) {
1654                                    lastOomAdj = mi.oomAdj;
1655                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1656                                        tag.append(" / ");
1657                                    }
1658                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1659                                        if (firstLine) {
1660                                            stack.append(":");
1661                                            firstLine = false;
1662                                        }
1663                                        stack.append("\n\t at ");
1664                                    } else {
1665                                        stack.append("$");
1666                                    }
1667                                } else {
1668                                    tag.append(" ");
1669                                    stack.append("$");
1670                                }
1671                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1672                                    appendMemBucket(tag, mi.pss, mi.name, false);
1673                                }
1674                                appendMemBucket(stack, mi.pss, mi.name, true);
1675                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1676                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1677                                    stack.append("(");
1678                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1679                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1680                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1681                                            stack.append(":");
1682                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1683                                        }
1684                                    }
1685                                    stack.append(")");
1686                                }
1687                            }
1688
1689                            logBuilder.append("  ");
1690                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1691                            logBuilder.append(' ');
1692                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1693                            logBuilder.append(' ');
1694                            ProcessList.appendRamKb(logBuilder, mi.pss);
1695                            logBuilder.append(" kB: ");
1696                            logBuilder.append(mi.name);
1697                            logBuilder.append(" (");
1698                            logBuilder.append(mi.pid);
1699                            logBuilder.append(") ");
1700                            logBuilder.append(mi.adjType);
1701                            logBuilder.append('\n');
1702                            if (mi.adjReason != null) {
1703                                logBuilder.append("                      ");
1704                                logBuilder.append(mi.adjReason);
1705                                logBuilder.append('\n');
1706                            }
1707                        }
1708
1709                        logBuilder.append("           ");
1710                        ProcessList.appendRamKb(logBuilder, totalPss);
1711                        logBuilder.append(" kB: TOTAL\n");
1712
1713                        long[] infos = new long[Debug.MEMINFO_COUNT];
1714                        Debug.getMemInfo(infos);
1715                        logBuilder.append("  MemInfo: ");
1716                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1717                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1718                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1719                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1720                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1721                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1722                            logBuilder.append("  ZRAM: ");
1723                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1724                            logBuilder.append(" kB RAM, ");
1725                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1726                            logBuilder.append(" kB swap total, ");
1727                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1728                            logBuilder.append(" kB swap free\n");
1729                        }
1730                        Slog.i(TAG, logBuilder.toString());
1731
1732                        StringBuilder dropBuilder = new StringBuilder(1024);
1733                        /*
1734                        StringWriter oomSw = new StringWriter();
1735                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1736                        StringWriter catSw = new StringWriter();
1737                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1738                        String[] emptyArgs = new String[] { };
1739                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1740                        oomPw.flush();
1741                        String oomString = oomSw.toString();
1742                        */
1743                        dropBuilder.append(stack);
1744                        dropBuilder.append('\n');
1745                        dropBuilder.append('\n');
1746                        dropBuilder.append(logBuilder);
1747                        dropBuilder.append('\n');
1748                        /*
1749                        dropBuilder.append(oomString);
1750                        dropBuilder.append('\n');
1751                        */
1752                        StringWriter catSw = new StringWriter();
1753                        synchronized (ActivityManagerService.this) {
1754                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1755                            String[] emptyArgs = new String[] { };
1756                            catPw.println();
1757                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1758                            catPw.println();
1759                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1760                                    false, false, null);
1761                            catPw.println();
1762                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1763                            catPw.flush();
1764                        }
1765                        dropBuilder.append(catSw.toString());
1766                        addErrorToDropBox("lowmem", null, "system_server", null,
1767                                null, tag.toString(), dropBuilder.toString(), null, null);
1768                        //Slog.i(TAG, "Sent to dropbox:");
1769                        //Slog.i(TAG, dropBuilder.toString());
1770                        synchronized (ActivityManagerService.this) {
1771                            long now = SystemClock.uptimeMillis();
1772                            if (mLastMemUsageReportTime < now) {
1773                                mLastMemUsageReportTime = now;
1774                            }
1775                        }
1776                    }
1777                };
1778                thread.start();
1779                break;
1780            }
1781            case START_USER_SWITCH_MSG: {
1782                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1783                break;
1784            }
1785            case REPORT_USER_SWITCH_MSG: {
1786                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1787                break;
1788            }
1789            case CONTINUE_USER_SWITCH_MSG: {
1790                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1791                break;
1792            }
1793            case USER_SWITCH_TIMEOUT_MSG: {
1794                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1795                break;
1796            }
1797            case IMMERSIVE_MODE_LOCK_MSG: {
1798                final boolean nextState = (msg.arg1 != 0);
1799                if (mUpdateLock.isHeld() != nextState) {
1800                    if (DEBUG_IMMERSIVE) {
1801                        final ActivityRecord r = (ActivityRecord) msg.obj;
1802                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1803                    }
1804                    if (nextState) {
1805                        mUpdateLock.acquire();
1806                    } else {
1807                        mUpdateLock.release();
1808                    }
1809                }
1810                break;
1811            }
1812            case PERSIST_URI_GRANTS_MSG: {
1813                writeGrantedUriPermissions();
1814                break;
1815            }
1816            case REQUEST_ALL_PSS_MSG: {
1817                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1818                break;
1819            }
1820            case START_PROFILES_MSG: {
1821                synchronized (ActivityManagerService.this) {
1822                    startProfilesLocked();
1823                }
1824                break;
1825            }
1826            case UPDATE_TIME: {
1827                synchronized (ActivityManagerService.this) {
1828                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1829                        ProcessRecord r = mLruProcesses.get(i);
1830                        if (r.thread != null) {
1831                            try {
1832                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1833                            } catch (RemoteException ex) {
1834                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1835                            }
1836                        }
1837                    }
1838                }
1839                break;
1840            }
1841            case SYSTEM_USER_START_MSG: {
1842                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1843                        Integer.toString(msg.arg1), msg.arg1);
1844                mSystemServiceManager.startUser(msg.arg1);
1845                break;
1846            }
1847            case SYSTEM_USER_CURRENT_MSG: {
1848                mBatteryStatsService.noteEvent(
1849                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1850                        Integer.toString(msg.arg2), msg.arg2);
1851                mBatteryStatsService.noteEvent(
1852                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1853                        Integer.toString(msg.arg1), msg.arg1);
1854                mSystemServiceManager.switchUser(msg.arg1);
1855                mLockToAppRequest.clearPrompt();
1856                break;
1857            }
1858            case ENTER_ANIMATION_COMPLETE_MSG: {
1859                synchronized (ActivityManagerService.this) {
1860                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1861                    if (r != null && r.app != null && r.app.thread != null) {
1862                        try {
1863                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1864                        } catch (RemoteException e) {
1865                        }
1866                    }
1867                }
1868                break;
1869            }
1870            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1871                enableScreenAfterBoot();
1872                break;
1873            }
1874            }
1875        }
1876    };
1877
1878    static final int COLLECT_PSS_BG_MSG = 1;
1879
1880    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1881        @Override
1882        public void handleMessage(Message msg) {
1883            switch (msg.what) {
1884            case COLLECT_PSS_BG_MSG: {
1885                long start = SystemClock.uptimeMillis();
1886                MemInfoReader memInfo = null;
1887                synchronized (ActivityManagerService.this) {
1888                    if (mFullPssPending) {
1889                        mFullPssPending = false;
1890                        memInfo = new MemInfoReader();
1891                    }
1892                }
1893                if (memInfo != null) {
1894                    updateCpuStatsNow();
1895                    long nativeTotalPss = 0;
1896                    synchronized (mProcessCpuThread) {
1897                        final int N = mProcessCpuTracker.countStats();
1898                        for (int j=0; j<N; j++) {
1899                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1900                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1901                                // This is definitely an application process; skip it.
1902                                continue;
1903                            }
1904                            synchronized (mPidsSelfLocked) {
1905                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1906                                    // This is one of our own processes; skip it.
1907                                    continue;
1908                                }
1909                            }
1910                            nativeTotalPss += Debug.getPss(st.pid, null);
1911                        }
1912                    }
1913                    memInfo.readMemInfo();
1914                    synchronized (this) {
1915                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1916                                + (SystemClock.uptimeMillis()-start) + "ms");
1917                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1918                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1919                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1920                                        +memInfo.getSlabSizeKb(),
1921                                nativeTotalPss);
1922                    }
1923                }
1924
1925                int i=0, num=0;
1926                long[] tmp = new long[1];
1927                do {
1928                    ProcessRecord proc;
1929                    int procState;
1930                    int pid;
1931                    synchronized (ActivityManagerService.this) {
1932                        if (i >= mPendingPssProcesses.size()) {
1933                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1934                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1935                            mPendingPssProcesses.clear();
1936                            return;
1937                        }
1938                        proc = mPendingPssProcesses.get(i);
1939                        procState = proc.pssProcState;
1940                        if (proc.thread != null && procState == proc.setProcState) {
1941                            pid = proc.pid;
1942                        } else {
1943                            proc = null;
1944                            pid = 0;
1945                        }
1946                        i++;
1947                    }
1948                    if (proc != null) {
1949                        long pss = Debug.getPss(pid, tmp);
1950                        synchronized (ActivityManagerService.this) {
1951                            if (proc.thread != null && proc.setProcState == procState
1952                                    && proc.pid == pid) {
1953                                num++;
1954                                proc.lastPssTime = SystemClock.uptimeMillis();
1955                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1956                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1957                                        + ": " + pss + " lastPss=" + proc.lastPss
1958                                        + " state=" + ProcessList.makeProcStateString(procState));
1959                                if (proc.initialIdlePss == 0) {
1960                                    proc.initialIdlePss = pss;
1961                                }
1962                                proc.lastPss = pss;
1963                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1964                                    proc.lastCachedPss = pss;
1965                                }
1966                            }
1967                        }
1968                    }
1969                } while (true);
1970            }
1971            }
1972        }
1973    };
1974
1975    /**
1976     * Monitor for package changes and update our internal state.
1977     */
1978    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1979        @Override
1980        public void onPackageRemoved(String packageName, int uid) {
1981            // Remove all tasks with activities in the specified package from the list of recent tasks
1982            synchronized (ActivityManagerService.this) {
1983                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1984                    TaskRecord tr = mRecentTasks.get(i);
1985                    ComponentName cn = tr.intent.getComponent();
1986                    if (cn != null && cn.getPackageName().equals(packageName)) {
1987                        // If the package name matches, remove the task and kill the process
1988                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1989                    }
1990                }
1991            }
1992        }
1993
1994        @Override
1995        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1996            onPackageModified(packageName);
1997            return true;
1998        }
1999
2000        @Override
2001        public void onPackageModified(String packageName) {
2002            final PackageManager pm = mContext.getPackageManager();
2003            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2004                    new ArrayList<Pair<Intent, Integer>>();
2005            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2006            // Copy the list of recent tasks so that we don't hold onto the lock on
2007            // ActivityManagerService for long periods while checking if components exist.
2008            synchronized (ActivityManagerService.this) {
2009                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2010                    TaskRecord tr = mRecentTasks.get(i);
2011                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2012                }
2013            }
2014            // Check the recent tasks and filter out all tasks with components that no longer exist.
2015            Intent tmpI = new Intent();
2016            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2017                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2018                ComponentName cn = p.first.getComponent();
2019                if (cn != null && cn.getPackageName().equals(packageName)) {
2020                    try {
2021                        // Add the task to the list to remove if the component no longer exists
2022                        tmpI.setComponent(cn);
2023                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2024                            tasksToRemove.add(p.second);
2025                        }
2026                    } catch (Exception e) {}
2027                }
2028            }
2029            // Prune all the tasks with removed components from the list of recent tasks
2030            synchronized (ActivityManagerService.this) {
2031                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2032                    // Remove the task but don't kill the process (since other components in that
2033                    // package may still be running and in the background)
2034                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2035                }
2036            }
2037        }
2038
2039        @Override
2040        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2041            // Force stop the specified packages
2042            if (packages != null) {
2043                for (String pkg : packages) {
2044                    synchronized (ActivityManagerService.this) {
2045                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2046                                "finished booting")) {
2047                            return true;
2048                        }
2049                    }
2050                }
2051            }
2052            return false;
2053        }
2054    };
2055
2056    public void setSystemProcess() {
2057        try {
2058            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2059            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2060            ServiceManager.addService("meminfo", new MemBinder(this));
2061            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2062            ServiceManager.addService("dbinfo", new DbBinder(this));
2063            if (MONITOR_CPU_USAGE) {
2064                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2065            }
2066            ServiceManager.addService("permission", new PermissionController(this));
2067
2068            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2069                    "android", STOCK_PM_FLAGS);
2070            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2071
2072            synchronized (this) {
2073                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2074                app.persistent = true;
2075                app.pid = MY_PID;
2076                app.maxAdj = ProcessList.SYSTEM_ADJ;
2077                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2078                mProcessNames.put(app.processName, app.uid, app);
2079                synchronized (mPidsSelfLocked) {
2080                    mPidsSelfLocked.put(app.pid, app);
2081                }
2082                updateLruProcessLocked(app, false, null);
2083                updateOomAdjLocked();
2084            }
2085        } catch (PackageManager.NameNotFoundException e) {
2086            throw new RuntimeException(
2087                    "Unable to find android system package", e);
2088        }
2089    }
2090
2091    public void setWindowManager(WindowManagerService wm) {
2092        mWindowManager = wm;
2093        mStackSupervisor.setWindowManager(wm);
2094    }
2095
2096    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2097        mUsageStatsService = usageStatsManager;
2098    }
2099
2100    public void startObservingNativeCrashes() {
2101        final NativeCrashListener ncl = new NativeCrashListener(this);
2102        ncl.start();
2103    }
2104
2105    public IAppOpsService getAppOpsService() {
2106        return mAppOpsService;
2107    }
2108
2109    static class MemBinder extends Binder {
2110        ActivityManagerService mActivityManagerService;
2111        MemBinder(ActivityManagerService activityManagerService) {
2112            mActivityManagerService = activityManagerService;
2113        }
2114
2115        @Override
2116        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2117            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2118                    != PackageManager.PERMISSION_GRANTED) {
2119                pw.println("Permission Denial: can't dump meminfo from from pid="
2120                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2121                        + " without permission " + android.Manifest.permission.DUMP);
2122                return;
2123            }
2124
2125            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2126        }
2127    }
2128
2129    static class GraphicsBinder extends Binder {
2130        ActivityManagerService mActivityManagerService;
2131        GraphicsBinder(ActivityManagerService activityManagerService) {
2132            mActivityManagerService = activityManagerService;
2133        }
2134
2135        @Override
2136        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2137            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2138                    != PackageManager.PERMISSION_GRANTED) {
2139                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2140                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2141                        + " without permission " + android.Manifest.permission.DUMP);
2142                return;
2143            }
2144
2145            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2146        }
2147    }
2148
2149    static class DbBinder extends Binder {
2150        ActivityManagerService mActivityManagerService;
2151        DbBinder(ActivityManagerService activityManagerService) {
2152            mActivityManagerService = activityManagerService;
2153        }
2154
2155        @Override
2156        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2157            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2158                    != PackageManager.PERMISSION_GRANTED) {
2159                pw.println("Permission Denial: can't dump dbinfo from from pid="
2160                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2161                        + " without permission " + android.Manifest.permission.DUMP);
2162                return;
2163            }
2164
2165            mActivityManagerService.dumpDbInfo(fd, pw, args);
2166        }
2167    }
2168
2169    static class CpuBinder extends Binder {
2170        ActivityManagerService mActivityManagerService;
2171        CpuBinder(ActivityManagerService activityManagerService) {
2172            mActivityManagerService = activityManagerService;
2173        }
2174
2175        @Override
2176        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2177            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2178                    != PackageManager.PERMISSION_GRANTED) {
2179                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2180                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2181                        + " without permission " + android.Manifest.permission.DUMP);
2182                return;
2183            }
2184
2185            synchronized (mActivityManagerService.mProcessCpuThread) {
2186                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2187                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2188                        SystemClock.uptimeMillis()));
2189            }
2190        }
2191    }
2192
2193    public static final class Lifecycle extends SystemService {
2194        private final ActivityManagerService mService;
2195
2196        public Lifecycle(Context context) {
2197            super(context);
2198            mService = new ActivityManagerService(context);
2199        }
2200
2201        @Override
2202        public void onStart() {
2203            mService.start();
2204        }
2205
2206        public ActivityManagerService getService() {
2207            return mService;
2208        }
2209    }
2210
2211    // Note: This method is invoked on the main thread but may need to attach various
2212    // handlers to other threads.  So take care to be explicit about the looper.
2213    public ActivityManagerService(Context systemContext) {
2214        mContext = systemContext;
2215        mFactoryTest = FactoryTest.getMode();
2216        mSystemThread = ActivityThread.currentActivityThread();
2217
2218        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2219
2220        mHandlerThread = new ServiceThread(TAG,
2221                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2222        mHandlerThread.start();
2223        mHandler = new MainHandler(mHandlerThread.getLooper());
2224
2225        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2226                "foreground", BROADCAST_FG_TIMEOUT, false);
2227        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2228                "background", BROADCAST_BG_TIMEOUT, true);
2229        mBroadcastQueues[0] = mFgBroadcastQueue;
2230        mBroadcastQueues[1] = mBgBroadcastQueue;
2231
2232        mServices = new ActiveServices(this);
2233        mProviderMap = new ProviderMap(this);
2234
2235        // TODO: Move creation of battery stats service outside of activity manager service.
2236        File dataDir = Environment.getDataDirectory();
2237        File systemDir = new File(dataDir, "system");
2238        systemDir.mkdirs();
2239        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2240        mBatteryStatsService.getActiveStatistics().readLocked();
2241        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2242        mOnBattery = DEBUG_POWER ? true
2243                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2244        mBatteryStatsService.getActiveStatistics().setCallback(this);
2245
2246        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2247
2248        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2249
2250        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2251
2252        // User 0 is the first and only user that runs at boot.
2253        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2254        mUserLru.add(Integer.valueOf(0));
2255        updateStartedUserArrayLocked();
2256
2257        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2258            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2259
2260        mConfiguration.setToDefaults();
2261        mConfiguration.setLocale(Locale.getDefault());
2262
2263        mConfigurationSeq = mConfiguration.seq = 1;
2264        mProcessCpuTracker.init();
2265
2266        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2267        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2268        mStackSupervisor = new ActivityStackSupervisor(this);
2269        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2270
2271        mProcessCpuThread = new Thread("CpuTracker") {
2272            @Override
2273            public void run() {
2274                while (true) {
2275                    try {
2276                        try {
2277                            synchronized(this) {
2278                                final long now = SystemClock.uptimeMillis();
2279                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2280                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2281                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2282                                //        + ", write delay=" + nextWriteDelay);
2283                                if (nextWriteDelay < nextCpuDelay) {
2284                                    nextCpuDelay = nextWriteDelay;
2285                                }
2286                                if (nextCpuDelay > 0) {
2287                                    mProcessCpuMutexFree.set(true);
2288                                    this.wait(nextCpuDelay);
2289                                }
2290                            }
2291                        } catch (InterruptedException e) {
2292                        }
2293                        updateCpuStatsNow();
2294                    } catch (Exception e) {
2295                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2296                    }
2297                }
2298            }
2299        };
2300
2301        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2302
2303        Watchdog.getInstance().addMonitor(this);
2304        Watchdog.getInstance().addThread(mHandler);
2305    }
2306
2307    public void setSystemServiceManager(SystemServiceManager mgr) {
2308        mSystemServiceManager = mgr;
2309    }
2310
2311    private void start() {
2312        Process.removeAllProcessGroups();
2313        mProcessCpuThread.start();
2314
2315        mBatteryStatsService.publish(mContext);
2316        mAppOpsService.publish(mContext);
2317        Slog.d("AppOps", "AppOpsService published");
2318        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2319    }
2320
2321    public void initPowerManagement() {
2322        mStackSupervisor.initPowerManagement();
2323        mBatteryStatsService.initPowerManagement();
2324    }
2325
2326    @Override
2327    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2328            throws RemoteException {
2329        if (code == SYSPROPS_TRANSACTION) {
2330            // We need to tell all apps about the system property change.
2331            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2332            synchronized(this) {
2333                final int NP = mProcessNames.getMap().size();
2334                for (int ip=0; ip<NP; ip++) {
2335                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2336                    final int NA = apps.size();
2337                    for (int ia=0; ia<NA; ia++) {
2338                        ProcessRecord app = apps.valueAt(ia);
2339                        if (app.thread != null) {
2340                            procs.add(app.thread.asBinder());
2341                        }
2342                    }
2343                }
2344            }
2345
2346            int N = procs.size();
2347            for (int i=0; i<N; i++) {
2348                Parcel data2 = Parcel.obtain();
2349                try {
2350                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2351                } catch (RemoteException e) {
2352                }
2353                data2.recycle();
2354            }
2355        }
2356        try {
2357            return super.onTransact(code, data, reply, flags);
2358        } catch (RuntimeException e) {
2359            // The activity manager only throws security exceptions, so let's
2360            // log all others.
2361            if (!(e instanceof SecurityException)) {
2362                Slog.wtf(TAG, "Activity Manager Crash", e);
2363            }
2364            throw e;
2365        }
2366    }
2367
2368    void updateCpuStats() {
2369        final long now = SystemClock.uptimeMillis();
2370        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2371            return;
2372        }
2373        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2374            synchronized (mProcessCpuThread) {
2375                mProcessCpuThread.notify();
2376            }
2377        }
2378    }
2379
2380    void updateCpuStatsNow() {
2381        synchronized (mProcessCpuThread) {
2382            mProcessCpuMutexFree.set(false);
2383            final long now = SystemClock.uptimeMillis();
2384            boolean haveNewCpuStats = false;
2385
2386            if (MONITOR_CPU_USAGE &&
2387                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2388                mLastCpuTime.set(now);
2389                haveNewCpuStats = true;
2390                mProcessCpuTracker.update();
2391                //Slog.i(TAG, mProcessCpu.printCurrentState());
2392                //Slog.i(TAG, "Total CPU usage: "
2393                //        + mProcessCpu.getTotalCpuPercent() + "%");
2394
2395                // Slog the cpu usage if the property is set.
2396                if ("true".equals(SystemProperties.get("events.cpu"))) {
2397                    int user = mProcessCpuTracker.getLastUserTime();
2398                    int system = mProcessCpuTracker.getLastSystemTime();
2399                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2400                    int irq = mProcessCpuTracker.getLastIrqTime();
2401                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2402                    int idle = mProcessCpuTracker.getLastIdleTime();
2403
2404                    int total = user + system + iowait + irq + softIrq + idle;
2405                    if (total == 0) total = 1;
2406
2407                    EventLog.writeEvent(EventLogTags.CPU,
2408                            ((user+system+iowait+irq+softIrq) * 100) / total,
2409                            (user * 100) / total,
2410                            (system * 100) / total,
2411                            (iowait * 100) / total,
2412                            (irq * 100) / total,
2413                            (softIrq * 100) / total);
2414                }
2415            }
2416
2417            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2418            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2419            synchronized(bstats) {
2420                synchronized(mPidsSelfLocked) {
2421                    if (haveNewCpuStats) {
2422                        if (mOnBattery) {
2423                            int perc = bstats.startAddingCpuLocked();
2424                            int totalUTime = 0;
2425                            int totalSTime = 0;
2426                            final int N = mProcessCpuTracker.countStats();
2427                            for (int i=0; i<N; i++) {
2428                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2429                                if (!st.working) {
2430                                    continue;
2431                                }
2432                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2433                                int otherUTime = (st.rel_utime*perc)/100;
2434                                int otherSTime = (st.rel_stime*perc)/100;
2435                                totalUTime += otherUTime;
2436                                totalSTime += otherSTime;
2437                                if (pr != null) {
2438                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2439                                    if (ps == null || !ps.isActive()) {
2440                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2441                                                pr.info.uid, pr.processName);
2442                                    }
2443                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2444                                            st.rel_stime-otherSTime);
2445                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2446                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2447                                } else {
2448                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2449                                    if (ps == null || !ps.isActive()) {
2450                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2451                                                bstats.mapUid(st.uid), st.name);
2452                                    }
2453                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2454                                            st.rel_stime-otherSTime);
2455                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2456                                }
2457                            }
2458                            bstats.finishAddingCpuLocked(perc, totalUTime,
2459                                    totalSTime, cpuSpeedTimes);
2460                        }
2461                    }
2462                }
2463
2464                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2465                    mLastWriteTime = now;
2466                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2467                }
2468            }
2469        }
2470    }
2471
2472    @Override
2473    public void batteryNeedsCpuUpdate() {
2474        updateCpuStatsNow();
2475    }
2476
2477    @Override
2478    public void batteryPowerChanged(boolean onBattery) {
2479        // When plugging in, update the CPU stats first before changing
2480        // the plug state.
2481        updateCpuStatsNow();
2482        synchronized (this) {
2483            synchronized(mPidsSelfLocked) {
2484                mOnBattery = DEBUG_POWER ? true : onBattery;
2485            }
2486        }
2487    }
2488
2489    /**
2490     * Initialize the application bind args. These are passed to each
2491     * process when the bindApplication() IPC is sent to the process. They're
2492     * lazily setup to make sure the services are running when they're asked for.
2493     */
2494    private HashMap<String, IBinder> getCommonServicesLocked() {
2495        if (mAppBindArgs == null) {
2496            mAppBindArgs = new HashMap<String, IBinder>();
2497
2498            // Setup the application init args
2499            mAppBindArgs.put("package", ServiceManager.getService("package"));
2500            mAppBindArgs.put("window", ServiceManager.getService("window"));
2501            mAppBindArgs.put(Context.ALARM_SERVICE,
2502                    ServiceManager.getService(Context.ALARM_SERVICE));
2503        }
2504        return mAppBindArgs;
2505    }
2506
2507    final void setFocusedActivityLocked(ActivityRecord r) {
2508        if (mFocusedActivity != r) {
2509            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2510            mFocusedActivity = r;
2511            if (r.task != null && r.task.voiceInteractor != null) {
2512                startRunningVoiceLocked();
2513            } else {
2514                finishRunningVoiceLocked();
2515            }
2516            mStackSupervisor.setFocusedStack(r);
2517            if (r != null) {
2518                mWindowManager.setFocusedApp(r.appToken, true);
2519            }
2520            applyUpdateLockStateLocked(r);
2521        }
2522    }
2523
2524    final void clearFocusedActivity(ActivityRecord r) {
2525        if (mFocusedActivity == r) {
2526            mFocusedActivity = null;
2527        }
2528    }
2529
2530    @Override
2531    public void setFocusedStack(int stackId) {
2532        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2533        synchronized (ActivityManagerService.this) {
2534            ActivityStack stack = mStackSupervisor.getStack(stackId);
2535            if (stack != null) {
2536                ActivityRecord r = stack.topRunningActivityLocked(null);
2537                if (r != null) {
2538                    setFocusedActivityLocked(r);
2539                }
2540            }
2541        }
2542    }
2543
2544    @Override
2545    public void notifyActivityDrawn(IBinder token) {
2546        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2547        synchronized (this) {
2548            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2549            if (r != null) {
2550                r.task.stack.notifyActivityDrawnLocked(r);
2551            }
2552        }
2553    }
2554
2555    final void applyUpdateLockStateLocked(ActivityRecord r) {
2556        // Modifications to the UpdateLock state are done on our handler, outside
2557        // the activity manager's locks.  The new state is determined based on the
2558        // state *now* of the relevant activity record.  The object is passed to
2559        // the handler solely for logging detail, not to be consulted/modified.
2560        final boolean nextState = r != null && r.immersive;
2561        mHandler.sendMessage(
2562                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2563    }
2564
2565    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2566        Message msg = Message.obtain();
2567        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2568        msg.obj = r.task.askedCompatMode ? null : r;
2569        mHandler.sendMessage(msg);
2570    }
2571
2572    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2573            String what, Object obj, ProcessRecord srcApp) {
2574        app.lastActivityTime = now;
2575
2576        if (app.activities.size() > 0) {
2577            // Don't want to touch dependent processes that are hosting activities.
2578            return index;
2579        }
2580
2581        int lrui = mLruProcesses.lastIndexOf(app);
2582        if (lrui < 0) {
2583            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2584                    + what + " " + obj + " from " + srcApp);
2585            return index;
2586        }
2587
2588        if (lrui >= index) {
2589            // Don't want to cause this to move dependent processes *back* in the
2590            // list as if they were less frequently used.
2591            return index;
2592        }
2593
2594        if (lrui >= mLruProcessActivityStart) {
2595            // Don't want to touch dependent processes that are hosting activities.
2596            return index;
2597        }
2598
2599        mLruProcesses.remove(lrui);
2600        if (index > 0) {
2601            index--;
2602        }
2603        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2604                + " in LRU list: " + app);
2605        mLruProcesses.add(index, app);
2606        return index;
2607    }
2608
2609    final void removeLruProcessLocked(ProcessRecord app) {
2610        int lrui = mLruProcesses.lastIndexOf(app);
2611        if (lrui >= 0) {
2612            if (lrui <= mLruProcessActivityStart) {
2613                mLruProcessActivityStart--;
2614            }
2615            if (lrui <= mLruProcessServiceStart) {
2616                mLruProcessServiceStart--;
2617            }
2618            mLruProcesses.remove(lrui);
2619        }
2620    }
2621
2622    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2623            ProcessRecord client) {
2624        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2625                || app.treatLikeActivity;
2626        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2627        if (!activityChange && hasActivity) {
2628            // The process has activities, so we are only allowing activity-based adjustments
2629            // to move it.  It should be kept in the front of the list with other
2630            // processes that have activities, and we don't want those to change their
2631            // order except due to activity operations.
2632            return;
2633        }
2634
2635        mLruSeq++;
2636        final long now = SystemClock.uptimeMillis();
2637        app.lastActivityTime = now;
2638
2639        // First a quick reject: if the app is already at the position we will
2640        // put it, then there is nothing to do.
2641        if (hasActivity) {
2642            final int N = mLruProcesses.size();
2643            if (N > 0 && mLruProcesses.get(N-1) == app) {
2644                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2645                return;
2646            }
2647        } else {
2648            if (mLruProcessServiceStart > 0
2649                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2650                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2651                return;
2652            }
2653        }
2654
2655        int lrui = mLruProcesses.lastIndexOf(app);
2656
2657        if (app.persistent && lrui >= 0) {
2658            // We don't care about the position of persistent processes, as long as
2659            // they are in the list.
2660            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2661            return;
2662        }
2663
2664        /* In progress: compute new position first, so we can avoid doing work
2665           if the process is not actually going to move.  Not yet working.
2666        int addIndex;
2667        int nextIndex;
2668        boolean inActivity = false, inService = false;
2669        if (hasActivity) {
2670            // Process has activities, put it at the very tipsy-top.
2671            addIndex = mLruProcesses.size();
2672            nextIndex = mLruProcessServiceStart;
2673            inActivity = true;
2674        } else if (hasService) {
2675            // Process has services, put it at the top of the service list.
2676            addIndex = mLruProcessActivityStart;
2677            nextIndex = mLruProcessServiceStart;
2678            inActivity = true;
2679            inService = true;
2680        } else  {
2681            // Process not otherwise of interest, it goes to the top of the non-service area.
2682            addIndex = mLruProcessServiceStart;
2683            if (client != null) {
2684                int clientIndex = mLruProcesses.lastIndexOf(client);
2685                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2686                        + app);
2687                if (clientIndex >= 0 && addIndex > clientIndex) {
2688                    addIndex = clientIndex;
2689                }
2690            }
2691            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2692        }
2693
2694        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2695                + mLruProcessActivityStart + "): " + app);
2696        */
2697
2698        if (lrui >= 0) {
2699            if (lrui < mLruProcessActivityStart) {
2700                mLruProcessActivityStart--;
2701            }
2702            if (lrui < mLruProcessServiceStart) {
2703                mLruProcessServiceStart--;
2704            }
2705            /*
2706            if (addIndex > lrui) {
2707                addIndex--;
2708            }
2709            if (nextIndex > lrui) {
2710                nextIndex--;
2711            }
2712            */
2713            mLruProcesses.remove(lrui);
2714        }
2715
2716        /*
2717        mLruProcesses.add(addIndex, app);
2718        if (inActivity) {
2719            mLruProcessActivityStart++;
2720        }
2721        if (inService) {
2722            mLruProcessActivityStart++;
2723        }
2724        */
2725
2726        int nextIndex;
2727        if (hasActivity) {
2728            final int N = mLruProcesses.size();
2729            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2730                // Process doesn't have activities, but has clients with
2731                // activities...  move it up, but one below the top (the top
2732                // should always have a real activity).
2733                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2734                mLruProcesses.add(N-1, app);
2735                // To keep it from spamming the LRU list (by making a bunch of clients),
2736                // we will push down any other entries owned by the app.
2737                final int uid = app.info.uid;
2738                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2739                    ProcessRecord subProc = mLruProcesses.get(i);
2740                    if (subProc.info.uid == uid) {
2741                        // We want to push this one down the list.  If the process after
2742                        // it is for the same uid, however, don't do so, because we don't
2743                        // want them internally to be re-ordered.
2744                        if (mLruProcesses.get(i-1).info.uid != uid) {
2745                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2746                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2747                            ProcessRecord tmp = mLruProcesses.get(i);
2748                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2749                            mLruProcesses.set(i-1, tmp);
2750                            i--;
2751                        }
2752                    } else {
2753                        // A gap, we can stop here.
2754                        break;
2755                    }
2756                }
2757            } else {
2758                // Process has activities, put it at the very tipsy-top.
2759                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2760                mLruProcesses.add(app);
2761            }
2762            nextIndex = mLruProcessServiceStart;
2763        } else if (hasService) {
2764            // Process has services, put it at the top of the service list.
2765            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2766            mLruProcesses.add(mLruProcessActivityStart, app);
2767            nextIndex = mLruProcessServiceStart;
2768            mLruProcessActivityStart++;
2769        } else  {
2770            // Process not otherwise of interest, it goes to the top of the non-service area.
2771            int index = mLruProcessServiceStart;
2772            if (client != null) {
2773                // If there is a client, don't allow the process to be moved up higher
2774                // in the list than that client.
2775                int clientIndex = mLruProcesses.lastIndexOf(client);
2776                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2777                        + " when updating " + app);
2778                if (clientIndex <= lrui) {
2779                    // Don't allow the client index restriction to push it down farther in the
2780                    // list than it already is.
2781                    clientIndex = lrui;
2782                }
2783                if (clientIndex >= 0 && index > clientIndex) {
2784                    index = clientIndex;
2785                }
2786            }
2787            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2788            mLruProcesses.add(index, app);
2789            nextIndex = index-1;
2790            mLruProcessActivityStart++;
2791            mLruProcessServiceStart++;
2792        }
2793
2794        // If the app is currently using a content provider or service,
2795        // bump those processes as well.
2796        for (int j=app.connections.size()-1; j>=0; j--) {
2797            ConnectionRecord cr = app.connections.valueAt(j);
2798            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2799                    && cr.binding.service.app != null
2800                    && cr.binding.service.app.lruSeq != mLruSeq
2801                    && !cr.binding.service.app.persistent) {
2802                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2803                        "service connection", cr, app);
2804            }
2805        }
2806        for (int j=app.conProviders.size()-1; j>=0; j--) {
2807            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2808            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2809                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2810                        "provider reference", cpr, app);
2811            }
2812        }
2813    }
2814
2815    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2816        if (uid == Process.SYSTEM_UID) {
2817            // The system gets to run in any process.  If there are multiple
2818            // processes with the same uid, just pick the first (this
2819            // should never happen).
2820            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2821            if (procs == null) return null;
2822            final int N = procs.size();
2823            for (int i = 0; i < N; i++) {
2824                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2825            }
2826        }
2827        ProcessRecord proc = mProcessNames.get(processName, uid);
2828        if (false && proc != null && !keepIfLarge
2829                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2830                && proc.lastCachedPss >= 4000) {
2831            // Turn this condition on to cause killing to happen regularly, for testing.
2832            if (proc.baseProcessTracker != null) {
2833                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2834            }
2835            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2836        } else if (proc != null && !keepIfLarge
2837                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2838                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2839            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2840            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2841                if (proc.baseProcessTracker != null) {
2842                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2843                }
2844                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2845            }
2846        }
2847        return proc;
2848    }
2849
2850    void ensurePackageDexOpt(String packageName) {
2851        IPackageManager pm = AppGlobals.getPackageManager();
2852        try {
2853            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2854                mDidDexOpt = true;
2855            }
2856        } catch (RemoteException e) {
2857        }
2858    }
2859
2860    boolean isNextTransitionForward() {
2861        int transit = mWindowManager.getPendingAppTransition();
2862        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2863                || transit == AppTransition.TRANSIT_TASK_OPEN
2864                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2865    }
2866
2867    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2868            String processName, String abiOverride, int uid, Runnable crashHandler) {
2869        synchronized(this) {
2870            ApplicationInfo info = new ApplicationInfo();
2871            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2872            // For isolated processes, the former contains the parent's uid and the latter the
2873            // actual uid of the isolated process.
2874            // In the special case introduced by this method (which is, starting an isolated
2875            // process directly from the SystemServer without an actual parent app process) the
2876            // closest thing to a parent's uid is SYSTEM_UID.
2877            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2878            // the |isolated| logic in the ProcessRecord constructor.
2879            info.uid = Process.SYSTEM_UID;
2880            info.processName = processName;
2881            info.className = entryPoint;
2882            info.packageName = "android";
2883            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2884                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2885                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2886                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2887                    crashHandler);
2888            return proc != null ? proc.pid : 0;
2889        }
2890    }
2891
2892    final ProcessRecord startProcessLocked(String processName,
2893            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2894            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2895            boolean isolated, boolean keepIfLarge) {
2896        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2897                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2898                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2899                null /* crashHandler */);
2900    }
2901
2902    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2903            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2904            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2905            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2906        long startTime = SystemClock.elapsedRealtime();
2907        ProcessRecord app;
2908        if (!isolated) {
2909            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2910            checkTime(startTime, "startProcess: after getProcessRecord");
2911        } else {
2912            // If this is an isolated process, it can't re-use an existing process.
2913            app = null;
2914        }
2915        // We don't have to do anything more if:
2916        // (1) There is an existing application record; and
2917        // (2) The caller doesn't think it is dead, OR there is no thread
2918        //     object attached to it so we know it couldn't have crashed; and
2919        // (3) There is a pid assigned to it, so it is either starting or
2920        //     already running.
2921        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2922                + " app=" + app + " knownToBeDead=" + knownToBeDead
2923                + " thread=" + (app != null ? app.thread : null)
2924                + " pid=" + (app != null ? app.pid : -1));
2925        if (app != null && app.pid > 0) {
2926            if (!knownToBeDead || app.thread == null) {
2927                // We already have the app running, or are waiting for it to
2928                // come up (we have a pid but not yet its thread), so keep it.
2929                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2930                // If this is a new package in the process, add the package to the list
2931                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2932                checkTime(startTime, "startProcess: done, added package to proc");
2933                return app;
2934            }
2935
2936            // An application record is attached to a previous process,
2937            // clean it up now.
2938            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2939            checkTime(startTime, "startProcess: bad proc running, killing");
2940            Process.killProcessGroup(app.info.uid, app.pid);
2941            handleAppDiedLocked(app, true, true);
2942            checkTime(startTime, "startProcess: done killing old proc");
2943        }
2944
2945        String hostingNameStr = hostingName != null
2946                ? hostingName.flattenToShortString() : null;
2947
2948        if (!isolated) {
2949            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2950                // If we are in the background, then check to see if this process
2951                // is bad.  If so, we will just silently fail.
2952                if (mBadProcesses.get(info.processName, info.uid) != null) {
2953                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2954                            + "/" + info.processName);
2955                    return null;
2956                }
2957            } else {
2958                // When the user is explicitly starting a process, then clear its
2959                // crash count so that we won't make it bad until they see at
2960                // least one crash dialog again, and make the process good again
2961                // if it had been bad.
2962                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2963                        + "/" + info.processName);
2964                mProcessCrashTimes.remove(info.processName, info.uid);
2965                if (mBadProcesses.get(info.processName, info.uid) != null) {
2966                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2967                            UserHandle.getUserId(info.uid), info.uid,
2968                            info.processName);
2969                    mBadProcesses.remove(info.processName, info.uid);
2970                    if (app != null) {
2971                        app.bad = false;
2972                    }
2973                }
2974            }
2975        }
2976
2977        if (app == null) {
2978            checkTime(startTime, "startProcess: creating new process record");
2979            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2980            app.crashHandler = crashHandler;
2981            if (app == null) {
2982                Slog.w(TAG, "Failed making new process record for "
2983                        + processName + "/" + info.uid + " isolated=" + isolated);
2984                return null;
2985            }
2986            mProcessNames.put(processName, app.uid, app);
2987            if (isolated) {
2988                mIsolatedProcesses.put(app.uid, app);
2989            }
2990            checkTime(startTime, "startProcess: done creating new process record");
2991        } else {
2992            // If this is a new package in the process, add the package to the list
2993            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2994            checkTime(startTime, "startProcess: added package to existing proc");
2995        }
2996
2997        // If the system is not ready yet, then hold off on starting this
2998        // process until it is.
2999        if (!mProcessesReady
3000                && !isAllowedWhileBooting(info)
3001                && !allowWhileBooting) {
3002            if (!mProcessesOnHold.contains(app)) {
3003                mProcessesOnHold.add(app);
3004            }
3005            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3006            checkTime(startTime, "startProcess: returning with proc on hold");
3007            return app;
3008        }
3009
3010        checkTime(startTime, "startProcess: stepping in to startProcess");
3011        startProcessLocked(
3012                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3013        checkTime(startTime, "startProcess: done starting proc!");
3014        return (app.pid != 0) ? app : null;
3015    }
3016
3017    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3018        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3019    }
3020
3021    private final void startProcessLocked(ProcessRecord app,
3022            String hostingType, String hostingNameStr) {
3023        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3024                null /* entryPoint */, null /* entryPointArgs */);
3025    }
3026
3027    private final void startProcessLocked(ProcessRecord app, String hostingType,
3028            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3029        long startTime = SystemClock.elapsedRealtime();
3030        if (app.pid > 0 && app.pid != MY_PID) {
3031            checkTime(startTime, "startProcess: removing from pids map");
3032            synchronized (mPidsSelfLocked) {
3033                mPidsSelfLocked.remove(app.pid);
3034                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3035            }
3036            checkTime(startTime, "startProcess: done removing from pids map");
3037            app.setPid(0);
3038        }
3039
3040        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3041                "startProcessLocked removing on hold: " + app);
3042        mProcessesOnHold.remove(app);
3043
3044        checkTime(startTime, "startProcess: starting to update cpu stats");
3045        updateCpuStats();
3046        checkTime(startTime, "startProcess: done updating cpu stats");
3047
3048        try {
3049            int uid = app.uid;
3050
3051            int[] gids = null;
3052            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3053            if (!app.isolated) {
3054                int[] permGids = null;
3055                try {
3056                    checkTime(startTime, "startProcess: getting gids from package manager");
3057                    final PackageManager pm = mContext.getPackageManager();
3058                    permGids = pm.getPackageGids(app.info.packageName);
3059
3060                    if (Environment.isExternalStorageEmulated()) {
3061                        checkTime(startTime, "startProcess: checking external storage perm");
3062                        if (pm.checkPermission(
3063                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3064                                app.info.packageName) == PERMISSION_GRANTED) {
3065                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3066                        } else {
3067                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3068                        }
3069                    }
3070                } catch (PackageManager.NameNotFoundException e) {
3071                    Slog.w(TAG, "Unable to retrieve gids", e);
3072                }
3073
3074                /*
3075                 * Add shared application and profile GIDs so applications can share some
3076                 * resources like shared libraries and access user-wide resources
3077                 */
3078                if (permGids == null) {
3079                    gids = new int[2];
3080                } else {
3081                    gids = new int[permGids.length + 2];
3082                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3083                }
3084                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3085                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3086            }
3087            checkTime(startTime, "startProcess: building args");
3088            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3089                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3090                        && mTopComponent != null
3091                        && app.processName.equals(mTopComponent.getPackageName())) {
3092                    uid = 0;
3093                }
3094                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3095                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3096                    uid = 0;
3097                }
3098            }
3099            int debugFlags = 0;
3100            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3101                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3102                // Also turn on CheckJNI for debuggable apps. It's quite
3103                // awkward to turn on otherwise.
3104                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3105            }
3106            // Run the app in safe mode if its manifest requests so or the
3107            // system is booted in safe mode.
3108            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3109                mSafeMode == true) {
3110                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3111            }
3112            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3113                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3114            }
3115            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3116                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3117            }
3118            if ("1".equals(SystemProperties.get("debug.assert"))) {
3119                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3120            }
3121
3122            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3123            if (requiredAbi == null) {
3124                requiredAbi = Build.SUPPORTED_ABIS[0];
3125            }
3126
3127            // Start the process.  It will either succeed and return a result containing
3128            // the PID of the new process, or else throw a RuntimeException.
3129            boolean isActivityProcess = (entryPoint == null);
3130            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3131            checkTime(startTime, "startProcess: asking zygote to start proc");
3132            Process.ProcessStartResult startResult = Process.start(entryPoint,
3133                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3134                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3135            checkTime(startTime, "startProcess: returned from zygote!");
3136
3137            if (app.isolated) {
3138                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3139            }
3140            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3141            checkTime(startTime, "startProcess: done updating battery stats");
3142
3143            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3144                    UserHandle.getUserId(uid), startResult.pid, uid,
3145                    app.processName, hostingType,
3146                    hostingNameStr != null ? hostingNameStr : "");
3147
3148            if (app.persistent) {
3149                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3150            }
3151
3152            checkTime(startTime, "startProcess: building log message");
3153            StringBuilder buf = mStringBuilder;
3154            buf.setLength(0);
3155            buf.append("Start proc ");
3156            buf.append(app.processName);
3157            if (!isActivityProcess) {
3158                buf.append(" [");
3159                buf.append(entryPoint);
3160                buf.append("]");
3161            }
3162            buf.append(" for ");
3163            buf.append(hostingType);
3164            if (hostingNameStr != null) {
3165                buf.append(" ");
3166                buf.append(hostingNameStr);
3167            }
3168            buf.append(": pid=");
3169            buf.append(startResult.pid);
3170            buf.append(" uid=");
3171            buf.append(uid);
3172            buf.append(" gids={");
3173            if (gids != null) {
3174                for (int gi=0; gi<gids.length; gi++) {
3175                    if (gi != 0) buf.append(", ");
3176                    buf.append(gids[gi]);
3177
3178                }
3179            }
3180            buf.append("}");
3181            if (requiredAbi != null) {
3182                buf.append(" abi=");
3183                buf.append(requiredAbi);
3184            }
3185            Slog.i(TAG, buf.toString());
3186            app.setPid(startResult.pid);
3187            app.usingWrapper = startResult.usingWrapper;
3188            app.removed = false;
3189            app.killedByAm = false;
3190            checkTime(startTime, "startProcess: starting to update pids map");
3191            synchronized (mPidsSelfLocked) {
3192                this.mPidsSelfLocked.put(startResult.pid, app);
3193                if (isActivityProcess) {
3194                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3195                    msg.obj = app;
3196                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3197                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3198                }
3199            }
3200            checkTime(startTime, "startProcess: done updating pids map");
3201        } catch (RuntimeException e) {
3202            // XXX do better error recovery.
3203            app.setPid(0);
3204            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3205            if (app.isolated) {
3206                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3207            }
3208            Slog.e(TAG, "Failure starting process " + app.processName, e);
3209        }
3210    }
3211
3212    void updateUsageStats(ActivityRecord component, boolean resumed) {
3213        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3214        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3215        if (resumed) {
3216            if (mUsageStatsService != null) {
3217                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3218                        System.currentTimeMillis(),
3219                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3220            }
3221            synchronized (stats) {
3222                stats.noteActivityResumedLocked(component.app.uid);
3223            }
3224        } else {
3225            if (mUsageStatsService != null) {
3226                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3227                        System.currentTimeMillis(),
3228                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3229            }
3230            synchronized (stats) {
3231                stats.noteActivityPausedLocked(component.app.uid);
3232            }
3233        }
3234    }
3235
3236    Intent getHomeIntent() {
3237        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3238        intent.setComponent(mTopComponent);
3239        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3240            intent.addCategory(Intent.CATEGORY_HOME);
3241        }
3242        return intent;
3243    }
3244
3245    boolean startHomeActivityLocked(int userId) {
3246        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3247                && mTopAction == null) {
3248            // We are running in factory test mode, but unable to find
3249            // the factory test app, so just sit around displaying the
3250            // error message and don't try to start anything.
3251            return false;
3252        }
3253        Intent intent = getHomeIntent();
3254        ActivityInfo aInfo =
3255            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3256        if (aInfo != null) {
3257            intent.setComponent(new ComponentName(
3258                    aInfo.applicationInfo.packageName, aInfo.name));
3259            // Don't do this if the home app is currently being
3260            // instrumented.
3261            aInfo = new ActivityInfo(aInfo);
3262            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3263            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3264                    aInfo.applicationInfo.uid, true);
3265            if (app == null || app.instrumentationClass == null) {
3266                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3267                mStackSupervisor.startHomeActivity(intent, aInfo);
3268            }
3269        }
3270
3271        return true;
3272    }
3273
3274    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3275        ActivityInfo ai = null;
3276        ComponentName comp = intent.getComponent();
3277        try {
3278            if (comp != null) {
3279                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3280            } else {
3281                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3282                        intent,
3283                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3284                            flags, userId);
3285
3286                if (info != null) {
3287                    ai = info.activityInfo;
3288                }
3289            }
3290        } catch (RemoteException e) {
3291            // ignore
3292        }
3293
3294        return ai;
3295    }
3296
3297    /**
3298     * Starts the "new version setup screen" if appropriate.
3299     */
3300    void startSetupActivityLocked() {
3301        // Only do this once per boot.
3302        if (mCheckedForSetup) {
3303            return;
3304        }
3305
3306        // We will show this screen if the current one is a different
3307        // version than the last one shown, and we are not running in
3308        // low-level factory test mode.
3309        final ContentResolver resolver = mContext.getContentResolver();
3310        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3311                Settings.Global.getInt(resolver,
3312                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3313            mCheckedForSetup = true;
3314
3315            // See if we should be showing the platform update setup UI.
3316            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3317            List<ResolveInfo> ris = mContext.getPackageManager()
3318                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3319
3320            // We don't allow third party apps to replace this.
3321            ResolveInfo ri = null;
3322            for (int i=0; ris != null && i<ris.size(); i++) {
3323                if ((ris.get(i).activityInfo.applicationInfo.flags
3324                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3325                    ri = ris.get(i);
3326                    break;
3327                }
3328            }
3329
3330            if (ri != null) {
3331                String vers = ri.activityInfo.metaData != null
3332                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3333                        : null;
3334                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3335                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3336                            Intent.METADATA_SETUP_VERSION);
3337                }
3338                String lastVers = Settings.Secure.getString(
3339                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3340                if (vers != null && !vers.equals(lastVers)) {
3341                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3342                    intent.setComponent(new ComponentName(
3343                            ri.activityInfo.packageName, ri.activityInfo.name));
3344                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3345                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3346                            null);
3347                }
3348            }
3349        }
3350    }
3351
3352    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3353        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3354    }
3355
3356    void enforceNotIsolatedCaller(String caller) {
3357        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3358            throw new SecurityException("Isolated process not allowed to call " + caller);
3359        }
3360    }
3361
3362    @Override
3363    public int getFrontActivityScreenCompatMode() {
3364        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3365        synchronized (this) {
3366            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3367        }
3368    }
3369
3370    @Override
3371    public void setFrontActivityScreenCompatMode(int mode) {
3372        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3373                "setFrontActivityScreenCompatMode");
3374        synchronized (this) {
3375            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3376        }
3377    }
3378
3379    @Override
3380    public int getPackageScreenCompatMode(String packageName) {
3381        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3382        synchronized (this) {
3383            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3384        }
3385    }
3386
3387    @Override
3388    public void setPackageScreenCompatMode(String packageName, int mode) {
3389        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3390                "setPackageScreenCompatMode");
3391        synchronized (this) {
3392            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3393        }
3394    }
3395
3396    @Override
3397    public boolean getPackageAskScreenCompat(String packageName) {
3398        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3399        synchronized (this) {
3400            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3401        }
3402    }
3403
3404    @Override
3405    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3406        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3407                "setPackageAskScreenCompat");
3408        synchronized (this) {
3409            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3410        }
3411    }
3412
3413    private void dispatchProcessesChanged() {
3414        int N;
3415        synchronized (this) {
3416            N = mPendingProcessChanges.size();
3417            if (mActiveProcessChanges.length < N) {
3418                mActiveProcessChanges = new ProcessChangeItem[N];
3419            }
3420            mPendingProcessChanges.toArray(mActiveProcessChanges);
3421            mAvailProcessChanges.addAll(mPendingProcessChanges);
3422            mPendingProcessChanges.clear();
3423            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3424        }
3425
3426        int i = mProcessObservers.beginBroadcast();
3427        while (i > 0) {
3428            i--;
3429            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3430            if (observer != null) {
3431                try {
3432                    for (int j=0; j<N; j++) {
3433                        ProcessChangeItem item = mActiveProcessChanges[j];
3434                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3435                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3436                                    + item.pid + " uid=" + item.uid + ": "
3437                                    + item.foregroundActivities);
3438                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3439                                    item.foregroundActivities);
3440                        }
3441                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3442                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3443                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3444                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3445                        }
3446                    }
3447                } catch (RemoteException e) {
3448                }
3449            }
3450        }
3451        mProcessObservers.finishBroadcast();
3452    }
3453
3454    private void dispatchProcessDied(int pid, int uid) {
3455        int i = mProcessObservers.beginBroadcast();
3456        while (i > 0) {
3457            i--;
3458            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3459            if (observer != null) {
3460                try {
3461                    observer.onProcessDied(pid, uid);
3462                } catch (RemoteException e) {
3463                }
3464            }
3465        }
3466        mProcessObservers.finishBroadcast();
3467    }
3468
3469    @Override
3470    public final int startActivity(IApplicationThread caller, String callingPackage,
3471            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3472            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3473        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3474            resultWho, requestCode, startFlags, profilerInfo, options,
3475            UserHandle.getCallingUserId());
3476    }
3477
3478    @Override
3479    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3480            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3481            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3482        enforceNotIsolatedCaller("startActivity");
3483        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3484                false, ALLOW_FULL_ONLY, "startActivity", null);
3485        // TODO: Switch to user app stacks here.
3486        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3487                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3488                profilerInfo, null, null, options, userId, null, null);
3489    }
3490
3491    @Override
3492    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3493            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3494            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3495
3496        // This is very dangerous -- it allows you to perform a start activity (including
3497        // permission grants) as any app that may launch one of your own activities.  So
3498        // we will only allow this to be done from activities that are part of the core framework,
3499        // and then only when they are running as the system.
3500        final ActivityRecord sourceRecord;
3501        final int targetUid;
3502        final String targetPackage;
3503        synchronized (this) {
3504            if (resultTo == null) {
3505                throw new SecurityException("Must be called from an activity");
3506            }
3507            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3508            if (sourceRecord == null) {
3509                throw new SecurityException("Called with bad activity token: " + resultTo);
3510            }
3511            if (!sourceRecord.info.packageName.equals("android")) {
3512                throw new SecurityException(
3513                        "Must be called from an activity that is declared in the android package");
3514            }
3515            if (sourceRecord.app == null) {
3516                throw new SecurityException("Called without a process attached to activity");
3517            }
3518            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3519                // This is still okay, as long as this activity is running under the
3520                // uid of the original calling activity.
3521                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3522                    throw new SecurityException(
3523                            "Calling activity in uid " + sourceRecord.app.uid
3524                                    + " must be system uid or original calling uid "
3525                                    + sourceRecord.launchedFromUid);
3526                }
3527            }
3528            targetUid = sourceRecord.launchedFromUid;
3529            targetPackage = sourceRecord.launchedFromPackage;
3530        }
3531
3532        // TODO: Switch to user app stacks here.
3533        try {
3534            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3535                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3536                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3537            return ret;
3538        } catch (SecurityException e) {
3539            // XXX need to figure out how to propagate to original app.
3540            // A SecurityException here is generally actually a fault of the original
3541            // calling activity (such as a fairly granting permissions), so propagate it
3542            // back to them.
3543            /*
3544            StringBuilder msg = new StringBuilder();
3545            msg.append("While launching");
3546            msg.append(intent.toString());
3547            msg.append(": ");
3548            msg.append(e.getMessage());
3549            */
3550            throw e;
3551        }
3552    }
3553
3554    @Override
3555    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3556            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3557            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3558        enforceNotIsolatedCaller("startActivityAndWait");
3559        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3560                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3561        WaitResult res = new WaitResult();
3562        // TODO: Switch to user app stacks here.
3563        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3564                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3565                options, userId, null, null);
3566        return res;
3567    }
3568
3569    @Override
3570    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3571            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3572            int startFlags, Configuration config, Bundle options, int userId) {
3573        enforceNotIsolatedCaller("startActivityWithConfig");
3574        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3575                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3576        // TODO: Switch to user app stacks here.
3577        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3578                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3579                null, null, config, options, userId, null, null);
3580        return ret;
3581    }
3582
3583    @Override
3584    public int startActivityIntentSender(IApplicationThread caller,
3585            IntentSender intent, Intent fillInIntent, String resolvedType,
3586            IBinder resultTo, String resultWho, int requestCode,
3587            int flagsMask, int flagsValues, Bundle options) {
3588        enforceNotIsolatedCaller("startActivityIntentSender");
3589        // Refuse possible leaked file descriptors
3590        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3591            throw new IllegalArgumentException("File descriptors passed in Intent");
3592        }
3593
3594        IIntentSender sender = intent.getTarget();
3595        if (!(sender instanceof PendingIntentRecord)) {
3596            throw new IllegalArgumentException("Bad PendingIntent object");
3597        }
3598
3599        PendingIntentRecord pir = (PendingIntentRecord)sender;
3600
3601        synchronized (this) {
3602            // If this is coming from the currently resumed activity, it is
3603            // effectively saying that app switches are allowed at this point.
3604            final ActivityStack stack = getFocusedStack();
3605            if (stack.mResumedActivity != null &&
3606                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3607                mAppSwitchesAllowedTime = 0;
3608            }
3609        }
3610        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3611                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3612        return ret;
3613    }
3614
3615    @Override
3616    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3617            Intent intent, String resolvedType, IVoiceInteractionSession session,
3618            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3619            Bundle options, int userId) {
3620        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3621                != PackageManager.PERMISSION_GRANTED) {
3622            String msg = "Permission Denial: startVoiceActivity() from pid="
3623                    + Binder.getCallingPid()
3624                    + ", uid=" + Binder.getCallingUid()
3625                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3626            Slog.w(TAG, msg);
3627            throw new SecurityException(msg);
3628        }
3629        if (session == null || interactor == null) {
3630            throw new NullPointerException("null session or interactor");
3631        }
3632        userId = handleIncomingUser(callingPid, callingUid, userId,
3633                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3634        // TODO: Switch to user app stacks here.
3635        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3636                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3637                null, options, userId, null, null);
3638    }
3639
3640    @Override
3641    public boolean startNextMatchingActivity(IBinder callingActivity,
3642            Intent intent, Bundle options) {
3643        // Refuse possible leaked file descriptors
3644        if (intent != null && intent.hasFileDescriptors() == true) {
3645            throw new IllegalArgumentException("File descriptors passed in Intent");
3646        }
3647
3648        synchronized (this) {
3649            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3650            if (r == null) {
3651                ActivityOptions.abort(options);
3652                return false;
3653            }
3654            if (r.app == null || r.app.thread == null) {
3655                // The caller is not running...  d'oh!
3656                ActivityOptions.abort(options);
3657                return false;
3658            }
3659            intent = new Intent(intent);
3660            // The caller is not allowed to change the data.
3661            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3662            // And we are resetting to find the next component...
3663            intent.setComponent(null);
3664
3665            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3666
3667            ActivityInfo aInfo = null;
3668            try {
3669                List<ResolveInfo> resolves =
3670                    AppGlobals.getPackageManager().queryIntentActivities(
3671                            intent, r.resolvedType,
3672                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3673                            UserHandle.getCallingUserId());
3674
3675                // Look for the original activity in the list...
3676                final int N = resolves != null ? resolves.size() : 0;
3677                for (int i=0; i<N; i++) {
3678                    ResolveInfo rInfo = resolves.get(i);
3679                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3680                            && rInfo.activityInfo.name.equals(r.info.name)) {
3681                        // We found the current one...  the next matching is
3682                        // after it.
3683                        i++;
3684                        if (i<N) {
3685                            aInfo = resolves.get(i).activityInfo;
3686                        }
3687                        if (debug) {
3688                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3689                                    + "/" + r.info.name);
3690                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3691                                    + "/" + aInfo.name);
3692                        }
3693                        break;
3694                    }
3695                }
3696            } catch (RemoteException e) {
3697            }
3698
3699            if (aInfo == null) {
3700                // Nobody who is next!
3701                ActivityOptions.abort(options);
3702                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3703                return false;
3704            }
3705
3706            intent.setComponent(new ComponentName(
3707                    aInfo.applicationInfo.packageName, aInfo.name));
3708            intent.setFlags(intent.getFlags()&~(
3709                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3710                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3711                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3712                    Intent.FLAG_ACTIVITY_NEW_TASK));
3713
3714            // Okay now we need to start the new activity, replacing the
3715            // currently running activity.  This is a little tricky because
3716            // we want to start the new one as if the current one is finished,
3717            // but not finish the current one first so that there is no flicker.
3718            // And thus...
3719            final boolean wasFinishing = r.finishing;
3720            r.finishing = true;
3721
3722            // Propagate reply information over to the new activity.
3723            final ActivityRecord resultTo = r.resultTo;
3724            final String resultWho = r.resultWho;
3725            final int requestCode = r.requestCode;
3726            r.resultTo = null;
3727            if (resultTo != null) {
3728                resultTo.removeResultsLocked(r, resultWho, requestCode);
3729            }
3730
3731            final long origId = Binder.clearCallingIdentity();
3732            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3733                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3734                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3735                    options, false, null, null, null);
3736            Binder.restoreCallingIdentity(origId);
3737
3738            r.finishing = wasFinishing;
3739            if (res != ActivityManager.START_SUCCESS) {
3740                return false;
3741            }
3742            return true;
3743        }
3744    }
3745
3746    @Override
3747    public final int startActivityFromRecents(int taskId, Bundle options) {
3748        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3749            String msg = "Permission Denial: startActivityFromRecents called without " +
3750                    START_TASKS_FROM_RECENTS;
3751            Slog.w(TAG, msg);
3752            throw new SecurityException(msg);
3753        }
3754        return startActivityFromRecentsInner(taskId, options);
3755    }
3756
3757    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3758        final TaskRecord task;
3759        final int callingUid;
3760        final String callingPackage;
3761        final Intent intent;
3762        final int userId;
3763        synchronized (this) {
3764            task = recentTaskForIdLocked(taskId);
3765            if (task == null) {
3766                throw new IllegalArgumentException("Task " + taskId + " not found.");
3767            }
3768            callingUid = task.mCallingUid;
3769            callingPackage = task.mCallingPackage;
3770            intent = task.intent;
3771            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3772            userId = task.userId;
3773        }
3774        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3775                options, userId, null, task);
3776    }
3777
3778    final int startActivityInPackage(int uid, String callingPackage,
3779            Intent intent, String resolvedType, IBinder resultTo,
3780            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3781            IActivityContainer container, TaskRecord inTask) {
3782
3783        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3784                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3785
3786        // TODO: Switch to user app stacks here.
3787        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3788                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3789                null, null, null, options, userId, container, inTask);
3790        return ret;
3791    }
3792
3793    @Override
3794    public final int startActivities(IApplicationThread caller, String callingPackage,
3795            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3796            int userId) {
3797        enforceNotIsolatedCaller("startActivities");
3798        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3799                false, ALLOW_FULL_ONLY, "startActivity", null);
3800        // TODO: Switch to user app stacks here.
3801        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3802                resolvedTypes, resultTo, options, userId);
3803        return ret;
3804    }
3805
3806    final int startActivitiesInPackage(int uid, String callingPackage,
3807            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3808            Bundle options, int userId) {
3809
3810        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3811                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3812        // TODO: Switch to user app stacks here.
3813        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3814                resultTo, options, userId);
3815        return ret;
3816    }
3817
3818    //explicitly remove thd old information in mRecentTasks when removing existing user.
3819    private void removeRecentTasksForUserLocked(int userId) {
3820        if(userId <= 0) {
3821            Slog.i(TAG, "Can't remove recent task on user " + userId);
3822            return;
3823        }
3824
3825        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3826            TaskRecord tr = mRecentTasks.get(i);
3827            if (tr.userId == userId) {
3828                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3829                        + " when finishing user" + userId);
3830                mRecentTasks.remove(i);
3831                tr.removedFromRecents(mTaskPersister);
3832            }
3833        }
3834
3835        // Remove tasks from persistent storage.
3836        mTaskPersister.wakeup(null, true);
3837    }
3838
3839    /**
3840     * Update the recent tasks lists: make sure tasks should still be here (their
3841     * applications / activities still exist), update their availability, fixup ordering
3842     * of affiliations.
3843     */
3844    void cleanupRecentTasksLocked(int userId) {
3845        if (mRecentTasks == null) {
3846            // Happens when called from the packagemanager broadcast before boot.
3847            return;
3848        }
3849
3850        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3851        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3852        final IPackageManager pm = AppGlobals.getPackageManager();
3853        final ActivityInfo dummyAct = new ActivityInfo();
3854        final ApplicationInfo dummyApp = new ApplicationInfo();
3855
3856        int N = mRecentTasks.size();
3857
3858        int[] users = userId == UserHandle.USER_ALL
3859                ? getUsersLocked() : new int[] { userId };
3860        for (int user : users) {
3861            for (int i = 0; i < N; i++) {
3862                TaskRecord task = mRecentTasks.get(i);
3863                if (task.userId != user) {
3864                    // Only look at tasks for the user ID of interest.
3865                    continue;
3866                }
3867                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3868                    // This situation is broken, and we should just get rid of it now.
3869                    mRecentTasks.remove(i);
3870                    task.removedFromRecents(mTaskPersister);
3871                    i--;
3872                    N--;
3873                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3874                    continue;
3875                }
3876                // Check whether this activity is currently available.
3877                if (task.realActivity != null) {
3878                    ActivityInfo ai = availActCache.get(task.realActivity);
3879                    if (ai == null) {
3880                        try {
3881                            ai = pm.getActivityInfo(task.realActivity,
3882                                    PackageManager.GET_UNINSTALLED_PACKAGES
3883                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3884                        } catch (RemoteException e) {
3885                            // Will never happen.
3886                            continue;
3887                        }
3888                        if (ai == null) {
3889                            ai = dummyAct;
3890                        }
3891                        availActCache.put(task.realActivity, ai);
3892                    }
3893                    if (ai == dummyAct) {
3894                        // This could be either because the activity no longer exists, or the
3895                        // app is temporarily gone.  For the former we want to remove the recents
3896                        // entry; for the latter we want to mark it as unavailable.
3897                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3898                        if (app == null) {
3899                            try {
3900                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3901                                        PackageManager.GET_UNINSTALLED_PACKAGES
3902                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3903                            } catch (RemoteException e) {
3904                                // Will never happen.
3905                                continue;
3906                            }
3907                            if (app == null) {
3908                                app = dummyApp;
3909                            }
3910                            availAppCache.put(task.realActivity.getPackageName(), app);
3911                        }
3912                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3913                            // Doesn't exist any more!  Good-bye.
3914                            mRecentTasks.remove(i);
3915                            task.removedFromRecents(mTaskPersister);
3916                            i--;
3917                            N--;
3918                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3919                            continue;
3920                        } else {
3921                            // Otherwise just not available for now.
3922                            if (task.isAvailable) {
3923                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3924                                        + task);
3925                            }
3926                            task.isAvailable = false;
3927                        }
3928                    } else {
3929                        if (!ai.enabled || !ai.applicationInfo.enabled
3930                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3931                            if (task.isAvailable) {
3932                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3933                                        + task + " (enabled=" + ai.enabled + "/"
3934                                        + ai.applicationInfo.enabled +  " flags="
3935                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3936                            }
3937                            task.isAvailable = false;
3938                        } else {
3939                            if (!task.isAvailable) {
3940                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3941                                        + task);
3942                            }
3943                            task.isAvailable = true;
3944                        }
3945                    }
3946                }
3947            }
3948        }
3949
3950        // Verify the affiliate chain for each task.
3951        for (int i = 0; i < N; ) {
3952            TaskRecord task = mRecentTasks.remove(i);
3953            if (mTmpRecents.contains(task)) {
3954                continue;
3955            }
3956            int affiliatedTaskId = task.mAffiliatedTaskId;
3957            while (true) {
3958                TaskRecord next = task.mNextAffiliate;
3959                if (next == null) {
3960                    break;
3961                }
3962                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3963                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3964                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3965                    task.setNextAffiliate(null);
3966                    if (next.mPrevAffiliate == task) {
3967                        next.setPrevAffiliate(null);
3968                    }
3969                    break;
3970                }
3971                if (next.mPrevAffiliate != task) {
3972                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3973                            next.mPrevAffiliate + " task=" + task);
3974                    next.setPrevAffiliate(null);
3975                    task.setNextAffiliate(null);
3976                    break;
3977                }
3978                if (!mRecentTasks.contains(next)) {
3979                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3980                    task.setNextAffiliate(null);
3981                    // We know that next.mPrevAffiliate is always task, from above, so clear
3982                    // its previous affiliate.
3983                    next.setPrevAffiliate(null);
3984                    break;
3985                }
3986                task = next;
3987            }
3988            // task is now the end of the list
3989            do {
3990                mRecentTasks.remove(task);
3991                mRecentTasks.add(i++, task);
3992                mTmpRecents.add(task);
3993                task.inRecents = true;
3994            } while ((task = task.mPrevAffiliate) != null);
3995        }
3996        mTmpRecents.clear();
3997        // mRecentTasks is now in sorted, affiliated order.
3998    }
3999
4000    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4001        int N = mRecentTasks.size();
4002        TaskRecord top = task;
4003        int topIndex = taskIndex;
4004        while (top.mNextAffiliate != null && topIndex > 0) {
4005            top = top.mNextAffiliate;
4006            topIndex--;
4007        }
4008        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4009                + topIndex + " from intial " + taskIndex);
4010        // Find the end of the chain, doing a sanity check along the way.
4011        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4012        int endIndex = topIndex;
4013        TaskRecord prev = top;
4014        while (endIndex < N) {
4015            TaskRecord cur = mRecentTasks.get(endIndex);
4016            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4017                    + endIndex + " " + cur);
4018            if (cur == top) {
4019                // Verify start of the chain.
4020                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4021                    Slog.wtf(TAG, "Bad chain @" + endIndex
4022                            + ": first task has next affiliate: " + prev);
4023                    sane = false;
4024                    break;
4025                }
4026            } else {
4027                // Verify middle of the chain's next points back to the one before.
4028                if (cur.mNextAffiliate != prev
4029                        || cur.mNextAffiliateTaskId != prev.taskId) {
4030                    Slog.wtf(TAG, "Bad chain @" + endIndex
4031                            + ": middle task " + cur + " @" + endIndex
4032                            + " has bad next affiliate "
4033                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4034                            + ", expected " + prev);
4035                    sane = false;
4036                    break;
4037                }
4038            }
4039            if (cur.mPrevAffiliateTaskId == -1) {
4040                // Chain ends here.
4041                if (cur.mPrevAffiliate != null) {
4042                    Slog.wtf(TAG, "Bad chain @" + endIndex
4043                            + ": last task " + cur + " has previous affiliate "
4044                            + cur.mPrevAffiliate);
4045                    sane = false;
4046                }
4047                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4048                break;
4049            } else {
4050                // Verify middle of the chain's prev points to a valid item.
4051                if (cur.mPrevAffiliate == null) {
4052                    Slog.wtf(TAG, "Bad chain @" + endIndex
4053                            + ": task " + cur + " has previous affiliate "
4054                            + cur.mPrevAffiliate + " but should be id "
4055                            + cur.mPrevAffiliate);
4056                    sane = false;
4057                    break;
4058                }
4059            }
4060            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4061                Slog.wtf(TAG, "Bad chain @" + endIndex
4062                        + ": task " + cur + " has affiliated id "
4063                        + cur.mAffiliatedTaskId + " but should be "
4064                        + task.mAffiliatedTaskId);
4065                sane = false;
4066                break;
4067            }
4068            prev = cur;
4069            endIndex++;
4070            if (endIndex >= N) {
4071                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4072                        + ": last task " + prev);
4073                sane = false;
4074                break;
4075            }
4076        }
4077        if (sane) {
4078            if (endIndex < taskIndex) {
4079                Slog.wtf(TAG, "Bad chain @" + endIndex
4080                        + ": did not extend to task " + task + " @" + taskIndex);
4081                sane = false;
4082            }
4083        }
4084        if (sane) {
4085            // All looks good, we can just move all of the affiliated tasks
4086            // to the top.
4087            for (int i=topIndex; i<=endIndex; i++) {
4088                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4089                        + " from " + i + " to " + (i-topIndex));
4090                TaskRecord cur = mRecentTasks.remove(i);
4091                mRecentTasks.add(i-topIndex, cur);
4092            }
4093            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4094                    + " to " + endIndex);
4095            return true;
4096        }
4097
4098        // Whoops, couldn't do it.
4099        return false;
4100    }
4101
4102    final void addRecentTaskLocked(TaskRecord task) {
4103        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4104                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4105
4106        int N = mRecentTasks.size();
4107        // Quick case: check if the top-most recent task is the same.
4108        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4109            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4110            return;
4111        }
4112        // Another quick case: check if this is part of a set of affiliated
4113        // tasks that are at the top.
4114        if (isAffiliated && N > 0 && task.inRecents
4115                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4116            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4117                    + " at top when adding " + task);
4118            return;
4119        }
4120        // Another quick case: never add voice sessions.
4121        if (task.voiceSession != null) {
4122            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4123            return;
4124        }
4125
4126        boolean needAffiliationFix = false;
4127
4128        // Slightly less quick case: the task is already in recents, so all we need
4129        // to do is move it.
4130        if (task.inRecents) {
4131            int taskIndex = mRecentTasks.indexOf(task);
4132            if (taskIndex >= 0) {
4133                if (!isAffiliated) {
4134                    // Simple case: this is not an affiliated task, so we just move it to the front.
4135                    mRecentTasks.remove(taskIndex);
4136                    mRecentTasks.add(0, task);
4137                    notifyTaskPersisterLocked(task, false);
4138                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4139                            + " from " + taskIndex);
4140                    return;
4141                } else {
4142                    // More complicated: need to keep all affiliated tasks together.
4143                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4144                        // All went well.
4145                        return;
4146                    }
4147
4148                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4149                    // everything and then go through our general path of adding a new task.
4150                    needAffiliationFix = true;
4151                }
4152            } else {
4153                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4154                needAffiliationFix = true;
4155            }
4156        }
4157
4158        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4159        trimRecentsForTask(task, true);
4160
4161        N = mRecentTasks.size();
4162        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4163            final TaskRecord tr = mRecentTasks.remove(N - 1);
4164            tr.removedFromRecents(mTaskPersister);
4165            N--;
4166        }
4167        task.inRecents = true;
4168        if (!isAffiliated || needAffiliationFix) {
4169            // If this is a simple non-affiliated task, or we had some failure trying to
4170            // handle it as part of an affilated task, then just place it at the top.
4171            mRecentTasks.add(0, task);
4172        } else if (isAffiliated) {
4173            // If this is a new affiliated task, then move all of the affiliated tasks
4174            // to the front and insert this new one.
4175            TaskRecord other = task.mNextAffiliate;
4176            if (other == null) {
4177                other = task.mPrevAffiliate;
4178            }
4179            if (other != null) {
4180                int otherIndex = mRecentTasks.indexOf(other);
4181                if (otherIndex >= 0) {
4182                    // Insert new task at appropriate location.
4183                    int taskIndex;
4184                    if (other == task.mNextAffiliate) {
4185                        // We found the index of our next affiliation, which is who is
4186                        // before us in the list, so add after that point.
4187                        taskIndex = otherIndex+1;
4188                    } else {
4189                        // We found the index of our previous affiliation, which is who is
4190                        // after us in the list, so add at their position.
4191                        taskIndex = otherIndex;
4192                    }
4193                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4194                            + taskIndex + ": " + task);
4195                    mRecentTasks.add(taskIndex, task);
4196
4197                    // Now move everything to the front.
4198                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4199                        // All went well.
4200                        return;
4201                    }
4202
4203                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4204                    // everything and then go through our general path of adding a new task.
4205                    needAffiliationFix = true;
4206                } else {
4207                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4208                            + other);
4209                    needAffiliationFix = true;
4210                }
4211            } else {
4212                if (DEBUG_RECENTS) Slog.d(TAG,
4213                        "addRecent: adding affiliated task without next/prev:" + task);
4214                needAffiliationFix = true;
4215            }
4216        }
4217        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4218
4219        if (needAffiliationFix) {
4220            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4221            cleanupRecentTasksLocked(task.userId);
4222        }
4223    }
4224
4225    /**
4226     * If needed, remove oldest existing entries in recents that are for the same kind
4227     * of task as the given one.
4228     */
4229    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4230        int N = mRecentTasks.size();
4231        final Intent intent = task.intent;
4232        final boolean document = intent != null && intent.isDocument();
4233
4234        int maxRecents = task.maxRecents - 1;
4235        for (int i=0; i<N; i++) {
4236            final TaskRecord tr = mRecentTasks.get(i);
4237            if (task != tr) {
4238                if (task.userId != tr.userId) {
4239                    continue;
4240                }
4241                if (i > MAX_RECENT_BITMAPS) {
4242                    tr.freeLastThumbnail();
4243                }
4244                final Intent trIntent = tr.intent;
4245                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4246                    (intent == null || !intent.filterEquals(trIntent))) {
4247                    continue;
4248                }
4249                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4250                if (document && trIsDocument) {
4251                    // These are the same document activity (not necessarily the same doc).
4252                    if (maxRecents > 0) {
4253                        --maxRecents;
4254                        continue;
4255                    }
4256                    // Hit the maximum number of documents for this task. Fall through
4257                    // and remove this document from recents.
4258                } else if (document || trIsDocument) {
4259                    // Only one of these is a document. Not the droid we're looking for.
4260                    continue;
4261                }
4262            }
4263
4264            if (!doTrim) {
4265                // If the caller is not actually asking for a trim, just tell them we reached
4266                // a point where the trim would happen.
4267                return i;
4268            }
4269
4270            // Either task and tr are the same or, their affinities match or their intents match
4271            // and neither of them is a document, or they are documents using the same activity
4272            // and their maxRecents has been reached.
4273            tr.disposeThumbnail();
4274            mRecentTasks.remove(i);
4275            if (task != tr) {
4276                tr.removedFromRecents(mTaskPersister);
4277            }
4278            i--;
4279            N--;
4280            if (task.intent == null) {
4281                // If the new recent task we are adding is not fully
4282                // specified, then replace it with the existing recent task.
4283                task = tr;
4284            }
4285            notifyTaskPersisterLocked(tr, false);
4286        }
4287
4288        return -1;
4289    }
4290
4291    @Override
4292    public void reportActivityFullyDrawn(IBinder token) {
4293        synchronized (this) {
4294            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4295            if (r == null) {
4296                return;
4297            }
4298            r.reportFullyDrawnLocked();
4299        }
4300    }
4301
4302    @Override
4303    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4304        synchronized (this) {
4305            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4306            if (r == null) {
4307                return;
4308            }
4309            final long origId = Binder.clearCallingIdentity();
4310            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4311            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4312                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4313            if (config != null) {
4314                r.frozenBeforeDestroy = true;
4315                if (!updateConfigurationLocked(config, r, false, false)) {
4316                    mStackSupervisor.resumeTopActivitiesLocked();
4317                }
4318            }
4319            Binder.restoreCallingIdentity(origId);
4320        }
4321    }
4322
4323    @Override
4324    public int getRequestedOrientation(IBinder token) {
4325        synchronized (this) {
4326            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4327            if (r == null) {
4328                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4329            }
4330            return mWindowManager.getAppOrientation(r.appToken);
4331        }
4332    }
4333
4334    /**
4335     * This is the internal entry point for handling Activity.finish().
4336     *
4337     * @param token The Binder token referencing the Activity we want to finish.
4338     * @param resultCode Result code, if any, from this Activity.
4339     * @param resultData Result data (Intent), if any, from this Activity.
4340     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4341     *            the root Activity in the task.
4342     *
4343     * @return Returns true if the activity successfully finished, or false if it is still running.
4344     */
4345    @Override
4346    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4347            boolean finishTask) {
4348        // Refuse possible leaked file descriptors
4349        if (resultData != null && resultData.hasFileDescriptors() == true) {
4350            throw new IllegalArgumentException("File descriptors passed in Intent");
4351        }
4352
4353        synchronized(this) {
4354            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4355            if (r == null) {
4356                return true;
4357            }
4358            // Keep track of the root activity of the task before we finish it
4359            TaskRecord tr = r.task;
4360            ActivityRecord rootR = tr.getRootActivity();
4361            // Do not allow task to finish in Lock Task mode.
4362            if (tr == mStackSupervisor.mLockTaskModeTask) {
4363                if (rootR == r) {
4364                    mStackSupervisor.showLockTaskToast();
4365                    return false;
4366                }
4367            }
4368            if (mController != null) {
4369                // Find the first activity that is not finishing.
4370                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4371                if (next != null) {
4372                    // ask watcher if this is allowed
4373                    boolean resumeOK = true;
4374                    try {
4375                        resumeOK = mController.activityResuming(next.packageName);
4376                    } catch (RemoteException e) {
4377                        mController = null;
4378                        Watchdog.getInstance().setActivityController(null);
4379                    }
4380
4381                    if (!resumeOK) {
4382                        return false;
4383                    }
4384                }
4385            }
4386            final long origId = Binder.clearCallingIdentity();
4387            try {
4388                boolean res;
4389                if (finishTask && r == rootR) {
4390                    // If requested, remove the task that is associated to this activity only if it
4391                    // was the root activity in the task.  The result code and data is ignored because
4392                    // we don't support returning them across task boundaries.
4393                    res = removeTaskByIdLocked(tr.taskId, 0);
4394                } else {
4395                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4396                            resultData, "app-request", true);
4397                }
4398                return res;
4399            } finally {
4400                Binder.restoreCallingIdentity(origId);
4401            }
4402        }
4403    }
4404
4405    @Override
4406    public final void finishHeavyWeightApp() {
4407        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4408                != PackageManager.PERMISSION_GRANTED) {
4409            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4410                    + Binder.getCallingPid()
4411                    + ", uid=" + Binder.getCallingUid()
4412                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4413            Slog.w(TAG, msg);
4414            throw new SecurityException(msg);
4415        }
4416
4417        synchronized(this) {
4418            if (mHeavyWeightProcess == null) {
4419                return;
4420            }
4421
4422            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4423                    mHeavyWeightProcess.activities);
4424            for (int i=0; i<activities.size(); i++) {
4425                ActivityRecord r = activities.get(i);
4426                if (!r.finishing) {
4427                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4428                            null, "finish-heavy", true);
4429                }
4430            }
4431
4432            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4433                    mHeavyWeightProcess.userId, 0));
4434            mHeavyWeightProcess = null;
4435        }
4436    }
4437
4438    @Override
4439    public void crashApplication(int uid, int initialPid, String packageName,
4440            String message) {
4441        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4442                != PackageManager.PERMISSION_GRANTED) {
4443            String msg = "Permission Denial: crashApplication() from pid="
4444                    + Binder.getCallingPid()
4445                    + ", uid=" + Binder.getCallingUid()
4446                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4447            Slog.w(TAG, msg);
4448            throw new SecurityException(msg);
4449        }
4450
4451        synchronized(this) {
4452            ProcessRecord proc = null;
4453
4454            // Figure out which process to kill.  We don't trust that initialPid
4455            // still has any relation to current pids, so must scan through the
4456            // list.
4457            synchronized (mPidsSelfLocked) {
4458                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4459                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4460                    if (p.uid != uid) {
4461                        continue;
4462                    }
4463                    if (p.pid == initialPid) {
4464                        proc = p;
4465                        break;
4466                    }
4467                    if (p.pkgList.containsKey(packageName)) {
4468                        proc = p;
4469                    }
4470                }
4471            }
4472
4473            if (proc == null) {
4474                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4475                        + " initialPid=" + initialPid
4476                        + " packageName=" + packageName);
4477                return;
4478            }
4479
4480            if (proc.thread != null) {
4481                if (proc.pid == Process.myPid()) {
4482                    Log.w(TAG, "crashApplication: trying to crash self!");
4483                    return;
4484                }
4485                long ident = Binder.clearCallingIdentity();
4486                try {
4487                    proc.thread.scheduleCrash(message);
4488                } catch (RemoteException e) {
4489                }
4490                Binder.restoreCallingIdentity(ident);
4491            }
4492        }
4493    }
4494
4495    @Override
4496    public final void finishSubActivity(IBinder token, String resultWho,
4497            int requestCode) {
4498        synchronized(this) {
4499            final long origId = Binder.clearCallingIdentity();
4500            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4501            if (r != null) {
4502                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4503            }
4504            Binder.restoreCallingIdentity(origId);
4505        }
4506    }
4507
4508    @Override
4509    public boolean finishActivityAffinity(IBinder token) {
4510        synchronized(this) {
4511            final long origId = Binder.clearCallingIdentity();
4512            try {
4513                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4514
4515                ActivityRecord rootR = r.task.getRootActivity();
4516                // Do not allow task to finish in Lock Task mode.
4517                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4518                    if (rootR == r) {
4519                        mStackSupervisor.showLockTaskToast();
4520                        return false;
4521                    }
4522                }
4523                boolean res = false;
4524                if (r != null) {
4525                    res = r.task.stack.finishActivityAffinityLocked(r);
4526                }
4527                return res;
4528            } finally {
4529                Binder.restoreCallingIdentity(origId);
4530            }
4531        }
4532    }
4533
4534    @Override
4535    public void finishVoiceTask(IVoiceInteractionSession session) {
4536        synchronized(this) {
4537            final long origId = Binder.clearCallingIdentity();
4538            try {
4539                mStackSupervisor.finishVoiceTask(session);
4540            } finally {
4541                Binder.restoreCallingIdentity(origId);
4542            }
4543        }
4544
4545    }
4546
4547    @Override
4548    public boolean releaseActivityInstance(IBinder token) {
4549        synchronized(this) {
4550            final long origId = Binder.clearCallingIdentity();
4551            try {
4552                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4553                if (r.task == null || r.task.stack == null) {
4554                    return false;
4555                }
4556                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4557            } finally {
4558                Binder.restoreCallingIdentity(origId);
4559            }
4560        }
4561    }
4562
4563    @Override
4564    public void releaseSomeActivities(IApplicationThread appInt) {
4565        synchronized(this) {
4566            final long origId = Binder.clearCallingIdentity();
4567            try {
4568                ProcessRecord app = getRecordForAppLocked(appInt);
4569                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4570            } finally {
4571                Binder.restoreCallingIdentity(origId);
4572            }
4573        }
4574    }
4575
4576    @Override
4577    public boolean willActivityBeVisible(IBinder token) {
4578        synchronized(this) {
4579            ActivityStack stack = ActivityRecord.getStackLocked(token);
4580            if (stack != null) {
4581                return stack.willActivityBeVisibleLocked(token);
4582            }
4583            return false;
4584        }
4585    }
4586
4587    @Override
4588    public void overridePendingTransition(IBinder token, String packageName,
4589            int enterAnim, int exitAnim) {
4590        synchronized(this) {
4591            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4592            if (self == null) {
4593                return;
4594            }
4595
4596            final long origId = Binder.clearCallingIdentity();
4597
4598            if (self.state == ActivityState.RESUMED
4599                    || self.state == ActivityState.PAUSING) {
4600                mWindowManager.overridePendingAppTransition(packageName,
4601                        enterAnim, exitAnim, null);
4602            }
4603
4604            Binder.restoreCallingIdentity(origId);
4605        }
4606    }
4607
4608    /**
4609     * Main function for removing an existing process from the activity manager
4610     * as a result of that process going away.  Clears out all connections
4611     * to the process.
4612     */
4613    private final void handleAppDiedLocked(ProcessRecord app,
4614            boolean restarting, boolean allowRestart) {
4615        int pid = app.pid;
4616        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4617        if (!restarting) {
4618            removeLruProcessLocked(app);
4619            if (pid > 0) {
4620                ProcessList.remove(pid);
4621            }
4622        }
4623
4624        if (mProfileProc == app) {
4625            clearProfilerLocked();
4626        }
4627
4628        // Remove this application's activities from active lists.
4629        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4630
4631        app.activities.clear();
4632
4633        if (app.instrumentationClass != null) {
4634            Slog.w(TAG, "Crash of app " + app.processName
4635                  + " running instrumentation " + app.instrumentationClass);
4636            Bundle info = new Bundle();
4637            info.putString("shortMsg", "Process crashed.");
4638            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4639        }
4640
4641        if (!restarting) {
4642            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4643                // If there was nothing to resume, and we are not already
4644                // restarting this process, but there is a visible activity that
4645                // is hosted by the process...  then make sure all visible
4646                // activities are running, taking care of restarting this
4647                // process.
4648                if (hasVisibleActivities) {
4649                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4650                }
4651            }
4652        }
4653    }
4654
4655    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4656        IBinder threadBinder = thread.asBinder();
4657        // Find the application record.
4658        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4659            ProcessRecord rec = mLruProcesses.get(i);
4660            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4661                return i;
4662            }
4663        }
4664        return -1;
4665    }
4666
4667    final ProcessRecord getRecordForAppLocked(
4668            IApplicationThread thread) {
4669        if (thread == null) {
4670            return null;
4671        }
4672
4673        int appIndex = getLRURecordIndexForAppLocked(thread);
4674        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4675    }
4676
4677    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4678        // If there are no longer any background processes running,
4679        // and the app that died was not running instrumentation,
4680        // then tell everyone we are now low on memory.
4681        boolean haveBg = false;
4682        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4683            ProcessRecord rec = mLruProcesses.get(i);
4684            if (rec.thread != null
4685                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4686                haveBg = true;
4687                break;
4688            }
4689        }
4690
4691        if (!haveBg) {
4692            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4693            if (doReport) {
4694                long now = SystemClock.uptimeMillis();
4695                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4696                    doReport = false;
4697                } else {
4698                    mLastMemUsageReportTime = now;
4699                }
4700            }
4701            final ArrayList<ProcessMemInfo> memInfos
4702                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4703            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4704            long now = SystemClock.uptimeMillis();
4705            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4706                ProcessRecord rec = mLruProcesses.get(i);
4707                if (rec == dyingProc || rec.thread == null) {
4708                    continue;
4709                }
4710                if (doReport) {
4711                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4712                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4713                }
4714                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4715                    // The low memory report is overriding any current
4716                    // state for a GC request.  Make sure to do
4717                    // heavy/important/visible/foreground processes first.
4718                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4719                        rec.lastRequestedGc = 0;
4720                    } else {
4721                        rec.lastRequestedGc = rec.lastLowMemory;
4722                    }
4723                    rec.reportLowMemory = true;
4724                    rec.lastLowMemory = now;
4725                    mProcessesToGc.remove(rec);
4726                    addProcessToGcListLocked(rec);
4727                }
4728            }
4729            if (doReport) {
4730                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4731                mHandler.sendMessage(msg);
4732            }
4733            scheduleAppGcsLocked();
4734        }
4735    }
4736
4737    final void appDiedLocked(ProcessRecord app) {
4738       appDiedLocked(app, app.pid, app.thread);
4739    }
4740
4741    final void appDiedLocked(ProcessRecord app, int pid,
4742            IApplicationThread thread) {
4743
4744        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4745        synchronized (stats) {
4746            stats.noteProcessDiedLocked(app.info.uid, pid);
4747        }
4748
4749        Process.killProcessGroup(app.info.uid, pid);
4750
4751        // Clean up already done if the process has been re-started.
4752        if (app.pid == pid && app.thread != null &&
4753                app.thread.asBinder() == thread.asBinder()) {
4754            boolean doLowMem = app.instrumentationClass == null;
4755            boolean doOomAdj = doLowMem;
4756            if (!app.killedByAm) {
4757                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4758                        + ") has died.");
4759                mAllowLowerMemLevel = true;
4760            } else {
4761                // Note that we always want to do oom adj to update our state with the
4762                // new number of procs.
4763                mAllowLowerMemLevel = false;
4764                doLowMem = false;
4765            }
4766            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4767            if (DEBUG_CLEANUP) Slog.v(
4768                TAG, "Dying app: " + app + ", pid: " + pid
4769                + ", thread: " + thread.asBinder());
4770            handleAppDiedLocked(app, false, true);
4771
4772            if (doOomAdj) {
4773                updateOomAdjLocked();
4774            }
4775            if (doLowMem) {
4776                doLowMemReportIfNeededLocked(app);
4777            }
4778        } else if (app.pid != pid) {
4779            // A new process has already been started.
4780            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4781                    + ") has died and restarted (pid " + app.pid + ").");
4782            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4783        } else if (DEBUG_PROCESSES) {
4784            Slog.d(TAG, "Received spurious death notification for thread "
4785                    + thread.asBinder());
4786        }
4787    }
4788
4789    /**
4790     * If a stack trace dump file is configured, dump process stack traces.
4791     * @param clearTraces causes the dump file to be erased prior to the new
4792     *    traces being written, if true; when false, the new traces will be
4793     *    appended to any existing file content.
4794     * @param firstPids of dalvik VM processes to dump stack traces for first
4795     * @param lastPids of dalvik VM processes to dump stack traces for last
4796     * @param nativeProcs optional list of native process names to dump stack crawls
4797     * @return file containing stack traces, or null if no dump file is configured
4798     */
4799    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4800            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4801        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4802        if (tracesPath == null || tracesPath.length() == 0) {
4803            return null;
4804        }
4805
4806        File tracesFile = new File(tracesPath);
4807        try {
4808            File tracesDir = tracesFile.getParentFile();
4809            if (!tracesDir.exists()) {
4810                tracesFile.mkdirs();
4811                if (!SELinux.restorecon(tracesDir)) {
4812                    return null;
4813                }
4814            }
4815            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4816
4817            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4818            tracesFile.createNewFile();
4819            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4820        } catch (IOException e) {
4821            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4822            return null;
4823        }
4824
4825        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4826        return tracesFile;
4827    }
4828
4829    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4830            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4831        // Use a FileObserver to detect when traces finish writing.
4832        // The order of traces is considered important to maintain for legibility.
4833        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4834            @Override
4835            public synchronized void onEvent(int event, String path) { notify(); }
4836        };
4837
4838        try {
4839            observer.startWatching();
4840
4841            // First collect all of the stacks of the most important pids.
4842            if (firstPids != null) {
4843                try {
4844                    int num = firstPids.size();
4845                    for (int i = 0; i < num; i++) {
4846                        synchronized (observer) {
4847                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4848                            observer.wait(200);  // Wait for write-close, give up after 200msec
4849                        }
4850                    }
4851                } catch (InterruptedException e) {
4852                    Log.wtf(TAG, e);
4853                }
4854            }
4855
4856            // Next collect the stacks of the native pids
4857            if (nativeProcs != null) {
4858                int[] pids = Process.getPidsForCommands(nativeProcs);
4859                if (pids != null) {
4860                    for (int pid : pids) {
4861                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4862                    }
4863                }
4864            }
4865
4866            // Lastly, measure CPU usage.
4867            if (processCpuTracker != null) {
4868                processCpuTracker.init();
4869                System.gc();
4870                processCpuTracker.update();
4871                try {
4872                    synchronized (processCpuTracker) {
4873                        processCpuTracker.wait(500); // measure over 1/2 second.
4874                    }
4875                } catch (InterruptedException e) {
4876                }
4877                processCpuTracker.update();
4878
4879                // We'll take the stack crawls of just the top apps using CPU.
4880                final int N = processCpuTracker.countWorkingStats();
4881                int numProcs = 0;
4882                for (int i=0; i<N && numProcs<5; i++) {
4883                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4884                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4885                        numProcs++;
4886                        try {
4887                            synchronized (observer) {
4888                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4889                                observer.wait(200);  // Wait for write-close, give up after 200msec
4890                            }
4891                        } catch (InterruptedException e) {
4892                            Log.wtf(TAG, e);
4893                        }
4894
4895                    }
4896                }
4897            }
4898        } finally {
4899            observer.stopWatching();
4900        }
4901    }
4902
4903    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4904        if (true || IS_USER_BUILD) {
4905            return;
4906        }
4907        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4908        if (tracesPath == null || tracesPath.length() == 0) {
4909            return;
4910        }
4911
4912        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4913        StrictMode.allowThreadDiskWrites();
4914        try {
4915            final File tracesFile = new File(tracesPath);
4916            final File tracesDir = tracesFile.getParentFile();
4917            final File tracesTmp = new File(tracesDir, "__tmp__");
4918            try {
4919                if (!tracesDir.exists()) {
4920                    tracesFile.mkdirs();
4921                    if (!SELinux.restorecon(tracesDir.getPath())) {
4922                        return;
4923                    }
4924                }
4925                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4926
4927                if (tracesFile.exists()) {
4928                    tracesTmp.delete();
4929                    tracesFile.renameTo(tracesTmp);
4930                }
4931                StringBuilder sb = new StringBuilder();
4932                Time tobj = new Time();
4933                tobj.set(System.currentTimeMillis());
4934                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4935                sb.append(": ");
4936                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4937                sb.append(" since ");
4938                sb.append(msg);
4939                FileOutputStream fos = new FileOutputStream(tracesFile);
4940                fos.write(sb.toString().getBytes());
4941                if (app == null) {
4942                    fos.write("\n*** No application process!".getBytes());
4943                }
4944                fos.close();
4945                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4946            } catch (IOException e) {
4947                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4948                return;
4949            }
4950
4951            if (app != null) {
4952                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4953                firstPids.add(app.pid);
4954                dumpStackTraces(tracesPath, firstPids, null, null, null);
4955            }
4956
4957            File lastTracesFile = null;
4958            File curTracesFile = null;
4959            for (int i=9; i>=0; i--) {
4960                String name = String.format(Locale.US, "slow%02d.txt", i);
4961                curTracesFile = new File(tracesDir, name);
4962                if (curTracesFile.exists()) {
4963                    if (lastTracesFile != null) {
4964                        curTracesFile.renameTo(lastTracesFile);
4965                    } else {
4966                        curTracesFile.delete();
4967                    }
4968                }
4969                lastTracesFile = curTracesFile;
4970            }
4971            tracesFile.renameTo(curTracesFile);
4972            if (tracesTmp.exists()) {
4973                tracesTmp.renameTo(tracesFile);
4974            }
4975        } finally {
4976            StrictMode.setThreadPolicy(oldPolicy);
4977        }
4978    }
4979
4980    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4981            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4982        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4983        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4984
4985        if (mController != null) {
4986            try {
4987                // 0 == continue, -1 = kill process immediately
4988                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4989                if (res < 0 && app.pid != MY_PID) {
4990                    app.kill("anr", true);
4991                }
4992            } catch (RemoteException e) {
4993                mController = null;
4994                Watchdog.getInstance().setActivityController(null);
4995            }
4996        }
4997
4998        long anrTime = SystemClock.uptimeMillis();
4999        if (MONITOR_CPU_USAGE) {
5000            updateCpuStatsNow();
5001        }
5002
5003        synchronized (this) {
5004            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5005            if (mShuttingDown) {
5006                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5007                return;
5008            } else if (app.notResponding) {
5009                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5010                return;
5011            } else if (app.crashing) {
5012                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5013                return;
5014            }
5015
5016            // In case we come through here for the same app before completing
5017            // this one, mark as anring now so we will bail out.
5018            app.notResponding = true;
5019
5020            // Log the ANR to the event log.
5021            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5022                    app.processName, app.info.flags, annotation);
5023
5024            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5025            firstPids.add(app.pid);
5026
5027            int parentPid = app.pid;
5028            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5029            if (parentPid != app.pid) firstPids.add(parentPid);
5030
5031            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5032
5033            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5034                ProcessRecord r = mLruProcesses.get(i);
5035                if (r != null && r.thread != null) {
5036                    int pid = r.pid;
5037                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5038                        if (r.persistent) {
5039                            firstPids.add(pid);
5040                        } else {
5041                            lastPids.put(pid, Boolean.TRUE);
5042                        }
5043                    }
5044                }
5045            }
5046        }
5047
5048        // Log the ANR to the main log.
5049        StringBuilder info = new StringBuilder();
5050        info.setLength(0);
5051        info.append("ANR in ").append(app.processName);
5052        if (activity != null && activity.shortComponentName != null) {
5053            info.append(" (").append(activity.shortComponentName).append(")");
5054        }
5055        info.append("\n");
5056        info.append("PID: ").append(app.pid).append("\n");
5057        if (annotation != null) {
5058            info.append("Reason: ").append(annotation).append("\n");
5059        }
5060        if (parent != null && parent != activity) {
5061            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5062        }
5063
5064        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5065
5066        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5067                NATIVE_STACKS_OF_INTEREST);
5068
5069        String cpuInfo = null;
5070        if (MONITOR_CPU_USAGE) {
5071            updateCpuStatsNow();
5072            synchronized (mProcessCpuThread) {
5073                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5074            }
5075            info.append(processCpuTracker.printCurrentLoad());
5076            info.append(cpuInfo);
5077        }
5078
5079        info.append(processCpuTracker.printCurrentState(anrTime));
5080
5081        Slog.e(TAG, info.toString());
5082        if (tracesFile == null) {
5083            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5084            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5085        }
5086
5087        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5088                cpuInfo, tracesFile, null);
5089
5090        if (mController != null) {
5091            try {
5092                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5093                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5094                if (res != 0) {
5095                    if (res < 0 && app.pid != MY_PID) {
5096                        app.kill("anr", true);
5097                    } else {
5098                        synchronized (this) {
5099                            mServices.scheduleServiceTimeoutLocked(app);
5100                        }
5101                    }
5102                    return;
5103                }
5104            } catch (RemoteException e) {
5105                mController = null;
5106                Watchdog.getInstance().setActivityController(null);
5107            }
5108        }
5109
5110        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5111        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5112                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5113
5114        synchronized (this) {
5115            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5116                app.kill("bg anr", true);
5117                return;
5118            }
5119
5120            // Set the app's notResponding state, and look up the errorReportReceiver
5121            makeAppNotRespondingLocked(app,
5122                    activity != null ? activity.shortComponentName : null,
5123                    annotation != null ? "ANR " + annotation : "ANR",
5124                    info.toString());
5125
5126            // Bring up the infamous App Not Responding dialog
5127            Message msg = Message.obtain();
5128            HashMap<String, Object> map = new HashMap<String, Object>();
5129            msg.what = SHOW_NOT_RESPONDING_MSG;
5130            msg.obj = map;
5131            msg.arg1 = aboveSystem ? 1 : 0;
5132            map.put("app", app);
5133            if (activity != null) {
5134                map.put("activity", activity);
5135            }
5136
5137            mHandler.sendMessage(msg);
5138        }
5139    }
5140
5141    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5142        if (!mLaunchWarningShown) {
5143            mLaunchWarningShown = true;
5144            mHandler.post(new Runnable() {
5145                @Override
5146                public void run() {
5147                    synchronized (ActivityManagerService.this) {
5148                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5149                        d.show();
5150                        mHandler.postDelayed(new Runnable() {
5151                            @Override
5152                            public void run() {
5153                                synchronized (ActivityManagerService.this) {
5154                                    d.dismiss();
5155                                    mLaunchWarningShown = false;
5156                                }
5157                            }
5158                        }, 4000);
5159                    }
5160                }
5161            });
5162        }
5163    }
5164
5165    @Override
5166    public boolean clearApplicationUserData(final String packageName,
5167            final IPackageDataObserver observer, int userId) {
5168        enforceNotIsolatedCaller("clearApplicationUserData");
5169        int uid = Binder.getCallingUid();
5170        int pid = Binder.getCallingPid();
5171        userId = handleIncomingUser(pid, uid,
5172                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5173        long callingId = Binder.clearCallingIdentity();
5174        try {
5175            IPackageManager pm = AppGlobals.getPackageManager();
5176            int pkgUid = -1;
5177            synchronized(this) {
5178                try {
5179                    pkgUid = pm.getPackageUid(packageName, userId);
5180                } catch (RemoteException e) {
5181                }
5182                if (pkgUid == -1) {
5183                    Slog.w(TAG, "Invalid packageName: " + packageName);
5184                    if (observer != null) {
5185                        try {
5186                            observer.onRemoveCompleted(packageName, false);
5187                        } catch (RemoteException e) {
5188                            Slog.i(TAG, "Observer no longer exists.");
5189                        }
5190                    }
5191                    return false;
5192                }
5193                if (uid == pkgUid || checkComponentPermission(
5194                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5195                        pid, uid, -1, true)
5196                        == PackageManager.PERMISSION_GRANTED) {
5197                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5198                } else {
5199                    throw new SecurityException("PID " + pid + " does not have permission "
5200                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5201                                    + " of package " + packageName);
5202                }
5203
5204                // Remove all tasks match the cleared application package and user
5205                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5206                    final TaskRecord tr = mRecentTasks.get(i);
5207                    final String taskPackageName =
5208                            tr.getBaseIntent().getComponent().getPackageName();
5209                    if (tr.userId != userId) continue;
5210                    if (!taskPackageName.equals(packageName)) continue;
5211                    removeTaskByIdLocked(tr.taskId, 0);
5212                }
5213            }
5214
5215            try {
5216                // Clear application user data
5217                pm.clearApplicationUserData(packageName, observer, userId);
5218
5219                synchronized(this) {
5220                    // Remove all permissions granted from/to this package
5221                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5222                }
5223
5224                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5225                        Uri.fromParts("package", packageName, null));
5226                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5227                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5228                        null, null, 0, null, null, null, false, false, userId);
5229            } catch (RemoteException e) {
5230            }
5231        } finally {
5232            Binder.restoreCallingIdentity(callingId);
5233        }
5234        return true;
5235    }
5236
5237    @Override
5238    public void killBackgroundProcesses(final String packageName, int userId) {
5239        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5240                != PackageManager.PERMISSION_GRANTED &&
5241                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5242                        != PackageManager.PERMISSION_GRANTED) {
5243            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5244                    + Binder.getCallingPid()
5245                    + ", uid=" + Binder.getCallingUid()
5246                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5247            Slog.w(TAG, msg);
5248            throw new SecurityException(msg);
5249        }
5250
5251        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5252                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5253        long callingId = Binder.clearCallingIdentity();
5254        try {
5255            IPackageManager pm = AppGlobals.getPackageManager();
5256            synchronized(this) {
5257                int appId = -1;
5258                try {
5259                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5260                } catch (RemoteException e) {
5261                }
5262                if (appId == -1) {
5263                    Slog.w(TAG, "Invalid packageName: " + packageName);
5264                    return;
5265                }
5266                killPackageProcessesLocked(packageName, appId, userId,
5267                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5268            }
5269        } finally {
5270            Binder.restoreCallingIdentity(callingId);
5271        }
5272    }
5273
5274    @Override
5275    public void killAllBackgroundProcesses() {
5276        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5277                != PackageManager.PERMISSION_GRANTED) {
5278            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5279                    + Binder.getCallingPid()
5280                    + ", uid=" + Binder.getCallingUid()
5281                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5282            Slog.w(TAG, msg);
5283            throw new SecurityException(msg);
5284        }
5285
5286        long callingId = Binder.clearCallingIdentity();
5287        try {
5288            synchronized(this) {
5289                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5290                final int NP = mProcessNames.getMap().size();
5291                for (int ip=0; ip<NP; ip++) {
5292                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5293                    final int NA = apps.size();
5294                    for (int ia=0; ia<NA; ia++) {
5295                        ProcessRecord app = apps.valueAt(ia);
5296                        if (app.persistent) {
5297                            // we don't kill persistent processes
5298                            continue;
5299                        }
5300                        if (app.removed) {
5301                            procs.add(app);
5302                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5303                            app.removed = true;
5304                            procs.add(app);
5305                        }
5306                    }
5307                }
5308
5309                int N = procs.size();
5310                for (int i=0; i<N; i++) {
5311                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5312                }
5313                mAllowLowerMemLevel = true;
5314                updateOomAdjLocked();
5315                doLowMemReportIfNeededLocked(null);
5316            }
5317        } finally {
5318            Binder.restoreCallingIdentity(callingId);
5319        }
5320    }
5321
5322    @Override
5323    public void forceStopPackage(final String packageName, int userId) {
5324        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5325                != PackageManager.PERMISSION_GRANTED) {
5326            String msg = "Permission Denial: forceStopPackage() from pid="
5327                    + Binder.getCallingPid()
5328                    + ", uid=" + Binder.getCallingUid()
5329                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5330            Slog.w(TAG, msg);
5331            throw new SecurityException(msg);
5332        }
5333        final int callingPid = Binder.getCallingPid();
5334        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5335                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5336        long callingId = Binder.clearCallingIdentity();
5337        try {
5338            IPackageManager pm = AppGlobals.getPackageManager();
5339            synchronized(this) {
5340                int[] users = userId == UserHandle.USER_ALL
5341                        ? getUsersLocked() : new int[] { userId };
5342                for (int user : users) {
5343                    int pkgUid = -1;
5344                    try {
5345                        pkgUid = pm.getPackageUid(packageName, user);
5346                    } catch (RemoteException e) {
5347                    }
5348                    if (pkgUid == -1) {
5349                        Slog.w(TAG, "Invalid packageName: " + packageName);
5350                        continue;
5351                    }
5352                    try {
5353                        pm.setPackageStoppedState(packageName, true, user);
5354                    } catch (RemoteException e) {
5355                    } catch (IllegalArgumentException e) {
5356                        Slog.w(TAG, "Failed trying to unstop package "
5357                                + packageName + ": " + e);
5358                    }
5359                    if (isUserRunningLocked(user, false)) {
5360                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5361                    }
5362                }
5363            }
5364        } finally {
5365            Binder.restoreCallingIdentity(callingId);
5366        }
5367    }
5368
5369    @Override
5370    public void addPackageDependency(String packageName) {
5371        synchronized (this) {
5372            int callingPid = Binder.getCallingPid();
5373            if (callingPid == Process.myPid()) {
5374                //  Yeah, um, no.
5375                Slog.w(TAG, "Can't addPackageDependency on system process");
5376                return;
5377            }
5378            ProcessRecord proc;
5379            synchronized (mPidsSelfLocked) {
5380                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5381            }
5382            if (proc != null) {
5383                if (proc.pkgDeps == null) {
5384                    proc.pkgDeps = new ArraySet<String>(1);
5385                }
5386                proc.pkgDeps.add(packageName);
5387            }
5388        }
5389    }
5390
5391    /*
5392     * The pkg name and app id have to be specified.
5393     */
5394    @Override
5395    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5396        if (pkg == null) {
5397            return;
5398        }
5399        // Make sure the uid is valid.
5400        if (appid < 0) {
5401            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5402            return;
5403        }
5404        int callerUid = Binder.getCallingUid();
5405        // Only the system server can kill an application
5406        if (callerUid == Process.SYSTEM_UID) {
5407            // Post an aysnc message to kill the application
5408            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5409            msg.arg1 = appid;
5410            msg.arg2 = 0;
5411            Bundle bundle = new Bundle();
5412            bundle.putString("pkg", pkg);
5413            bundle.putString("reason", reason);
5414            msg.obj = bundle;
5415            mHandler.sendMessage(msg);
5416        } else {
5417            throw new SecurityException(callerUid + " cannot kill pkg: " +
5418                    pkg);
5419        }
5420    }
5421
5422    @Override
5423    public void closeSystemDialogs(String reason) {
5424        enforceNotIsolatedCaller("closeSystemDialogs");
5425
5426        final int pid = Binder.getCallingPid();
5427        final int uid = Binder.getCallingUid();
5428        final long origId = Binder.clearCallingIdentity();
5429        try {
5430            synchronized (this) {
5431                // Only allow this from foreground processes, so that background
5432                // applications can't abuse it to prevent system UI from being shown.
5433                if (uid >= Process.FIRST_APPLICATION_UID) {
5434                    ProcessRecord proc;
5435                    synchronized (mPidsSelfLocked) {
5436                        proc = mPidsSelfLocked.get(pid);
5437                    }
5438                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5439                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5440                                + " from background process " + proc);
5441                        return;
5442                    }
5443                }
5444                closeSystemDialogsLocked(reason);
5445            }
5446        } finally {
5447            Binder.restoreCallingIdentity(origId);
5448        }
5449    }
5450
5451    void closeSystemDialogsLocked(String reason) {
5452        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5453        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5454                | Intent.FLAG_RECEIVER_FOREGROUND);
5455        if (reason != null) {
5456            intent.putExtra("reason", reason);
5457        }
5458        mWindowManager.closeSystemDialogs(reason);
5459
5460        mStackSupervisor.closeSystemDialogsLocked();
5461
5462        broadcastIntentLocked(null, null, intent, null,
5463                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5464                Process.SYSTEM_UID, UserHandle.USER_ALL);
5465    }
5466
5467    @Override
5468    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5469        enforceNotIsolatedCaller("getProcessMemoryInfo");
5470        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5471        for (int i=pids.length-1; i>=0; i--) {
5472            ProcessRecord proc;
5473            int oomAdj;
5474            synchronized (this) {
5475                synchronized (mPidsSelfLocked) {
5476                    proc = mPidsSelfLocked.get(pids[i]);
5477                    oomAdj = proc != null ? proc.setAdj : 0;
5478                }
5479            }
5480            infos[i] = new Debug.MemoryInfo();
5481            Debug.getMemoryInfo(pids[i], infos[i]);
5482            if (proc != null) {
5483                synchronized (this) {
5484                    if (proc.thread != null && proc.setAdj == oomAdj) {
5485                        // Record this for posterity if the process has been stable.
5486                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5487                                infos[i].getTotalUss(), false, proc.pkgList);
5488                    }
5489                }
5490            }
5491        }
5492        return infos;
5493    }
5494
5495    @Override
5496    public long[] getProcessPss(int[] pids) {
5497        enforceNotIsolatedCaller("getProcessPss");
5498        long[] pss = new long[pids.length];
5499        for (int i=pids.length-1; i>=0; i--) {
5500            ProcessRecord proc;
5501            int oomAdj;
5502            synchronized (this) {
5503                synchronized (mPidsSelfLocked) {
5504                    proc = mPidsSelfLocked.get(pids[i]);
5505                    oomAdj = proc != null ? proc.setAdj : 0;
5506                }
5507            }
5508            long[] tmpUss = new long[1];
5509            pss[i] = Debug.getPss(pids[i], tmpUss);
5510            if (proc != null) {
5511                synchronized (this) {
5512                    if (proc.thread != null && proc.setAdj == oomAdj) {
5513                        // Record this for posterity if the process has been stable.
5514                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5515                    }
5516                }
5517            }
5518        }
5519        return pss;
5520    }
5521
5522    @Override
5523    public void killApplicationProcess(String processName, int uid) {
5524        if (processName == null) {
5525            return;
5526        }
5527
5528        int callerUid = Binder.getCallingUid();
5529        // Only the system server can kill an application
5530        if (callerUid == Process.SYSTEM_UID) {
5531            synchronized (this) {
5532                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5533                if (app != null && app.thread != null) {
5534                    try {
5535                        app.thread.scheduleSuicide();
5536                    } catch (RemoteException e) {
5537                        // If the other end already died, then our work here is done.
5538                    }
5539                } else {
5540                    Slog.w(TAG, "Process/uid not found attempting kill of "
5541                            + processName + " / " + uid);
5542                }
5543            }
5544        } else {
5545            throw new SecurityException(callerUid + " cannot kill app process: " +
5546                    processName);
5547        }
5548    }
5549
5550    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5551        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5552                false, true, false, false, UserHandle.getUserId(uid), reason);
5553        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5554                Uri.fromParts("package", packageName, null));
5555        if (!mProcessesReady) {
5556            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5557                    | Intent.FLAG_RECEIVER_FOREGROUND);
5558        }
5559        intent.putExtra(Intent.EXTRA_UID, uid);
5560        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5561        broadcastIntentLocked(null, null, intent,
5562                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5563                false, false,
5564                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5565    }
5566
5567    private void forceStopUserLocked(int userId, String reason) {
5568        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5569        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5570        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5571                | Intent.FLAG_RECEIVER_FOREGROUND);
5572        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5573        broadcastIntentLocked(null, null, intent,
5574                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5575                false, false,
5576                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5577    }
5578
5579    private final boolean killPackageProcessesLocked(String packageName, int appId,
5580            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5581            boolean doit, boolean evenPersistent, String reason) {
5582        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5583
5584        // Remove all processes this package may have touched: all with the
5585        // same UID (except for the system or root user), and all whose name
5586        // matches the package name.
5587        final int NP = mProcessNames.getMap().size();
5588        for (int ip=0; ip<NP; ip++) {
5589            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5590            final int NA = apps.size();
5591            for (int ia=0; ia<NA; ia++) {
5592                ProcessRecord app = apps.valueAt(ia);
5593                if (app.persistent && !evenPersistent) {
5594                    // we don't kill persistent processes
5595                    continue;
5596                }
5597                if (app.removed) {
5598                    if (doit) {
5599                        procs.add(app);
5600                    }
5601                    continue;
5602                }
5603
5604                // Skip process if it doesn't meet our oom adj requirement.
5605                if (app.setAdj < minOomAdj) {
5606                    continue;
5607                }
5608
5609                // If no package is specified, we call all processes under the
5610                // give user id.
5611                if (packageName == null) {
5612                    if (app.userId != userId) {
5613                        continue;
5614                    }
5615                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5616                        continue;
5617                    }
5618                // Package has been specified, we want to hit all processes
5619                // that match it.  We need to qualify this by the processes
5620                // that are running under the specified app and user ID.
5621                } else {
5622                    final boolean isDep = app.pkgDeps != null
5623                            && app.pkgDeps.contains(packageName);
5624                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5625                        continue;
5626                    }
5627                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5628                        continue;
5629                    }
5630                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5631                        continue;
5632                    }
5633                }
5634
5635                // Process has passed all conditions, kill it!
5636                if (!doit) {
5637                    return true;
5638                }
5639                app.removed = true;
5640                procs.add(app);
5641            }
5642        }
5643
5644        int N = procs.size();
5645        for (int i=0; i<N; i++) {
5646            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5647        }
5648        updateOomAdjLocked();
5649        return N > 0;
5650    }
5651
5652    private final boolean forceStopPackageLocked(String name, int appId,
5653            boolean callerWillRestart, boolean purgeCache, boolean doit,
5654            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5655        int i;
5656        int N;
5657
5658        if (userId == UserHandle.USER_ALL && name == null) {
5659            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5660        }
5661
5662        if (appId < 0 && name != null) {
5663            try {
5664                appId = UserHandle.getAppId(
5665                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5666            } catch (RemoteException e) {
5667            }
5668        }
5669
5670        if (doit) {
5671            if (name != null) {
5672                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5673                        + " user=" + userId + ": " + reason);
5674            } else {
5675                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5676            }
5677
5678            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5679            for (int ip=pmap.size()-1; ip>=0; ip--) {
5680                SparseArray<Long> ba = pmap.valueAt(ip);
5681                for (i=ba.size()-1; i>=0; i--) {
5682                    boolean remove = false;
5683                    final int entUid = ba.keyAt(i);
5684                    if (name != null) {
5685                        if (userId == UserHandle.USER_ALL) {
5686                            if (UserHandle.getAppId(entUid) == appId) {
5687                                remove = true;
5688                            }
5689                        } else {
5690                            if (entUid == UserHandle.getUid(userId, appId)) {
5691                                remove = true;
5692                            }
5693                        }
5694                    } else if (UserHandle.getUserId(entUid) == userId) {
5695                        remove = true;
5696                    }
5697                    if (remove) {
5698                        ba.removeAt(i);
5699                    }
5700                }
5701                if (ba.size() == 0) {
5702                    pmap.removeAt(ip);
5703                }
5704            }
5705        }
5706
5707        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5708                -100, callerWillRestart, true, doit, evenPersistent,
5709                name == null ? ("stop user " + userId) : ("stop " + name));
5710
5711        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5712            if (!doit) {
5713                return true;
5714            }
5715            didSomething = true;
5716        }
5717
5718        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5719            if (!doit) {
5720                return true;
5721            }
5722            didSomething = true;
5723        }
5724
5725        if (name == null) {
5726            // Remove all sticky broadcasts from this user.
5727            mStickyBroadcasts.remove(userId);
5728        }
5729
5730        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5731        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5732                userId, providers)) {
5733            if (!doit) {
5734                return true;
5735            }
5736            didSomething = true;
5737        }
5738        N = providers.size();
5739        for (i=0; i<N; i++) {
5740            removeDyingProviderLocked(null, providers.get(i), true);
5741        }
5742
5743        // Remove transient permissions granted from/to this package/user
5744        removeUriPermissionsForPackageLocked(name, userId, false);
5745
5746        if (name == null || uninstalling) {
5747            // Remove pending intents.  For now we only do this when force
5748            // stopping users, because we have some problems when doing this
5749            // for packages -- app widgets are not currently cleaned up for
5750            // such packages, so they can be left with bad pending intents.
5751            if (mIntentSenderRecords.size() > 0) {
5752                Iterator<WeakReference<PendingIntentRecord>> it
5753                        = mIntentSenderRecords.values().iterator();
5754                while (it.hasNext()) {
5755                    WeakReference<PendingIntentRecord> wpir = it.next();
5756                    if (wpir == null) {
5757                        it.remove();
5758                        continue;
5759                    }
5760                    PendingIntentRecord pir = wpir.get();
5761                    if (pir == null) {
5762                        it.remove();
5763                        continue;
5764                    }
5765                    if (name == null) {
5766                        // Stopping user, remove all objects for the user.
5767                        if (pir.key.userId != userId) {
5768                            // Not the same user, skip it.
5769                            continue;
5770                        }
5771                    } else {
5772                        if (UserHandle.getAppId(pir.uid) != appId) {
5773                            // Different app id, skip it.
5774                            continue;
5775                        }
5776                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5777                            // Different user, skip it.
5778                            continue;
5779                        }
5780                        if (!pir.key.packageName.equals(name)) {
5781                            // Different package, skip it.
5782                            continue;
5783                        }
5784                    }
5785                    if (!doit) {
5786                        return true;
5787                    }
5788                    didSomething = true;
5789                    it.remove();
5790                    pir.canceled = true;
5791                    if (pir.key.activity != null) {
5792                        pir.key.activity.pendingResults.remove(pir.ref);
5793                    }
5794                }
5795            }
5796        }
5797
5798        if (doit) {
5799            if (purgeCache && name != null) {
5800                AttributeCache ac = AttributeCache.instance();
5801                if (ac != null) {
5802                    ac.removePackage(name);
5803                }
5804            }
5805            if (mBooted) {
5806                mStackSupervisor.resumeTopActivitiesLocked();
5807                mStackSupervisor.scheduleIdleLocked();
5808            }
5809        }
5810
5811        return didSomething;
5812    }
5813
5814    private final boolean removeProcessLocked(ProcessRecord app,
5815            boolean callerWillRestart, boolean allowRestart, String reason) {
5816        final String name = app.processName;
5817        final int uid = app.uid;
5818        if (DEBUG_PROCESSES) Slog.d(
5819            TAG, "Force removing proc " + app.toShortString() + " (" + name
5820            + "/" + uid + ")");
5821
5822        mProcessNames.remove(name, uid);
5823        mIsolatedProcesses.remove(app.uid);
5824        if (mHeavyWeightProcess == app) {
5825            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5826                    mHeavyWeightProcess.userId, 0));
5827            mHeavyWeightProcess = null;
5828        }
5829        boolean needRestart = false;
5830        if (app.pid > 0 && app.pid != MY_PID) {
5831            int pid = app.pid;
5832            synchronized (mPidsSelfLocked) {
5833                mPidsSelfLocked.remove(pid);
5834                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5835            }
5836            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5837            if (app.isolated) {
5838                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5839            }
5840            app.kill(reason, true);
5841            handleAppDiedLocked(app, true, allowRestart);
5842            removeLruProcessLocked(app);
5843
5844            if (app.persistent && !app.isolated) {
5845                if (!callerWillRestart) {
5846                    addAppLocked(app.info, false, null /* ABI override */);
5847                } else {
5848                    needRestart = true;
5849                }
5850            }
5851        } else {
5852            mRemovedProcesses.add(app);
5853        }
5854
5855        return needRestart;
5856    }
5857
5858    private final void processStartTimedOutLocked(ProcessRecord app) {
5859        final int pid = app.pid;
5860        boolean gone = false;
5861        synchronized (mPidsSelfLocked) {
5862            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5863            if (knownApp != null && knownApp.thread == null) {
5864                mPidsSelfLocked.remove(pid);
5865                gone = true;
5866            }
5867        }
5868
5869        if (gone) {
5870            Slog.w(TAG, "Process " + app + " failed to attach");
5871            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5872                    pid, app.uid, app.processName);
5873            mProcessNames.remove(app.processName, app.uid);
5874            mIsolatedProcesses.remove(app.uid);
5875            if (mHeavyWeightProcess == app) {
5876                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5877                        mHeavyWeightProcess.userId, 0));
5878                mHeavyWeightProcess = null;
5879            }
5880            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5881            if (app.isolated) {
5882                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5883            }
5884            // Take care of any launching providers waiting for this process.
5885            checkAppInLaunchingProvidersLocked(app, true);
5886            // Take care of any services that are waiting for the process.
5887            mServices.processStartTimedOutLocked(app);
5888            app.kill("start timeout", true);
5889            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5890                Slog.w(TAG, "Unattached app died before backup, skipping");
5891                try {
5892                    IBackupManager bm = IBackupManager.Stub.asInterface(
5893                            ServiceManager.getService(Context.BACKUP_SERVICE));
5894                    bm.agentDisconnected(app.info.packageName);
5895                } catch (RemoteException e) {
5896                    // Can't happen; the backup manager is local
5897                }
5898            }
5899            if (isPendingBroadcastProcessLocked(pid)) {
5900                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5901                skipPendingBroadcastLocked(pid);
5902            }
5903        } else {
5904            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5905        }
5906    }
5907
5908    private final boolean attachApplicationLocked(IApplicationThread thread,
5909            int pid) {
5910
5911        // Find the application record that is being attached...  either via
5912        // the pid if we are running in multiple processes, or just pull the
5913        // next app record if we are emulating process with anonymous threads.
5914        ProcessRecord app;
5915        if (pid != MY_PID && pid >= 0) {
5916            synchronized (mPidsSelfLocked) {
5917                app = mPidsSelfLocked.get(pid);
5918            }
5919        } else {
5920            app = null;
5921        }
5922
5923        if (app == null) {
5924            Slog.w(TAG, "No pending application record for pid " + pid
5925                    + " (IApplicationThread " + thread + "); dropping process");
5926            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5927            if (pid > 0 && pid != MY_PID) {
5928                Process.killProcessQuiet(pid);
5929                //TODO: Process.killProcessGroup(app.info.uid, pid);
5930            } else {
5931                try {
5932                    thread.scheduleExit();
5933                } catch (Exception e) {
5934                    // Ignore exceptions.
5935                }
5936            }
5937            return false;
5938        }
5939
5940        // If this application record is still attached to a previous
5941        // process, clean it up now.
5942        if (app.thread != null) {
5943            handleAppDiedLocked(app, true, true);
5944        }
5945
5946        // Tell the process all about itself.
5947
5948        if (localLOGV) Slog.v(
5949                TAG, "Binding process pid " + pid + " to record " + app);
5950
5951        final String processName = app.processName;
5952        try {
5953            AppDeathRecipient adr = new AppDeathRecipient(
5954                    app, pid, thread);
5955            thread.asBinder().linkToDeath(adr, 0);
5956            app.deathRecipient = adr;
5957        } catch (RemoteException e) {
5958            app.resetPackageList(mProcessStats);
5959            startProcessLocked(app, "link fail", processName);
5960            return false;
5961        }
5962
5963        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5964
5965        app.makeActive(thread, mProcessStats);
5966        app.curAdj = app.setAdj = -100;
5967        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5968        app.forcingToForeground = null;
5969        updateProcessForegroundLocked(app, false, false);
5970        app.hasShownUi = false;
5971        app.debugging = false;
5972        app.cached = false;
5973
5974        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5975
5976        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5977        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5978
5979        if (!normalMode) {
5980            Slog.i(TAG, "Launching preboot mode app: " + app);
5981        }
5982
5983        if (localLOGV) Slog.v(
5984            TAG, "New app record " + app
5985            + " thread=" + thread.asBinder() + " pid=" + pid);
5986        try {
5987            int testMode = IApplicationThread.DEBUG_OFF;
5988            if (mDebugApp != null && mDebugApp.equals(processName)) {
5989                testMode = mWaitForDebugger
5990                    ? IApplicationThread.DEBUG_WAIT
5991                    : IApplicationThread.DEBUG_ON;
5992                app.debugging = true;
5993                if (mDebugTransient) {
5994                    mDebugApp = mOrigDebugApp;
5995                    mWaitForDebugger = mOrigWaitForDebugger;
5996                }
5997            }
5998            String profileFile = app.instrumentationProfileFile;
5999            ParcelFileDescriptor profileFd = null;
6000            int samplingInterval = 0;
6001            boolean profileAutoStop = false;
6002            if (mProfileApp != null && mProfileApp.equals(processName)) {
6003                mProfileProc = app;
6004                profileFile = mProfileFile;
6005                profileFd = mProfileFd;
6006                samplingInterval = mSamplingInterval;
6007                profileAutoStop = mAutoStopProfiler;
6008            }
6009            boolean enableOpenGlTrace = false;
6010            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6011                enableOpenGlTrace = true;
6012                mOpenGlTraceApp = null;
6013            }
6014
6015            // If the app is being launched for restore or full backup, set it up specially
6016            boolean isRestrictedBackupMode = false;
6017            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6018                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6019                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6020                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6021            }
6022
6023            ensurePackageDexOpt(app.instrumentationInfo != null
6024                    ? app.instrumentationInfo.packageName
6025                    : app.info.packageName);
6026            if (app.instrumentationClass != null) {
6027                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6028            }
6029            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6030                    + processName + " with config " + mConfiguration);
6031            ApplicationInfo appInfo = app.instrumentationInfo != null
6032                    ? app.instrumentationInfo : app.info;
6033            app.compat = compatibilityInfoForPackageLocked(appInfo);
6034            if (profileFd != null) {
6035                profileFd = profileFd.dup();
6036            }
6037            ProfilerInfo profilerInfo = profileFile == null ? null
6038                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6039            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6040                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6041                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6042                    isRestrictedBackupMode || !normalMode, app.persistent,
6043                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6044                    mCoreSettingsObserver.getCoreSettingsLocked());
6045            updateLruProcessLocked(app, false, null);
6046            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6047        } catch (Exception e) {
6048            // todo: Yikes!  What should we do?  For now we will try to
6049            // start another process, but that could easily get us in
6050            // an infinite loop of restarting processes...
6051            Slog.w(TAG, "Exception thrown during bind!", e);
6052
6053            app.resetPackageList(mProcessStats);
6054            app.unlinkDeathRecipient();
6055            startProcessLocked(app, "bind fail", processName);
6056            return false;
6057        }
6058
6059        // Remove this record from the list of starting applications.
6060        mPersistentStartingProcesses.remove(app);
6061        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6062                "Attach application locked removing on hold: " + app);
6063        mProcessesOnHold.remove(app);
6064
6065        boolean badApp = false;
6066        boolean didSomething = false;
6067
6068        // See if the top visible activity is waiting to run in this process...
6069        if (normalMode) {
6070            try {
6071                if (mStackSupervisor.attachApplicationLocked(app)) {
6072                    didSomething = true;
6073                }
6074            } catch (Exception e) {
6075                badApp = true;
6076            }
6077        }
6078
6079        // Find any services that should be running in this process...
6080        if (!badApp) {
6081            try {
6082                didSomething |= mServices.attachApplicationLocked(app, processName);
6083            } catch (Exception e) {
6084                badApp = true;
6085            }
6086        }
6087
6088        // Check if a next-broadcast receiver is in this process...
6089        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6090            try {
6091                didSomething |= sendPendingBroadcastsLocked(app);
6092            } catch (Exception e) {
6093                // If the app died trying to launch the receiver we declare it 'bad'
6094                badApp = true;
6095            }
6096        }
6097
6098        // Check whether the next backup agent is in this process...
6099        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6100            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6101            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6102            try {
6103                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6104                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6105                        mBackupTarget.backupMode);
6106            } catch (Exception e) {
6107                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6108                e.printStackTrace();
6109            }
6110        }
6111
6112        if (badApp) {
6113            // todo: Also need to kill application to deal with all
6114            // kinds of exceptions.
6115            handleAppDiedLocked(app, false, true);
6116            return false;
6117        }
6118
6119        if (!didSomething) {
6120            updateOomAdjLocked();
6121        }
6122
6123        return true;
6124    }
6125
6126    @Override
6127    public final void attachApplication(IApplicationThread thread) {
6128        synchronized (this) {
6129            int callingPid = Binder.getCallingPid();
6130            final long origId = Binder.clearCallingIdentity();
6131            attachApplicationLocked(thread, callingPid);
6132            Binder.restoreCallingIdentity(origId);
6133        }
6134    }
6135
6136    @Override
6137    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6138        final long origId = Binder.clearCallingIdentity();
6139        synchronized (this) {
6140            ActivityStack stack = ActivityRecord.getStackLocked(token);
6141            if (stack != null) {
6142                ActivityRecord r =
6143                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6144                if (stopProfiling) {
6145                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6146                        try {
6147                            mProfileFd.close();
6148                        } catch (IOException e) {
6149                        }
6150                        clearProfilerLocked();
6151                    }
6152                }
6153            }
6154        }
6155        Binder.restoreCallingIdentity(origId);
6156    }
6157
6158    void postEnableScreenAfterBootLocked() {
6159        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6160    }
6161
6162    void enableScreenAfterBoot() {
6163        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6164                SystemClock.uptimeMillis());
6165        mWindowManager.enableScreenAfterBoot();
6166
6167        synchronized (this) {
6168            updateEventDispatchingLocked();
6169        }
6170    }
6171
6172    @Override
6173    public void showBootMessage(final CharSequence msg, final boolean always) {
6174        enforceNotIsolatedCaller("showBootMessage");
6175        mWindowManager.showBootMessage(msg, always);
6176    }
6177
6178    @Override
6179    public void keyguardWaitingForActivityDrawn() {
6180        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6181        final long token = Binder.clearCallingIdentity();
6182        try {
6183            synchronized (this) {
6184                if (DEBUG_LOCKSCREEN) logLockScreen("");
6185                mWindowManager.keyguardWaitingForActivityDrawn();
6186            }
6187        } finally {
6188            Binder.restoreCallingIdentity(token);
6189        }
6190    }
6191
6192    final void finishBooting() {
6193        // Register receivers to handle package update events
6194        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6195
6196        // Let system services know.
6197        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6198
6199        synchronized (this) {
6200            // Ensure that any processes we had put on hold are now started
6201            // up.
6202            final int NP = mProcessesOnHold.size();
6203            if (NP > 0) {
6204                ArrayList<ProcessRecord> procs =
6205                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6206                for (int ip=0; ip<NP; ip++) {
6207                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6208                            + procs.get(ip));
6209                    startProcessLocked(procs.get(ip), "on-hold", null);
6210                }
6211            }
6212
6213            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6214                // Start looking for apps that are abusing wake locks.
6215                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6216                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6217                // Tell anyone interested that we are done booting!
6218                SystemProperties.set("sys.boot_completed", "1");
6219                SystemProperties.set("dev.bootcomplete", "1");
6220                for (int i=0; i<mStartedUsers.size(); i++) {
6221                    UserStartedState uss = mStartedUsers.valueAt(i);
6222                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6223                        uss.mState = UserStartedState.STATE_RUNNING;
6224                        final int userId = mStartedUsers.keyAt(i);
6225                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6226                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6227                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6228                        broadcastIntentLocked(null, null, intent, null,
6229                                new IIntentReceiver.Stub() {
6230                                    @Override
6231                                    public void performReceive(Intent intent, int resultCode,
6232                                            String data, Bundle extras, boolean ordered,
6233                                            boolean sticky, int sendingUser) {
6234                                        synchronized (ActivityManagerService.this) {
6235                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6236                                                    true, false);
6237                                        }
6238                                    }
6239                                },
6240                                0, null, null,
6241                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6242                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6243                                userId);
6244                    }
6245                }
6246                scheduleStartProfilesLocked();
6247            }
6248        }
6249    }
6250
6251    final void ensureBootCompleted() {
6252        boolean booting;
6253        boolean enableScreen;
6254        synchronized (this) {
6255            booting = mBooting;
6256            mBooting = false;
6257            enableScreen = !mBooted;
6258            mBooted = true;
6259        }
6260
6261        if (booting) {
6262            finishBooting();
6263        }
6264
6265        if (enableScreen) {
6266            enableScreenAfterBoot();
6267        }
6268    }
6269
6270    @Override
6271    public final void activityResumed(IBinder token) {
6272        final long origId = Binder.clearCallingIdentity();
6273        synchronized(this) {
6274            ActivityStack stack = ActivityRecord.getStackLocked(token);
6275            if (stack != null) {
6276                ActivityRecord.activityResumedLocked(token);
6277            }
6278        }
6279        Binder.restoreCallingIdentity(origId);
6280    }
6281
6282    @Override
6283    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
6284        final long origId = Binder.clearCallingIdentity();
6285        synchronized(this) {
6286            ActivityStack stack = ActivityRecord.getStackLocked(token);
6287            if (stack != null) {
6288                stack.activityPausedLocked(token, false, persistentState);
6289            }
6290        }
6291        Binder.restoreCallingIdentity(origId);
6292    }
6293
6294    @Override
6295    public final void activityStopped(IBinder token, Bundle icicle,
6296            PersistableBundle persistentState, CharSequence description) {
6297        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6298
6299        // Refuse possible leaked file descriptors
6300        if (icicle != null && icicle.hasFileDescriptors()) {
6301            throw new IllegalArgumentException("File descriptors passed in Bundle");
6302        }
6303
6304        final long origId = Binder.clearCallingIdentity();
6305
6306        synchronized (this) {
6307            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6308            if (r != null) {
6309                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6310            }
6311        }
6312
6313        trimApplications();
6314
6315        Binder.restoreCallingIdentity(origId);
6316    }
6317
6318    @Override
6319    public final void activityDestroyed(IBinder token) {
6320        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6321        synchronized (this) {
6322            ActivityStack stack = ActivityRecord.getStackLocked(token);
6323            if (stack != null) {
6324                stack.activityDestroyedLocked(token);
6325            }
6326        }
6327    }
6328
6329    @Override
6330    public final void backgroundResourcesReleased(IBinder token) {
6331        final long origId = Binder.clearCallingIdentity();
6332        try {
6333            synchronized (this) {
6334                ActivityStack stack = ActivityRecord.getStackLocked(token);
6335                if (stack != null) {
6336                    stack.backgroundResourcesReleased(token);
6337                }
6338            }
6339        } finally {
6340            Binder.restoreCallingIdentity(origId);
6341        }
6342    }
6343
6344    @Override
6345    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6346        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6347    }
6348
6349    @Override
6350    public final void notifyEnterAnimationComplete(IBinder token) {
6351        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6352    }
6353
6354    @Override
6355    public String getCallingPackage(IBinder token) {
6356        synchronized (this) {
6357            ActivityRecord r = getCallingRecordLocked(token);
6358            return r != null ? r.info.packageName : null;
6359        }
6360    }
6361
6362    @Override
6363    public ComponentName getCallingActivity(IBinder token) {
6364        synchronized (this) {
6365            ActivityRecord r = getCallingRecordLocked(token);
6366            return r != null ? r.intent.getComponent() : null;
6367        }
6368    }
6369
6370    private ActivityRecord getCallingRecordLocked(IBinder token) {
6371        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6372        if (r == null) {
6373            return null;
6374        }
6375        return r.resultTo;
6376    }
6377
6378    @Override
6379    public ComponentName getActivityClassForToken(IBinder token) {
6380        synchronized(this) {
6381            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6382            if (r == null) {
6383                return null;
6384            }
6385            return r.intent.getComponent();
6386        }
6387    }
6388
6389    @Override
6390    public String getPackageForToken(IBinder token) {
6391        synchronized(this) {
6392            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6393            if (r == null) {
6394                return null;
6395            }
6396            return r.packageName;
6397        }
6398    }
6399
6400    @Override
6401    public IIntentSender getIntentSender(int type,
6402            String packageName, IBinder token, String resultWho,
6403            int requestCode, Intent[] intents, String[] resolvedTypes,
6404            int flags, Bundle options, int userId) {
6405        enforceNotIsolatedCaller("getIntentSender");
6406        // Refuse possible leaked file descriptors
6407        if (intents != null) {
6408            if (intents.length < 1) {
6409                throw new IllegalArgumentException("Intents array length must be >= 1");
6410            }
6411            for (int i=0; i<intents.length; i++) {
6412                Intent intent = intents[i];
6413                if (intent != null) {
6414                    if (intent.hasFileDescriptors()) {
6415                        throw new IllegalArgumentException("File descriptors passed in Intent");
6416                    }
6417                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6418                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6419                        throw new IllegalArgumentException(
6420                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6421                    }
6422                    intents[i] = new Intent(intent);
6423                }
6424            }
6425            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6426                throw new IllegalArgumentException(
6427                        "Intent array length does not match resolvedTypes length");
6428            }
6429        }
6430        if (options != null) {
6431            if (options.hasFileDescriptors()) {
6432                throw new IllegalArgumentException("File descriptors passed in options");
6433            }
6434        }
6435
6436        synchronized(this) {
6437            int callingUid = Binder.getCallingUid();
6438            int origUserId = userId;
6439            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6440                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6441                    ALLOW_NON_FULL, "getIntentSender", null);
6442            if (origUserId == UserHandle.USER_CURRENT) {
6443                // We don't want to evaluate this until the pending intent is
6444                // actually executed.  However, we do want to always do the
6445                // security checking for it above.
6446                userId = UserHandle.USER_CURRENT;
6447            }
6448            try {
6449                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6450                    int uid = AppGlobals.getPackageManager()
6451                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6452                    if (!UserHandle.isSameApp(callingUid, uid)) {
6453                        String msg = "Permission Denial: getIntentSender() from pid="
6454                            + Binder.getCallingPid()
6455                            + ", uid=" + Binder.getCallingUid()
6456                            + ", (need uid=" + uid + ")"
6457                            + " is not allowed to send as package " + packageName;
6458                        Slog.w(TAG, msg);
6459                        throw new SecurityException(msg);
6460                    }
6461                }
6462
6463                return getIntentSenderLocked(type, packageName, callingUid, userId,
6464                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6465
6466            } catch (RemoteException e) {
6467                throw new SecurityException(e);
6468            }
6469        }
6470    }
6471
6472    IIntentSender getIntentSenderLocked(int type, String packageName,
6473            int callingUid, int userId, IBinder token, String resultWho,
6474            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6475            Bundle options) {
6476        if (DEBUG_MU)
6477            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6478        ActivityRecord activity = null;
6479        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6480            activity = ActivityRecord.isInStackLocked(token);
6481            if (activity == null) {
6482                return null;
6483            }
6484            if (activity.finishing) {
6485                return null;
6486            }
6487        }
6488
6489        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6490        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6491        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6492        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6493                |PendingIntent.FLAG_UPDATE_CURRENT);
6494
6495        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6496                type, packageName, activity, resultWho,
6497                requestCode, intents, resolvedTypes, flags, options, userId);
6498        WeakReference<PendingIntentRecord> ref;
6499        ref = mIntentSenderRecords.get(key);
6500        PendingIntentRecord rec = ref != null ? ref.get() : null;
6501        if (rec != null) {
6502            if (!cancelCurrent) {
6503                if (updateCurrent) {
6504                    if (rec.key.requestIntent != null) {
6505                        rec.key.requestIntent.replaceExtras(intents != null ?
6506                                intents[intents.length - 1] : null);
6507                    }
6508                    if (intents != null) {
6509                        intents[intents.length-1] = rec.key.requestIntent;
6510                        rec.key.allIntents = intents;
6511                        rec.key.allResolvedTypes = resolvedTypes;
6512                    } else {
6513                        rec.key.allIntents = null;
6514                        rec.key.allResolvedTypes = null;
6515                    }
6516                }
6517                return rec;
6518            }
6519            rec.canceled = true;
6520            mIntentSenderRecords.remove(key);
6521        }
6522        if (noCreate) {
6523            return rec;
6524        }
6525        rec = new PendingIntentRecord(this, key, callingUid);
6526        mIntentSenderRecords.put(key, rec.ref);
6527        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6528            if (activity.pendingResults == null) {
6529                activity.pendingResults
6530                        = new HashSet<WeakReference<PendingIntentRecord>>();
6531            }
6532            activity.pendingResults.add(rec.ref);
6533        }
6534        return rec;
6535    }
6536
6537    @Override
6538    public void cancelIntentSender(IIntentSender sender) {
6539        if (!(sender instanceof PendingIntentRecord)) {
6540            return;
6541        }
6542        synchronized(this) {
6543            PendingIntentRecord rec = (PendingIntentRecord)sender;
6544            try {
6545                int uid = AppGlobals.getPackageManager()
6546                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6547                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6548                    String msg = "Permission Denial: cancelIntentSender() from pid="
6549                        + Binder.getCallingPid()
6550                        + ", uid=" + Binder.getCallingUid()
6551                        + " is not allowed to cancel packges "
6552                        + rec.key.packageName;
6553                    Slog.w(TAG, msg);
6554                    throw new SecurityException(msg);
6555                }
6556            } catch (RemoteException e) {
6557                throw new SecurityException(e);
6558            }
6559            cancelIntentSenderLocked(rec, true);
6560        }
6561    }
6562
6563    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6564        rec.canceled = true;
6565        mIntentSenderRecords.remove(rec.key);
6566        if (cleanActivity && rec.key.activity != null) {
6567            rec.key.activity.pendingResults.remove(rec.ref);
6568        }
6569    }
6570
6571    @Override
6572    public String getPackageForIntentSender(IIntentSender pendingResult) {
6573        if (!(pendingResult instanceof PendingIntentRecord)) {
6574            return null;
6575        }
6576        try {
6577            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6578            return res.key.packageName;
6579        } catch (ClassCastException e) {
6580        }
6581        return null;
6582    }
6583
6584    @Override
6585    public int getUidForIntentSender(IIntentSender sender) {
6586        if (sender instanceof PendingIntentRecord) {
6587            try {
6588                PendingIntentRecord res = (PendingIntentRecord)sender;
6589                return res.uid;
6590            } catch (ClassCastException e) {
6591            }
6592        }
6593        return -1;
6594    }
6595
6596    @Override
6597    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6598        if (!(pendingResult instanceof PendingIntentRecord)) {
6599            return false;
6600        }
6601        try {
6602            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6603            if (res.key.allIntents == null) {
6604                return false;
6605            }
6606            for (int i=0; i<res.key.allIntents.length; i++) {
6607                Intent intent = res.key.allIntents[i];
6608                if (intent.getPackage() != null && intent.getComponent() != null) {
6609                    return false;
6610                }
6611            }
6612            return true;
6613        } catch (ClassCastException e) {
6614        }
6615        return false;
6616    }
6617
6618    @Override
6619    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6620        if (!(pendingResult instanceof PendingIntentRecord)) {
6621            return false;
6622        }
6623        try {
6624            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6625            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6626                return true;
6627            }
6628            return false;
6629        } catch (ClassCastException e) {
6630        }
6631        return false;
6632    }
6633
6634    @Override
6635    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6636        if (!(pendingResult instanceof PendingIntentRecord)) {
6637            return null;
6638        }
6639        try {
6640            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6641            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6642        } catch (ClassCastException e) {
6643        }
6644        return null;
6645    }
6646
6647    @Override
6648    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6649        if (!(pendingResult instanceof PendingIntentRecord)) {
6650            return null;
6651        }
6652        try {
6653            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6654            Intent intent = res.key.requestIntent;
6655            if (intent != null) {
6656                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6657                        || res.lastTagPrefix.equals(prefix))) {
6658                    return res.lastTag;
6659                }
6660                res.lastTagPrefix = prefix;
6661                StringBuilder sb = new StringBuilder(128);
6662                if (prefix != null) {
6663                    sb.append(prefix);
6664                }
6665                if (intent.getAction() != null) {
6666                    sb.append(intent.getAction());
6667                } else if (intent.getComponent() != null) {
6668                    intent.getComponent().appendShortString(sb);
6669                } else {
6670                    sb.append("?");
6671                }
6672                return res.lastTag = sb.toString();
6673            }
6674        } catch (ClassCastException e) {
6675        }
6676        return null;
6677    }
6678
6679    @Override
6680    public void setProcessLimit(int max) {
6681        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6682                "setProcessLimit()");
6683        synchronized (this) {
6684            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6685            mProcessLimitOverride = max;
6686        }
6687        trimApplications();
6688    }
6689
6690    @Override
6691    public int getProcessLimit() {
6692        synchronized (this) {
6693            return mProcessLimitOverride;
6694        }
6695    }
6696
6697    void foregroundTokenDied(ForegroundToken token) {
6698        synchronized (ActivityManagerService.this) {
6699            synchronized (mPidsSelfLocked) {
6700                ForegroundToken cur
6701                    = mForegroundProcesses.get(token.pid);
6702                if (cur != token) {
6703                    return;
6704                }
6705                mForegroundProcesses.remove(token.pid);
6706                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6707                if (pr == null) {
6708                    return;
6709                }
6710                pr.forcingToForeground = null;
6711                updateProcessForegroundLocked(pr, false, false);
6712            }
6713            updateOomAdjLocked();
6714        }
6715    }
6716
6717    @Override
6718    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6719        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6720                "setProcessForeground()");
6721        synchronized(this) {
6722            boolean changed = false;
6723
6724            synchronized (mPidsSelfLocked) {
6725                ProcessRecord pr = mPidsSelfLocked.get(pid);
6726                if (pr == null && isForeground) {
6727                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6728                    return;
6729                }
6730                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6731                if (oldToken != null) {
6732                    oldToken.token.unlinkToDeath(oldToken, 0);
6733                    mForegroundProcesses.remove(pid);
6734                    if (pr != null) {
6735                        pr.forcingToForeground = null;
6736                    }
6737                    changed = true;
6738                }
6739                if (isForeground && token != null) {
6740                    ForegroundToken newToken = new ForegroundToken() {
6741                        @Override
6742                        public void binderDied() {
6743                            foregroundTokenDied(this);
6744                        }
6745                    };
6746                    newToken.pid = pid;
6747                    newToken.token = token;
6748                    try {
6749                        token.linkToDeath(newToken, 0);
6750                        mForegroundProcesses.put(pid, newToken);
6751                        pr.forcingToForeground = token;
6752                        changed = true;
6753                    } catch (RemoteException e) {
6754                        // If the process died while doing this, we will later
6755                        // do the cleanup with the process death link.
6756                    }
6757                }
6758            }
6759
6760            if (changed) {
6761                updateOomAdjLocked();
6762            }
6763        }
6764    }
6765
6766    // =========================================================
6767    // PERMISSIONS
6768    // =========================================================
6769
6770    static class PermissionController extends IPermissionController.Stub {
6771        ActivityManagerService mActivityManagerService;
6772        PermissionController(ActivityManagerService activityManagerService) {
6773            mActivityManagerService = activityManagerService;
6774        }
6775
6776        @Override
6777        public boolean checkPermission(String permission, int pid, int uid) {
6778            return mActivityManagerService.checkPermission(permission, pid,
6779                    uid) == PackageManager.PERMISSION_GRANTED;
6780        }
6781    }
6782
6783    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6784        @Override
6785        public int checkComponentPermission(String permission, int pid, int uid,
6786                int owningUid, boolean exported) {
6787            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6788                    owningUid, exported);
6789        }
6790
6791        @Override
6792        public Object getAMSLock() {
6793            return ActivityManagerService.this;
6794        }
6795    }
6796
6797    /**
6798     * This can be called with or without the global lock held.
6799     */
6800    int checkComponentPermission(String permission, int pid, int uid,
6801            int owningUid, boolean exported) {
6802        // We might be performing an operation on behalf of an indirect binder
6803        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6804        // client identity accordingly before proceeding.
6805        Identity tlsIdentity = sCallerIdentity.get();
6806        if (tlsIdentity != null) {
6807            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6808                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6809            uid = tlsIdentity.uid;
6810            pid = tlsIdentity.pid;
6811        }
6812
6813        if (pid == MY_PID) {
6814            return PackageManager.PERMISSION_GRANTED;
6815        }
6816
6817        return ActivityManager.checkComponentPermission(permission, uid,
6818                owningUid, exported);
6819    }
6820
6821    /**
6822     * As the only public entry point for permissions checking, this method
6823     * can enforce the semantic that requesting a check on a null global
6824     * permission is automatically denied.  (Internally a null permission
6825     * string is used when calling {@link #checkComponentPermission} in cases
6826     * when only uid-based security is needed.)
6827     *
6828     * This can be called with or without the global lock held.
6829     */
6830    @Override
6831    public int checkPermission(String permission, int pid, int uid) {
6832        if (permission == null) {
6833            return PackageManager.PERMISSION_DENIED;
6834        }
6835        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6836    }
6837
6838    /**
6839     * Binder IPC calls go through the public entry point.
6840     * This can be called with or without the global lock held.
6841     */
6842    int checkCallingPermission(String permission) {
6843        return checkPermission(permission,
6844                Binder.getCallingPid(),
6845                UserHandle.getAppId(Binder.getCallingUid()));
6846    }
6847
6848    /**
6849     * This can be called with or without the global lock held.
6850     */
6851    void enforceCallingPermission(String permission, String func) {
6852        if (checkCallingPermission(permission)
6853                == PackageManager.PERMISSION_GRANTED) {
6854            return;
6855        }
6856
6857        String msg = "Permission Denial: " + func + " from pid="
6858                + Binder.getCallingPid()
6859                + ", uid=" + Binder.getCallingUid()
6860                + " requires " + permission;
6861        Slog.w(TAG, msg);
6862        throw new SecurityException(msg);
6863    }
6864
6865    /**
6866     * Determine if UID is holding permissions required to access {@link Uri} in
6867     * the given {@link ProviderInfo}. Final permission checking is always done
6868     * in {@link ContentProvider}.
6869     */
6870    private final boolean checkHoldingPermissionsLocked(
6871            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6872        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6873                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6874        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6875            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6876                    != PERMISSION_GRANTED) {
6877                return false;
6878            }
6879        }
6880        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6881    }
6882
6883    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6884            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6885        if (pi.applicationInfo.uid == uid) {
6886            return true;
6887        } else if (!pi.exported) {
6888            return false;
6889        }
6890
6891        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6892        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6893        try {
6894            // check if target holds top-level <provider> permissions
6895            if (!readMet && pi.readPermission != null && considerUidPermissions
6896                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6897                readMet = true;
6898            }
6899            if (!writeMet && pi.writePermission != null && considerUidPermissions
6900                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6901                writeMet = true;
6902            }
6903
6904            // track if unprotected read/write is allowed; any denied
6905            // <path-permission> below removes this ability
6906            boolean allowDefaultRead = pi.readPermission == null;
6907            boolean allowDefaultWrite = pi.writePermission == null;
6908
6909            // check if target holds any <path-permission> that match uri
6910            final PathPermission[] pps = pi.pathPermissions;
6911            if (pps != null) {
6912                final String path = grantUri.uri.getPath();
6913                int i = pps.length;
6914                while (i > 0 && (!readMet || !writeMet)) {
6915                    i--;
6916                    PathPermission pp = pps[i];
6917                    if (pp.match(path)) {
6918                        if (!readMet) {
6919                            final String pprperm = pp.getReadPermission();
6920                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6921                                    + pprperm + " for " + pp.getPath()
6922                                    + ": match=" + pp.match(path)
6923                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6924                            if (pprperm != null) {
6925                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6926                                        == PERMISSION_GRANTED) {
6927                                    readMet = true;
6928                                } else {
6929                                    allowDefaultRead = false;
6930                                }
6931                            }
6932                        }
6933                        if (!writeMet) {
6934                            final String ppwperm = pp.getWritePermission();
6935                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6936                                    + ppwperm + " for " + pp.getPath()
6937                                    + ": match=" + pp.match(path)
6938                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6939                            if (ppwperm != null) {
6940                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6941                                        == PERMISSION_GRANTED) {
6942                                    writeMet = true;
6943                                } else {
6944                                    allowDefaultWrite = false;
6945                                }
6946                            }
6947                        }
6948                    }
6949                }
6950            }
6951
6952            // grant unprotected <provider> read/write, if not blocked by
6953            // <path-permission> above
6954            if (allowDefaultRead) readMet = true;
6955            if (allowDefaultWrite) writeMet = true;
6956
6957        } catch (RemoteException e) {
6958            return false;
6959        }
6960
6961        return readMet && writeMet;
6962    }
6963
6964    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6965        ProviderInfo pi = null;
6966        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6967        if (cpr != null) {
6968            pi = cpr.info;
6969        } else {
6970            try {
6971                pi = AppGlobals.getPackageManager().resolveContentProvider(
6972                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6973            } catch (RemoteException ex) {
6974            }
6975        }
6976        return pi;
6977    }
6978
6979    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6980        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6981        if (targetUris != null) {
6982            return targetUris.get(grantUri);
6983        }
6984        return null;
6985    }
6986
6987    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6988            String targetPkg, int targetUid, GrantUri grantUri) {
6989        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6990        if (targetUris == null) {
6991            targetUris = Maps.newArrayMap();
6992            mGrantedUriPermissions.put(targetUid, targetUris);
6993        }
6994
6995        UriPermission perm = targetUris.get(grantUri);
6996        if (perm == null) {
6997            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6998            targetUris.put(grantUri, perm);
6999        }
7000
7001        return perm;
7002    }
7003
7004    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7005            final int modeFlags) {
7006        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7007        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7008                : UriPermission.STRENGTH_OWNED;
7009
7010        // Root gets to do everything.
7011        if (uid == 0) {
7012            return true;
7013        }
7014
7015        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7016        if (perms == null) return false;
7017
7018        // First look for exact match
7019        final UriPermission exactPerm = perms.get(grantUri);
7020        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7021            return true;
7022        }
7023
7024        // No exact match, look for prefixes
7025        final int N = perms.size();
7026        for (int i = 0; i < N; i++) {
7027            final UriPermission perm = perms.valueAt(i);
7028            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7029                    && perm.getStrength(modeFlags) >= minStrength) {
7030                return true;
7031            }
7032        }
7033
7034        return false;
7035    }
7036
7037    /**
7038     * @param uri This uri must NOT contain an embedded userId.
7039     * @param userId The userId in which the uri is to be resolved.
7040     */
7041    @Override
7042    public int checkUriPermission(Uri uri, int pid, int uid,
7043            final int modeFlags, int userId) {
7044        enforceNotIsolatedCaller("checkUriPermission");
7045
7046        // Another redirected-binder-call permissions check as in
7047        // {@link checkComponentPermission}.
7048        Identity tlsIdentity = sCallerIdentity.get();
7049        if (tlsIdentity != null) {
7050            uid = tlsIdentity.uid;
7051            pid = tlsIdentity.pid;
7052        }
7053
7054        // Our own process gets to do everything.
7055        if (pid == MY_PID) {
7056            return PackageManager.PERMISSION_GRANTED;
7057        }
7058        synchronized (this) {
7059            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7060                    ? PackageManager.PERMISSION_GRANTED
7061                    : PackageManager.PERMISSION_DENIED;
7062        }
7063    }
7064
7065    /**
7066     * Check if the targetPkg can be granted permission to access uri by
7067     * the callingUid using the given modeFlags.  Throws a security exception
7068     * if callingUid is not allowed to do this.  Returns the uid of the target
7069     * if the URI permission grant should be performed; returns -1 if it is not
7070     * needed (for example targetPkg already has permission to access the URI).
7071     * If you already know the uid of the target, you can supply it in
7072     * lastTargetUid else set that to -1.
7073     */
7074    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7075            final int modeFlags, int lastTargetUid) {
7076        if (!Intent.isAccessUriMode(modeFlags)) {
7077            return -1;
7078        }
7079
7080        if (targetPkg != null) {
7081            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7082                    "Checking grant " + targetPkg + " permission to " + grantUri);
7083        }
7084
7085        final IPackageManager pm = AppGlobals.getPackageManager();
7086
7087        // If this is not a content: uri, we can't do anything with it.
7088        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7089            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7090                    "Can't grant URI permission for non-content URI: " + grantUri);
7091            return -1;
7092        }
7093
7094        final String authority = grantUri.uri.getAuthority();
7095        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7096        if (pi == null) {
7097            Slog.w(TAG, "No content provider found for permission check: " +
7098                    grantUri.uri.toSafeString());
7099            return -1;
7100        }
7101
7102        int targetUid = lastTargetUid;
7103        if (targetUid < 0 && targetPkg != null) {
7104            try {
7105                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7106                if (targetUid < 0) {
7107                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7108                            "Can't grant URI permission no uid for: " + targetPkg);
7109                    return -1;
7110                }
7111            } catch (RemoteException ex) {
7112                return -1;
7113            }
7114        }
7115
7116        if (targetUid >= 0) {
7117            // First...  does the target actually need this permission?
7118            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7119                // No need to grant the target this permission.
7120                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7121                        "Target " + targetPkg + " already has full permission to " + grantUri);
7122                return -1;
7123            }
7124        } else {
7125            // First...  there is no target package, so can anyone access it?
7126            boolean allowed = pi.exported;
7127            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7128                if (pi.readPermission != null) {
7129                    allowed = false;
7130                }
7131            }
7132            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7133                if (pi.writePermission != null) {
7134                    allowed = false;
7135                }
7136            }
7137            if (allowed) {
7138                return -1;
7139            }
7140        }
7141
7142        /* There is a special cross user grant if:
7143         * - The target is on another user.
7144         * - Apps on the current user can access the uri without any uid permissions.
7145         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7146         * grant uri permissions.
7147         */
7148        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7149                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7150                modeFlags, false /*without considering the uid permissions*/);
7151
7152        // Second...  is the provider allowing granting of URI permissions?
7153        if (!specialCrossUserGrant) {
7154            if (!pi.grantUriPermissions) {
7155                throw new SecurityException("Provider " + pi.packageName
7156                        + "/" + pi.name
7157                        + " does not allow granting of Uri permissions (uri "
7158                        + grantUri + ")");
7159            }
7160            if (pi.uriPermissionPatterns != null) {
7161                final int N = pi.uriPermissionPatterns.length;
7162                boolean allowed = false;
7163                for (int i=0; i<N; i++) {
7164                    if (pi.uriPermissionPatterns[i] != null
7165                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7166                        allowed = true;
7167                        break;
7168                    }
7169                }
7170                if (!allowed) {
7171                    throw new SecurityException("Provider " + pi.packageName
7172                            + "/" + pi.name
7173                            + " does not allow granting of permission to path of Uri "
7174                            + grantUri);
7175                }
7176            }
7177        }
7178
7179        // Third...  does the caller itself have permission to access
7180        // this uri?
7181        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7182            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7183                // Require they hold a strong enough Uri permission
7184                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7185                    throw new SecurityException("Uid " + callingUid
7186                            + " does not have permission to uri " + grantUri);
7187                }
7188            }
7189        }
7190        return targetUid;
7191    }
7192
7193    /**
7194     * @param uri This uri must NOT contain an embedded userId.
7195     * @param userId The userId in which the uri is to be resolved.
7196     */
7197    @Override
7198    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7199            final int modeFlags, int userId) {
7200        enforceNotIsolatedCaller("checkGrantUriPermission");
7201        synchronized(this) {
7202            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7203                    new GrantUri(userId, uri, false), modeFlags, -1);
7204        }
7205    }
7206
7207    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7208            final int modeFlags, UriPermissionOwner owner) {
7209        if (!Intent.isAccessUriMode(modeFlags)) {
7210            return;
7211        }
7212
7213        // So here we are: the caller has the assumed permission
7214        // to the uri, and the target doesn't.  Let's now give this to
7215        // the target.
7216
7217        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7218                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7219
7220        final String authority = grantUri.uri.getAuthority();
7221        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7222        if (pi == null) {
7223            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7224            return;
7225        }
7226
7227        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7228            grantUri.prefix = true;
7229        }
7230        final UriPermission perm = findOrCreateUriPermissionLocked(
7231                pi.packageName, targetPkg, targetUid, grantUri);
7232        perm.grantModes(modeFlags, owner);
7233    }
7234
7235    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7236            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7237        if (targetPkg == null) {
7238            throw new NullPointerException("targetPkg");
7239        }
7240        int targetUid;
7241        final IPackageManager pm = AppGlobals.getPackageManager();
7242        try {
7243            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7244        } catch (RemoteException ex) {
7245            return;
7246        }
7247
7248        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7249                targetUid);
7250        if (targetUid < 0) {
7251            return;
7252        }
7253
7254        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7255                owner);
7256    }
7257
7258    static class NeededUriGrants extends ArrayList<GrantUri> {
7259        final String targetPkg;
7260        final int targetUid;
7261        final int flags;
7262
7263        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7264            this.targetPkg = targetPkg;
7265            this.targetUid = targetUid;
7266            this.flags = flags;
7267        }
7268    }
7269
7270    /**
7271     * Like checkGrantUriPermissionLocked, but takes an Intent.
7272     */
7273    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7274            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7275        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7276                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7277                + " clip=" + (intent != null ? intent.getClipData() : null)
7278                + " from " + intent + "; flags=0x"
7279                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7280
7281        if (targetPkg == null) {
7282            throw new NullPointerException("targetPkg");
7283        }
7284
7285        if (intent == null) {
7286            return null;
7287        }
7288        Uri data = intent.getData();
7289        ClipData clip = intent.getClipData();
7290        if (data == null && clip == null) {
7291            return null;
7292        }
7293        // Default userId for uris in the intent (if they don't specify it themselves)
7294        int contentUserHint = intent.getContentUserHint();
7295        if (contentUserHint == UserHandle.USER_CURRENT) {
7296            contentUserHint = UserHandle.getUserId(callingUid);
7297        }
7298        final IPackageManager pm = AppGlobals.getPackageManager();
7299        int targetUid;
7300        if (needed != null) {
7301            targetUid = needed.targetUid;
7302        } else {
7303            try {
7304                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7305            } catch (RemoteException ex) {
7306                return null;
7307            }
7308            if (targetUid < 0) {
7309                if (DEBUG_URI_PERMISSION) {
7310                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7311                            + " on user " + targetUserId);
7312                }
7313                return null;
7314            }
7315        }
7316        if (data != null) {
7317            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7318            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7319                    targetUid);
7320            if (targetUid > 0) {
7321                if (needed == null) {
7322                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7323                }
7324                needed.add(grantUri);
7325            }
7326        }
7327        if (clip != null) {
7328            for (int i=0; i<clip.getItemCount(); i++) {
7329                Uri uri = clip.getItemAt(i).getUri();
7330                if (uri != null) {
7331                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7332                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7333                            targetUid);
7334                    if (targetUid > 0) {
7335                        if (needed == null) {
7336                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7337                        }
7338                        needed.add(grantUri);
7339                    }
7340                } else {
7341                    Intent clipIntent = clip.getItemAt(i).getIntent();
7342                    if (clipIntent != null) {
7343                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7344                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7345                        if (newNeeded != null) {
7346                            needed = newNeeded;
7347                        }
7348                    }
7349                }
7350            }
7351        }
7352
7353        return needed;
7354    }
7355
7356    /**
7357     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7358     */
7359    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7360            UriPermissionOwner owner) {
7361        if (needed != null) {
7362            for (int i=0; i<needed.size(); i++) {
7363                GrantUri grantUri = needed.get(i);
7364                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7365                        grantUri, needed.flags, owner);
7366            }
7367        }
7368    }
7369
7370    void grantUriPermissionFromIntentLocked(int callingUid,
7371            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7372        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7373                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7374        if (needed == null) {
7375            return;
7376        }
7377
7378        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7379    }
7380
7381    /**
7382     * @param uri This uri must NOT contain an embedded userId.
7383     * @param userId The userId in which the uri is to be resolved.
7384     */
7385    @Override
7386    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7387            final int modeFlags, int userId) {
7388        enforceNotIsolatedCaller("grantUriPermission");
7389        GrantUri grantUri = new GrantUri(userId, uri, false);
7390        synchronized(this) {
7391            final ProcessRecord r = getRecordForAppLocked(caller);
7392            if (r == null) {
7393                throw new SecurityException("Unable to find app for caller "
7394                        + caller
7395                        + " when granting permission to uri " + grantUri);
7396            }
7397            if (targetPkg == null) {
7398                throw new IllegalArgumentException("null target");
7399            }
7400            if (grantUri == null) {
7401                throw new IllegalArgumentException("null uri");
7402            }
7403
7404            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7405                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7406                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7407                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7408
7409            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7410                    UserHandle.getUserId(r.uid));
7411        }
7412    }
7413
7414    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7415        if (perm.modeFlags == 0) {
7416            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7417                    perm.targetUid);
7418            if (perms != null) {
7419                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7420                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7421
7422                perms.remove(perm.uri);
7423                if (perms.isEmpty()) {
7424                    mGrantedUriPermissions.remove(perm.targetUid);
7425                }
7426            }
7427        }
7428    }
7429
7430    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7431        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7432
7433        final IPackageManager pm = AppGlobals.getPackageManager();
7434        final String authority = grantUri.uri.getAuthority();
7435        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7436        if (pi == null) {
7437            Slog.w(TAG, "No content provider found for permission revoke: "
7438                    + grantUri.toSafeString());
7439            return;
7440        }
7441
7442        // Does the caller have this permission on the URI?
7443        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7444            // Right now, if you are not the original owner of the permission,
7445            // you are not allowed to revoke it.
7446            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7447                throw new SecurityException("Uid " + callingUid
7448                        + " does not have permission to uri " + grantUri);
7449            //}
7450        }
7451
7452        boolean persistChanged = false;
7453
7454        // Go through all of the permissions and remove any that match.
7455        int N = mGrantedUriPermissions.size();
7456        for (int i = 0; i < N; i++) {
7457            final int targetUid = mGrantedUriPermissions.keyAt(i);
7458            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7459
7460            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7461                final UriPermission perm = it.next();
7462                if (perm.uri.sourceUserId == grantUri.sourceUserId
7463                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7464                    if (DEBUG_URI_PERMISSION)
7465                        Slog.v(TAG,
7466                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7467                    persistChanged |= perm.revokeModes(
7468                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7469                    if (perm.modeFlags == 0) {
7470                        it.remove();
7471                    }
7472                }
7473            }
7474
7475            if (perms.isEmpty()) {
7476                mGrantedUriPermissions.remove(targetUid);
7477                N--;
7478                i--;
7479            }
7480        }
7481
7482        if (persistChanged) {
7483            schedulePersistUriGrants();
7484        }
7485    }
7486
7487    /**
7488     * @param uri This uri must NOT contain an embedded userId.
7489     * @param userId The userId in which the uri is to be resolved.
7490     */
7491    @Override
7492    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7493            int userId) {
7494        enforceNotIsolatedCaller("revokeUriPermission");
7495        synchronized(this) {
7496            final ProcessRecord r = getRecordForAppLocked(caller);
7497            if (r == null) {
7498                throw new SecurityException("Unable to find app for caller "
7499                        + caller
7500                        + " when revoking permission to uri " + uri);
7501            }
7502            if (uri == null) {
7503                Slog.w(TAG, "revokeUriPermission: null uri");
7504                return;
7505            }
7506
7507            if (!Intent.isAccessUriMode(modeFlags)) {
7508                return;
7509            }
7510
7511            final IPackageManager pm = AppGlobals.getPackageManager();
7512            final String authority = uri.getAuthority();
7513            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7514            if (pi == null) {
7515                Slog.w(TAG, "No content provider found for permission revoke: "
7516                        + uri.toSafeString());
7517                return;
7518            }
7519
7520            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7521        }
7522    }
7523
7524    /**
7525     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7526     * given package.
7527     *
7528     * @param packageName Package name to match, or {@code null} to apply to all
7529     *            packages.
7530     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7531     *            to all users.
7532     * @param persistable If persistable grants should be removed.
7533     */
7534    private void removeUriPermissionsForPackageLocked(
7535            String packageName, int userHandle, boolean persistable) {
7536        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7537            throw new IllegalArgumentException("Must narrow by either package or user");
7538        }
7539
7540        boolean persistChanged = false;
7541
7542        int N = mGrantedUriPermissions.size();
7543        for (int i = 0; i < N; i++) {
7544            final int targetUid = mGrantedUriPermissions.keyAt(i);
7545            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7546
7547            // Only inspect grants matching user
7548            if (userHandle == UserHandle.USER_ALL
7549                    || userHandle == UserHandle.getUserId(targetUid)) {
7550                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7551                    final UriPermission perm = it.next();
7552
7553                    // Only inspect grants matching package
7554                    if (packageName == null || perm.sourcePkg.equals(packageName)
7555                            || perm.targetPkg.equals(packageName)) {
7556                        persistChanged |= perm.revokeModes(
7557                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7558
7559                        // Only remove when no modes remain; any persisted grants
7560                        // will keep this alive.
7561                        if (perm.modeFlags == 0) {
7562                            it.remove();
7563                        }
7564                    }
7565                }
7566
7567                if (perms.isEmpty()) {
7568                    mGrantedUriPermissions.remove(targetUid);
7569                    N--;
7570                    i--;
7571                }
7572            }
7573        }
7574
7575        if (persistChanged) {
7576            schedulePersistUriGrants();
7577        }
7578    }
7579
7580    @Override
7581    public IBinder newUriPermissionOwner(String name) {
7582        enforceNotIsolatedCaller("newUriPermissionOwner");
7583        synchronized(this) {
7584            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7585            return owner.getExternalTokenLocked();
7586        }
7587    }
7588
7589    /**
7590     * @param uri This uri must NOT contain an embedded userId.
7591     * @param sourceUserId The userId in which the uri is to be resolved.
7592     * @param targetUserId The userId of the app that receives the grant.
7593     */
7594    @Override
7595    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7596            final int modeFlags, int sourceUserId, int targetUserId) {
7597        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7598                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7599        synchronized(this) {
7600            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7601            if (owner == null) {
7602                throw new IllegalArgumentException("Unknown owner: " + token);
7603            }
7604            if (fromUid != Binder.getCallingUid()) {
7605                if (Binder.getCallingUid() != Process.myUid()) {
7606                    // Only system code can grant URI permissions on behalf
7607                    // of other users.
7608                    throw new SecurityException("nice try");
7609                }
7610            }
7611            if (targetPkg == null) {
7612                throw new IllegalArgumentException("null target");
7613            }
7614            if (uri == null) {
7615                throw new IllegalArgumentException("null uri");
7616            }
7617
7618            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7619                    modeFlags, owner, targetUserId);
7620        }
7621    }
7622
7623    /**
7624     * @param uri This uri must NOT contain an embedded userId.
7625     * @param userId The userId in which the uri is to be resolved.
7626     */
7627    @Override
7628    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7629        synchronized(this) {
7630            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7631            if (owner == null) {
7632                throw new IllegalArgumentException("Unknown owner: " + token);
7633            }
7634
7635            if (uri == null) {
7636                owner.removeUriPermissionsLocked(mode);
7637            } else {
7638                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7639            }
7640        }
7641    }
7642
7643    private void schedulePersistUriGrants() {
7644        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7645            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7646                    10 * DateUtils.SECOND_IN_MILLIS);
7647        }
7648    }
7649
7650    private void writeGrantedUriPermissions() {
7651        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7652
7653        // Snapshot permissions so we can persist without lock
7654        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7655        synchronized (this) {
7656            final int size = mGrantedUriPermissions.size();
7657            for (int i = 0; i < size; i++) {
7658                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7659                for (UriPermission perm : perms.values()) {
7660                    if (perm.persistedModeFlags != 0) {
7661                        persist.add(perm.snapshot());
7662                    }
7663                }
7664            }
7665        }
7666
7667        FileOutputStream fos = null;
7668        try {
7669            fos = mGrantFile.startWrite();
7670
7671            XmlSerializer out = new FastXmlSerializer();
7672            out.setOutput(fos, "utf-8");
7673            out.startDocument(null, true);
7674            out.startTag(null, TAG_URI_GRANTS);
7675            for (UriPermission.Snapshot perm : persist) {
7676                out.startTag(null, TAG_URI_GRANT);
7677                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7678                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7679                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7680                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7681                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7682                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7683                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7684                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7685                out.endTag(null, TAG_URI_GRANT);
7686            }
7687            out.endTag(null, TAG_URI_GRANTS);
7688            out.endDocument();
7689
7690            mGrantFile.finishWrite(fos);
7691        } catch (IOException e) {
7692            if (fos != null) {
7693                mGrantFile.failWrite(fos);
7694            }
7695        }
7696    }
7697
7698    private void readGrantedUriPermissionsLocked() {
7699        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7700
7701        final long now = System.currentTimeMillis();
7702
7703        FileInputStream fis = null;
7704        try {
7705            fis = mGrantFile.openRead();
7706            final XmlPullParser in = Xml.newPullParser();
7707            in.setInput(fis, null);
7708
7709            int type;
7710            while ((type = in.next()) != END_DOCUMENT) {
7711                final String tag = in.getName();
7712                if (type == START_TAG) {
7713                    if (TAG_URI_GRANT.equals(tag)) {
7714                        final int sourceUserId;
7715                        final int targetUserId;
7716                        final int userHandle = readIntAttribute(in,
7717                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7718                        if (userHandle != UserHandle.USER_NULL) {
7719                            // For backwards compatibility.
7720                            sourceUserId = userHandle;
7721                            targetUserId = userHandle;
7722                        } else {
7723                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7724                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7725                        }
7726                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7727                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7728                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7729                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7730                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7731                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7732
7733                        // Sanity check that provider still belongs to source package
7734                        final ProviderInfo pi = getProviderInfoLocked(
7735                                uri.getAuthority(), sourceUserId);
7736                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7737                            int targetUid = -1;
7738                            try {
7739                                targetUid = AppGlobals.getPackageManager()
7740                                        .getPackageUid(targetPkg, targetUserId);
7741                            } catch (RemoteException e) {
7742                            }
7743                            if (targetUid != -1) {
7744                                final UriPermission perm = findOrCreateUriPermissionLocked(
7745                                        sourcePkg, targetPkg, targetUid,
7746                                        new GrantUri(sourceUserId, uri, prefix));
7747                                perm.initPersistedModes(modeFlags, createdTime);
7748                            }
7749                        } else {
7750                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7751                                    + " but instead found " + pi);
7752                        }
7753                    }
7754                }
7755            }
7756        } catch (FileNotFoundException e) {
7757            // Missing grants is okay
7758        } catch (IOException e) {
7759            Log.wtf(TAG, "Failed reading Uri grants", e);
7760        } catch (XmlPullParserException e) {
7761            Log.wtf(TAG, "Failed reading Uri grants", e);
7762        } finally {
7763            IoUtils.closeQuietly(fis);
7764        }
7765    }
7766
7767    /**
7768     * @param uri This uri must NOT contain an embedded userId.
7769     * @param userId The userId in which the uri is to be resolved.
7770     */
7771    @Override
7772    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7773        enforceNotIsolatedCaller("takePersistableUriPermission");
7774
7775        Preconditions.checkFlagsArgument(modeFlags,
7776                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7777
7778        synchronized (this) {
7779            final int callingUid = Binder.getCallingUid();
7780            boolean persistChanged = false;
7781            GrantUri grantUri = new GrantUri(userId, uri, false);
7782
7783            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7784                    new GrantUri(userId, uri, false));
7785            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7786                    new GrantUri(userId, uri, true));
7787
7788            final boolean exactValid = (exactPerm != null)
7789                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7790            final boolean prefixValid = (prefixPerm != null)
7791                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7792
7793            if (!(exactValid || prefixValid)) {
7794                throw new SecurityException("No persistable permission grants found for UID "
7795                        + callingUid + " and Uri " + grantUri.toSafeString());
7796            }
7797
7798            if (exactValid) {
7799                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7800            }
7801            if (prefixValid) {
7802                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7803            }
7804
7805            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7806
7807            if (persistChanged) {
7808                schedulePersistUriGrants();
7809            }
7810        }
7811    }
7812
7813    /**
7814     * @param uri This uri must NOT contain an embedded userId.
7815     * @param userId The userId in which the uri is to be resolved.
7816     */
7817    @Override
7818    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7819        enforceNotIsolatedCaller("releasePersistableUriPermission");
7820
7821        Preconditions.checkFlagsArgument(modeFlags,
7822                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7823
7824        synchronized (this) {
7825            final int callingUid = Binder.getCallingUid();
7826            boolean persistChanged = false;
7827
7828            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7829                    new GrantUri(userId, uri, false));
7830            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7831                    new GrantUri(userId, uri, true));
7832            if (exactPerm == null && prefixPerm == null) {
7833                throw new SecurityException("No permission grants found for UID " + callingUid
7834                        + " and Uri " + uri.toSafeString());
7835            }
7836
7837            if (exactPerm != null) {
7838                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7839                removeUriPermissionIfNeededLocked(exactPerm);
7840            }
7841            if (prefixPerm != null) {
7842                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7843                removeUriPermissionIfNeededLocked(prefixPerm);
7844            }
7845
7846            if (persistChanged) {
7847                schedulePersistUriGrants();
7848            }
7849        }
7850    }
7851
7852    /**
7853     * Prune any older {@link UriPermission} for the given UID until outstanding
7854     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7855     *
7856     * @return if any mutations occured that require persisting.
7857     */
7858    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7859        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7860        if (perms == null) return false;
7861        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7862
7863        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7864        for (UriPermission perm : perms.values()) {
7865            if (perm.persistedModeFlags != 0) {
7866                persisted.add(perm);
7867            }
7868        }
7869
7870        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7871        if (trimCount <= 0) return false;
7872
7873        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7874        for (int i = 0; i < trimCount; i++) {
7875            final UriPermission perm = persisted.get(i);
7876
7877            if (DEBUG_URI_PERMISSION) {
7878                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7879            }
7880
7881            perm.releasePersistableModes(~0);
7882            removeUriPermissionIfNeededLocked(perm);
7883        }
7884
7885        return true;
7886    }
7887
7888    @Override
7889    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7890            String packageName, boolean incoming) {
7891        enforceNotIsolatedCaller("getPersistedUriPermissions");
7892        Preconditions.checkNotNull(packageName, "packageName");
7893
7894        final int callingUid = Binder.getCallingUid();
7895        final IPackageManager pm = AppGlobals.getPackageManager();
7896        try {
7897            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7898            if (packageUid != callingUid) {
7899                throw new SecurityException(
7900                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7901            }
7902        } catch (RemoteException e) {
7903            throw new SecurityException("Failed to verify package name ownership");
7904        }
7905
7906        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7907        synchronized (this) {
7908            if (incoming) {
7909                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7910                        callingUid);
7911                if (perms == null) {
7912                    Slog.w(TAG, "No permission grants found for " + packageName);
7913                } else {
7914                    for (UriPermission perm : perms.values()) {
7915                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7916                            result.add(perm.buildPersistedPublicApiObject());
7917                        }
7918                    }
7919                }
7920            } else {
7921                final int size = mGrantedUriPermissions.size();
7922                for (int i = 0; i < size; i++) {
7923                    final ArrayMap<GrantUri, UriPermission> perms =
7924                            mGrantedUriPermissions.valueAt(i);
7925                    for (UriPermission perm : perms.values()) {
7926                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7927                            result.add(perm.buildPersistedPublicApiObject());
7928                        }
7929                    }
7930                }
7931            }
7932        }
7933        return new ParceledListSlice<android.content.UriPermission>(result);
7934    }
7935
7936    @Override
7937    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7938        synchronized (this) {
7939            ProcessRecord app =
7940                who != null ? getRecordForAppLocked(who) : null;
7941            if (app == null) return;
7942
7943            Message msg = Message.obtain();
7944            msg.what = WAIT_FOR_DEBUGGER_MSG;
7945            msg.obj = app;
7946            msg.arg1 = waiting ? 1 : 0;
7947            mHandler.sendMessage(msg);
7948        }
7949    }
7950
7951    @Override
7952    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7953        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7954        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7955        outInfo.availMem = Process.getFreeMemory();
7956        outInfo.totalMem = Process.getTotalMemory();
7957        outInfo.threshold = homeAppMem;
7958        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7959        outInfo.hiddenAppThreshold = cachedAppMem;
7960        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7961                ProcessList.SERVICE_ADJ);
7962        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7963                ProcessList.VISIBLE_APP_ADJ);
7964        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7965                ProcessList.FOREGROUND_APP_ADJ);
7966    }
7967
7968    // =========================================================
7969    // TASK MANAGEMENT
7970    // =========================================================
7971
7972    @Override
7973    public List<IAppTask> getAppTasks(String callingPackage) {
7974        int callingUid = Binder.getCallingUid();
7975        long ident = Binder.clearCallingIdentity();
7976
7977        synchronized(this) {
7978            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7979            try {
7980                if (localLOGV) Slog.v(TAG, "getAppTasks");
7981
7982                final int N = mRecentTasks.size();
7983                for (int i = 0; i < N; i++) {
7984                    TaskRecord tr = mRecentTasks.get(i);
7985                    // Skip tasks that do not match the caller.  We don't need to verify
7986                    // callingPackage, because we are also limiting to callingUid and know
7987                    // that will limit to the correct security sandbox.
7988                    if (tr.effectiveUid != callingUid) {
7989                        continue;
7990                    }
7991                    Intent intent = tr.getBaseIntent();
7992                    if (intent == null ||
7993                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7994                        continue;
7995                    }
7996                    ActivityManager.RecentTaskInfo taskInfo =
7997                            createRecentTaskInfoFromTaskRecord(tr);
7998                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7999                    list.add(taskImpl);
8000                }
8001            } finally {
8002                Binder.restoreCallingIdentity(ident);
8003            }
8004            return list;
8005        }
8006    }
8007
8008    @Override
8009    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8010        final int callingUid = Binder.getCallingUid();
8011        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8012
8013        synchronized(this) {
8014            if (localLOGV) Slog.v(
8015                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8016
8017            final boolean allowed = checkCallingPermission(
8018                    android.Manifest.permission.GET_TASKS)
8019                    == PackageManager.PERMISSION_GRANTED;
8020            if (!allowed) {
8021                Slog.w(TAG, "getTasks: caller " + callingUid
8022                        + " does not hold GET_TASKS; limiting output");
8023            }
8024
8025            // TODO: Improve with MRU list from all ActivityStacks.
8026            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8027        }
8028
8029        return list;
8030    }
8031
8032    TaskRecord getMostRecentTask() {
8033        return mRecentTasks.get(0);
8034    }
8035
8036    /**
8037     * Creates a new RecentTaskInfo from a TaskRecord.
8038     */
8039    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8040        // Update the task description to reflect any changes in the task stack
8041        tr.updateTaskDescription();
8042
8043        // Compose the recent task info
8044        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8045        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8046        rti.persistentId = tr.taskId;
8047        rti.baseIntent = new Intent(tr.getBaseIntent());
8048        rti.origActivity = tr.origActivity;
8049        rti.description = tr.lastDescription;
8050        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8051        rti.userId = tr.userId;
8052        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8053        rti.firstActiveTime = tr.firstActiveTime;
8054        rti.lastActiveTime = tr.lastActiveTime;
8055        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8056        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8057        return rti;
8058    }
8059
8060    @Override
8061    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8062        final int callingUid = Binder.getCallingUid();
8063        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8064                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8065
8066        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8067        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8068        synchronized (this) {
8069            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8070                    == PackageManager.PERMISSION_GRANTED;
8071            if (!allowed) {
8072                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8073                        + " does not hold GET_TASKS; limiting output");
8074            }
8075            final boolean detailed = checkCallingPermission(
8076                    android.Manifest.permission.GET_DETAILED_TASKS)
8077                    == PackageManager.PERMISSION_GRANTED;
8078
8079            final int N = mRecentTasks.size();
8080            ArrayList<ActivityManager.RecentTaskInfo> res
8081                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8082                            maxNum < N ? maxNum : N);
8083
8084            final Set<Integer> includedUsers;
8085            if (includeProfiles) {
8086                includedUsers = getProfileIdsLocked(userId);
8087            } else {
8088                includedUsers = new HashSet<Integer>();
8089            }
8090            includedUsers.add(Integer.valueOf(userId));
8091
8092            for (int i=0; i<N && maxNum > 0; i++) {
8093                TaskRecord tr = mRecentTasks.get(i);
8094                // Only add calling user or related users recent tasks
8095                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8096                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8097                    continue;
8098                }
8099
8100                // Return the entry if desired by the caller.  We always return
8101                // the first entry, because callers always expect this to be the
8102                // foreground app.  We may filter others if the caller has
8103                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8104                // we should exclude the entry.
8105
8106                if (i == 0
8107                        || withExcluded
8108                        || (tr.intent == null)
8109                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8110                                == 0)) {
8111                    if (!allowed) {
8112                        // If the caller doesn't have the GET_TASKS permission, then only
8113                        // allow them to see a small subset of tasks -- their own and home.
8114                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8115                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8116                            continue;
8117                        }
8118                    }
8119                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8120                        if (tr.stack != null && tr.stack.isHomeStack()) {
8121                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8122                            continue;
8123                        }
8124                    }
8125                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8126                        // Don't include auto remove tasks that are finished or finishing.
8127                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8128                                + tr);
8129                        continue;
8130                    }
8131                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8132                            && !tr.isAvailable) {
8133                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8134                        continue;
8135                    }
8136
8137                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8138                    if (!detailed) {
8139                        rti.baseIntent.replaceExtras((Bundle)null);
8140                    }
8141
8142                    res.add(rti);
8143                    maxNum--;
8144                }
8145            }
8146            return res;
8147        }
8148    }
8149
8150    private TaskRecord recentTaskForIdLocked(int id) {
8151        final int N = mRecentTasks.size();
8152            for (int i=0; i<N; i++) {
8153                TaskRecord tr = mRecentTasks.get(i);
8154                if (tr.taskId == id) {
8155                    return tr;
8156                }
8157            }
8158            return null;
8159    }
8160
8161    @Override
8162    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8163        synchronized (this) {
8164            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8165                    "getTaskThumbnail()");
8166            TaskRecord tr = recentTaskForIdLocked(id);
8167            if (tr != null) {
8168                return tr.getTaskThumbnailLocked();
8169            }
8170        }
8171        return null;
8172    }
8173
8174    @Override
8175    public int addAppTask(IBinder activityToken, Intent intent,
8176            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8177        final int callingUid = Binder.getCallingUid();
8178        final long callingIdent = Binder.clearCallingIdentity();
8179
8180        try {
8181            synchronized (this) {
8182                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8183                if (r == null) {
8184                    throw new IllegalArgumentException("Activity does not exist; token="
8185                            + activityToken);
8186                }
8187                ComponentName comp = intent.getComponent();
8188                if (comp == null) {
8189                    throw new IllegalArgumentException("Intent " + intent
8190                            + " must specify explicit component");
8191                }
8192                if (thumbnail.getWidth() != mThumbnailWidth
8193                        || thumbnail.getHeight() != mThumbnailHeight) {
8194                    throw new IllegalArgumentException("Bad thumbnail size: got "
8195                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8196                            + mThumbnailWidth + "x" + mThumbnailHeight);
8197                }
8198                if (intent.getSelector() != null) {
8199                    intent.setSelector(null);
8200                }
8201                if (intent.getSourceBounds() != null) {
8202                    intent.setSourceBounds(null);
8203                }
8204                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8205                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8206                        // The caller has added this as an auto-remove task...  that makes no
8207                        // sense, so turn off auto-remove.
8208                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8209                    }
8210                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8211                    // Must be a new task.
8212                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8213                }
8214                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8215                    mLastAddedTaskActivity = null;
8216                }
8217                ActivityInfo ainfo = mLastAddedTaskActivity;
8218                if (ainfo == null) {
8219                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8220                            comp, 0, UserHandle.getUserId(callingUid));
8221                    if (ainfo.applicationInfo.uid != callingUid) {
8222                        throw new SecurityException(
8223                                "Can't add task for another application: target uid="
8224                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8225                    }
8226                }
8227
8228                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8229                        intent, description);
8230
8231                int trimIdx = trimRecentsForTask(task, false);
8232                if (trimIdx >= 0) {
8233                    // If this would have caused a trim, then we'll abort because that
8234                    // means it would be added at the end of the list but then just removed.
8235                    return -1;
8236                }
8237
8238                final int N = mRecentTasks.size();
8239                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8240                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8241                    tr.removedFromRecents(mTaskPersister);
8242                }
8243
8244                task.inRecents = true;
8245                mRecentTasks.add(task);
8246                r.task.stack.addTask(task, false, false);
8247
8248                task.setLastThumbnail(thumbnail);
8249                task.freeLastThumbnail();
8250
8251                return task.taskId;
8252            }
8253        } finally {
8254            Binder.restoreCallingIdentity(callingIdent);
8255        }
8256    }
8257
8258    @Override
8259    public Point getAppTaskThumbnailSize() {
8260        synchronized (this) {
8261            return new Point(mThumbnailWidth,  mThumbnailHeight);
8262        }
8263    }
8264
8265    @Override
8266    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8267        synchronized (this) {
8268            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8269            if (r != null) {
8270                r.taskDescription = td;
8271                r.task.updateTaskDescription();
8272            }
8273        }
8274    }
8275
8276    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8277        mRecentTasks.remove(tr);
8278        tr.removedFromRecents(mTaskPersister);
8279        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8280        Intent baseIntent = new Intent(
8281                tr.intent != null ? tr.intent : tr.affinityIntent);
8282        ComponentName component = baseIntent.getComponent();
8283        if (component == null) {
8284            Slog.w(TAG, "Now component for base intent of task: " + tr);
8285            return;
8286        }
8287
8288        // Find any running services associated with this app.
8289        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8290
8291        if (killProcesses) {
8292            // Find any running processes associated with this app.
8293            final String pkg = component.getPackageName();
8294            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8295            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8296            for (int i=0; i<pmap.size(); i++) {
8297                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8298                for (int j=0; j<uids.size(); j++) {
8299                    ProcessRecord proc = uids.valueAt(j);
8300                    if (proc.userId != tr.userId) {
8301                        continue;
8302                    }
8303                    if (!proc.pkgList.containsKey(pkg)) {
8304                        continue;
8305                    }
8306                    procs.add(proc);
8307                }
8308            }
8309
8310            // Kill the running processes.
8311            for (int i=0; i<procs.size(); i++) {
8312                ProcessRecord pr = procs.get(i);
8313                if (pr == mHomeProcess) {
8314                    // Don't kill the home process along with tasks from the same package.
8315                    continue;
8316                }
8317                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8318                    pr.kill("remove task", true);
8319                } else {
8320                    pr.waitingToKill = "remove task";
8321                }
8322            }
8323        }
8324    }
8325
8326    /**
8327     * Removes the task with the specified task id.
8328     *
8329     * @param taskId Identifier of the task to be removed.
8330     * @param flags Additional operational flags.  May be 0 or
8331     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8332     * @return Returns true if the given task was found and removed.
8333     */
8334    private boolean removeTaskByIdLocked(int taskId, int flags) {
8335        TaskRecord tr = recentTaskForIdLocked(taskId);
8336        if (tr != null) {
8337            tr.removeTaskActivitiesLocked();
8338            cleanUpRemovedTaskLocked(tr, flags);
8339            if (tr.isPersistable) {
8340                notifyTaskPersisterLocked(null, true);
8341            }
8342            return true;
8343        }
8344        return false;
8345    }
8346
8347    @Override
8348    public boolean removeTask(int taskId, int flags) {
8349        synchronized (this) {
8350            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8351                    "removeTask()");
8352            long ident = Binder.clearCallingIdentity();
8353            try {
8354                return removeTaskByIdLocked(taskId, flags);
8355            } finally {
8356                Binder.restoreCallingIdentity(ident);
8357            }
8358        }
8359    }
8360
8361    /**
8362     * TODO: Add mController hook
8363     */
8364    @Override
8365    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8366        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8367                "moveTaskToFront()");
8368
8369        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8370        synchronized(this) {
8371            moveTaskToFrontLocked(taskId, flags, options);
8372        }
8373    }
8374
8375    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8376        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8377                Binder.getCallingUid(), "Task to front")) {
8378            ActivityOptions.abort(options);
8379            return;
8380        }
8381        final long origId = Binder.clearCallingIdentity();
8382        try {
8383            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8384            if (task == null) {
8385                return;
8386            }
8387            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8388                mStackSupervisor.showLockTaskToast();
8389                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8390                return;
8391            }
8392            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8393            if (prev != null && prev.isRecentsActivity()) {
8394                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8395            }
8396            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8397        } finally {
8398            Binder.restoreCallingIdentity(origId);
8399        }
8400        ActivityOptions.abort(options);
8401    }
8402
8403    @Override
8404    public void moveTaskToBack(int taskId) {
8405        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8406                "moveTaskToBack()");
8407
8408        synchronized(this) {
8409            TaskRecord tr = recentTaskForIdLocked(taskId);
8410            if (tr != null) {
8411                if (tr == mStackSupervisor.mLockTaskModeTask) {
8412                    mStackSupervisor.showLockTaskToast();
8413                    return;
8414                }
8415                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8416                ActivityStack stack = tr.stack;
8417                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8418                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8419                            Binder.getCallingUid(), "Task to back")) {
8420                        return;
8421                    }
8422                }
8423                final long origId = Binder.clearCallingIdentity();
8424                try {
8425                    stack.moveTaskToBackLocked(taskId, null);
8426                } finally {
8427                    Binder.restoreCallingIdentity(origId);
8428                }
8429            }
8430        }
8431    }
8432
8433    /**
8434     * Moves an activity, and all of the other activities within the same task, to the bottom
8435     * of the history stack.  The activity's order within the task is unchanged.
8436     *
8437     * @param token A reference to the activity we wish to move
8438     * @param nonRoot If false then this only works if the activity is the root
8439     *                of a task; if true it will work for any activity in a task.
8440     * @return Returns true if the move completed, false if not.
8441     */
8442    @Override
8443    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8444        enforceNotIsolatedCaller("moveActivityTaskToBack");
8445        synchronized(this) {
8446            final long origId = Binder.clearCallingIdentity();
8447            try {
8448                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8449                if (taskId >= 0) {
8450                    if ((mStackSupervisor.mLockTaskModeTask != null)
8451                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8452                        mStackSupervisor.showLockTaskToast();
8453                        return false;
8454                    }
8455                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8456                }
8457            } finally {
8458                Binder.restoreCallingIdentity(origId);
8459            }
8460        }
8461        return false;
8462    }
8463
8464    @Override
8465    public void moveTaskBackwards(int task) {
8466        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8467                "moveTaskBackwards()");
8468
8469        synchronized(this) {
8470            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8471                    Binder.getCallingUid(), "Task backwards")) {
8472                return;
8473            }
8474            final long origId = Binder.clearCallingIdentity();
8475            moveTaskBackwardsLocked(task);
8476            Binder.restoreCallingIdentity(origId);
8477        }
8478    }
8479
8480    private final void moveTaskBackwardsLocked(int task) {
8481        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8482    }
8483
8484    @Override
8485    public IBinder getHomeActivityToken() throws RemoteException {
8486        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8487                "getHomeActivityToken()");
8488        synchronized (this) {
8489            return mStackSupervisor.getHomeActivityToken();
8490        }
8491    }
8492
8493    @Override
8494    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8495            IActivityContainerCallback callback) throws RemoteException {
8496        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8497                "createActivityContainer()");
8498        synchronized (this) {
8499            if (parentActivityToken == null) {
8500                throw new IllegalArgumentException("parent token must not be null");
8501            }
8502            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8503            if (r == null) {
8504                return null;
8505            }
8506            if (callback == null) {
8507                throw new IllegalArgumentException("callback must not be null");
8508            }
8509            return mStackSupervisor.createActivityContainer(r, callback);
8510        }
8511    }
8512
8513    @Override
8514    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8515        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8516                "deleteActivityContainer()");
8517        synchronized (this) {
8518            mStackSupervisor.deleteActivityContainer(container);
8519        }
8520    }
8521
8522    @Override
8523    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8524            throws RemoteException {
8525        synchronized (this) {
8526            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8527            if (stack != null) {
8528                return stack.mActivityContainer;
8529            }
8530            return null;
8531        }
8532    }
8533
8534    @Override
8535    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8536        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8537                "moveTaskToStack()");
8538        if (stackId == HOME_STACK_ID) {
8539            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8540                    new RuntimeException("here").fillInStackTrace());
8541        }
8542        synchronized (this) {
8543            long ident = Binder.clearCallingIdentity();
8544            try {
8545                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8546                        + stackId + " toTop=" + toTop);
8547                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8548            } finally {
8549                Binder.restoreCallingIdentity(ident);
8550            }
8551        }
8552    }
8553
8554    @Override
8555    public void resizeStack(int stackBoxId, Rect bounds) {
8556        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8557                "resizeStackBox()");
8558        long ident = Binder.clearCallingIdentity();
8559        try {
8560            mWindowManager.resizeStack(stackBoxId, bounds);
8561        } finally {
8562            Binder.restoreCallingIdentity(ident);
8563        }
8564    }
8565
8566    @Override
8567    public List<StackInfo> getAllStackInfos() {
8568        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8569                "getAllStackInfos()");
8570        long ident = Binder.clearCallingIdentity();
8571        try {
8572            synchronized (this) {
8573                return mStackSupervisor.getAllStackInfosLocked();
8574            }
8575        } finally {
8576            Binder.restoreCallingIdentity(ident);
8577        }
8578    }
8579
8580    @Override
8581    public StackInfo getStackInfo(int stackId) {
8582        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8583                "getStackInfo()");
8584        long ident = Binder.clearCallingIdentity();
8585        try {
8586            synchronized (this) {
8587                return mStackSupervisor.getStackInfoLocked(stackId);
8588            }
8589        } finally {
8590            Binder.restoreCallingIdentity(ident);
8591        }
8592    }
8593
8594    @Override
8595    public boolean isInHomeStack(int taskId) {
8596        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8597                "getStackInfo()");
8598        long ident = Binder.clearCallingIdentity();
8599        try {
8600            synchronized (this) {
8601                TaskRecord tr = recentTaskForIdLocked(taskId);
8602                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8603            }
8604        } finally {
8605            Binder.restoreCallingIdentity(ident);
8606        }
8607    }
8608
8609    @Override
8610    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8611        synchronized(this) {
8612            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8613        }
8614    }
8615
8616    private boolean isLockTaskAuthorized(String pkg) {
8617        final DevicePolicyManager dpm = (DevicePolicyManager)
8618                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8619        try {
8620            int uid = mContext.getPackageManager().getPackageUid(pkg,
8621                    Binder.getCallingUserHandle().getIdentifier());
8622            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8623        } catch (NameNotFoundException e) {
8624            return false;
8625        }
8626    }
8627
8628    void startLockTaskMode(TaskRecord task) {
8629        final String pkg;
8630        synchronized (this) {
8631            pkg = task.intent.getComponent().getPackageName();
8632        }
8633        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8634        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8635            final TaskRecord taskRecord = task;
8636            mHandler.post(new Runnable() {
8637                @Override
8638                public void run() {
8639                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8640                }
8641            });
8642            return;
8643        }
8644        long ident = Binder.clearCallingIdentity();
8645        try {
8646            synchronized (this) {
8647                // Since we lost lock on task, make sure it is still there.
8648                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8649                if (task != null) {
8650                    if (!isSystemInitiated
8651                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8652                        throw new IllegalArgumentException("Invalid task, not in foreground");
8653                    }
8654                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8655                }
8656            }
8657        } finally {
8658            Binder.restoreCallingIdentity(ident);
8659        }
8660    }
8661
8662    @Override
8663    public void startLockTaskMode(int taskId) {
8664        final TaskRecord task;
8665        long ident = Binder.clearCallingIdentity();
8666        try {
8667            synchronized (this) {
8668                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8669            }
8670        } finally {
8671            Binder.restoreCallingIdentity(ident);
8672        }
8673        if (task != null) {
8674            startLockTaskMode(task);
8675        }
8676    }
8677
8678    @Override
8679    public void startLockTaskMode(IBinder token) {
8680        final TaskRecord task;
8681        long ident = Binder.clearCallingIdentity();
8682        try {
8683            synchronized (this) {
8684                final ActivityRecord r = ActivityRecord.forToken(token);
8685                if (r == null) {
8686                    return;
8687                }
8688                task = r.task;
8689            }
8690        } finally {
8691            Binder.restoreCallingIdentity(ident);
8692        }
8693        if (task != null) {
8694            startLockTaskMode(task);
8695        }
8696    }
8697
8698    @Override
8699    public void startLockTaskModeOnCurrent() throws RemoteException {
8700        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8701                "startLockTaskModeOnCurrent");
8702        ActivityRecord r = null;
8703        synchronized (this) {
8704            r = mStackSupervisor.topRunningActivityLocked();
8705        }
8706        startLockTaskMode(r.task);
8707    }
8708
8709    @Override
8710    public void stopLockTaskMode() {
8711        // Verify that the user matches the package of the intent for the TaskRecord
8712        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8713        // and stopLockTaskMode.
8714        final int callingUid = Binder.getCallingUid();
8715        if (callingUid != Process.SYSTEM_UID) {
8716            try {
8717                String pkg =
8718                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8719                int uid = mContext.getPackageManager().getPackageUid(pkg,
8720                        Binder.getCallingUserHandle().getIdentifier());
8721                if (uid != callingUid) {
8722                    throw new SecurityException("Invalid uid, expected " + uid);
8723                }
8724            } catch (NameNotFoundException e) {
8725                Log.d(TAG, "stopLockTaskMode " + e);
8726                return;
8727            }
8728        }
8729        long ident = Binder.clearCallingIdentity();
8730        try {
8731            Log.d(TAG, "stopLockTaskMode");
8732            // Stop lock task
8733            synchronized (this) {
8734                mStackSupervisor.setLockTaskModeLocked(null, false);
8735            }
8736        } finally {
8737            Binder.restoreCallingIdentity(ident);
8738        }
8739    }
8740
8741    @Override
8742    public void stopLockTaskModeOnCurrent() throws RemoteException {
8743        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8744                "stopLockTaskModeOnCurrent");
8745        long ident = Binder.clearCallingIdentity();
8746        try {
8747            stopLockTaskMode();
8748        } finally {
8749            Binder.restoreCallingIdentity(ident);
8750        }
8751    }
8752
8753    @Override
8754    public boolean isInLockTaskMode() {
8755        synchronized (this) {
8756            return mStackSupervisor.isInLockTaskMode();
8757        }
8758    }
8759
8760    // =========================================================
8761    // CONTENT PROVIDERS
8762    // =========================================================
8763
8764    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8765        List<ProviderInfo> providers = null;
8766        try {
8767            providers = AppGlobals.getPackageManager().
8768                queryContentProviders(app.processName, app.uid,
8769                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8770        } catch (RemoteException ex) {
8771        }
8772        if (DEBUG_MU)
8773            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8774        int userId = app.userId;
8775        if (providers != null) {
8776            int N = providers.size();
8777            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8778            for (int i=0; i<N; i++) {
8779                ProviderInfo cpi =
8780                    (ProviderInfo)providers.get(i);
8781                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8782                        cpi.name, cpi.flags);
8783                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8784                    // This is a singleton provider, but a user besides the
8785                    // default user is asking to initialize a process it runs
8786                    // in...  well, no, it doesn't actually run in this process,
8787                    // it runs in the process of the default user.  Get rid of it.
8788                    providers.remove(i);
8789                    N--;
8790                    i--;
8791                    continue;
8792                }
8793
8794                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8795                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8796                if (cpr == null) {
8797                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8798                    mProviderMap.putProviderByClass(comp, cpr);
8799                }
8800                if (DEBUG_MU)
8801                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8802                app.pubProviders.put(cpi.name, cpr);
8803                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8804                    // Don't add this if it is a platform component that is marked
8805                    // to run in multiple processes, because this is actually
8806                    // part of the framework so doesn't make sense to track as a
8807                    // separate apk in the process.
8808                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8809                            mProcessStats);
8810                }
8811                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8812            }
8813        }
8814        return providers;
8815    }
8816
8817    /**
8818     * Check if {@link ProcessRecord} has a possible chance at accessing the
8819     * given {@link ProviderInfo}. Final permission checking is always done
8820     * in {@link ContentProvider}.
8821     */
8822    private final String checkContentProviderPermissionLocked(
8823            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8824        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8825        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8826        boolean checkedGrants = false;
8827        if (checkUser) {
8828            // Looking for cross-user grants before enforcing the typical cross-users permissions
8829            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8830            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8831                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8832                    return null;
8833                }
8834                checkedGrants = true;
8835            }
8836            userId = handleIncomingUser(callingPid, callingUid, userId,
8837                    false, ALLOW_NON_FULL,
8838                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8839            if (userId != tmpTargetUserId) {
8840                // When we actually went to determine the final targer user ID, this ended
8841                // up different than our initial check for the authority.  This is because
8842                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8843                // SELF.  So we need to re-check the grants again.
8844                checkedGrants = false;
8845            }
8846        }
8847        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8848                cpi.applicationInfo.uid, cpi.exported)
8849                == PackageManager.PERMISSION_GRANTED) {
8850            return null;
8851        }
8852        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8853                cpi.applicationInfo.uid, cpi.exported)
8854                == PackageManager.PERMISSION_GRANTED) {
8855            return null;
8856        }
8857
8858        PathPermission[] pps = cpi.pathPermissions;
8859        if (pps != null) {
8860            int i = pps.length;
8861            while (i > 0) {
8862                i--;
8863                PathPermission pp = pps[i];
8864                String pprperm = pp.getReadPermission();
8865                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8866                        cpi.applicationInfo.uid, cpi.exported)
8867                        == PackageManager.PERMISSION_GRANTED) {
8868                    return null;
8869                }
8870                String ppwperm = pp.getWritePermission();
8871                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8872                        cpi.applicationInfo.uid, cpi.exported)
8873                        == PackageManager.PERMISSION_GRANTED) {
8874                    return null;
8875                }
8876            }
8877        }
8878        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8879            return null;
8880        }
8881
8882        String msg;
8883        if (!cpi.exported) {
8884            msg = "Permission Denial: opening provider " + cpi.name
8885                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8886                    + ", uid=" + callingUid + ") that is not exported from uid "
8887                    + cpi.applicationInfo.uid;
8888        } else {
8889            msg = "Permission Denial: opening provider " + cpi.name
8890                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8891                    + ", uid=" + callingUid + ") requires "
8892                    + cpi.readPermission + " or " + cpi.writePermission;
8893        }
8894        Slog.w(TAG, msg);
8895        return msg;
8896    }
8897
8898    /**
8899     * Returns if the ContentProvider has granted a uri to callingUid
8900     */
8901    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8902        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8903        if (perms != null) {
8904            for (int i=perms.size()-1; i>=0; i--) {
8905                GrantUri grantUri = perms.keyAt(i);
8906                if (grantUri.sourceUserId == userId || !checkUser) {
8907                    if (matchesProvider(grantUri.uri, cpi)) {
8908                        return true;
8909                    }
8910                }
8911            }
8912        }
8913        return false;
8914    }
8915
8916    /**
8917     * Returns true if the uri authority is one of the authorities specified in the provider.
8918     */
8919    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8920        String uriAuth = uri.getAuthority();
8921        String cpiAuth = cpi.authority;
8922        if (cpiAuth.indexOf(';') == -1) {
8923            return cpiAuth.equals(uriAuth);
8924        }
8925        String[] cpiAuths = cpiAuth.split(";");
8926        int length = cpiAuths.length;
8927        for (int i = 0; i < length; i++) {
8928            if (cpiAuths[i].equals(uriAuth)) return true;
8929        }
8930        return false;
8931    }
8932
8933    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8934            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8935        if (r != null) {
8936            for (int i=0; i<r.conProviders.size(); i++) {
8937                ContentProviderConnection conn = r.conProviders.get(i);
8938                if (conn.provider == cpr) {
8939                    if (DEBUG_PROVIDER) Slog.v(TAG,
8940                            "Adding provider requested by "
8941                            + r.processName + " from process "
8942                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8943                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8944                    if (stable) {
8945                        conn.stableCount++;
8946                        conn.numStableIncs++;
8947                    } else {
8948                        conn.unstableCount++;
8949                        conn.numUnstableIncs++;
8950                    }
8951                    return conn;
8952                }
8953            }
8954            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8955            if (stable) {
8956                conn.stableCount = 1;
8957                conn.numStableIncs = 1;
8958            } else {
8959                conn.unstableCount = 1;
8960                conn.numUnstableIncs = 1;
8961            }
8962            cpr.connections.add(conn);
8963            r.conProviders.add(conn);
8964            return conn;
8965        }
8966        cpr.addExternalProcessHandleLocked(externalProcessToken);
8967        return null;
8968    }
8969
8970    boolean decProviderCountLocked(ContentProviderConnection conn,
8971            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8972        if (conn != null) {
8973            cpr = conn.provider;
8974            if (DEBUG_PROVIDER) Slog.v(TAG,
8975                    "Removing provider requested by "
8976                    + conn.client.processName + " from process "
8977                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8978                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8979            if (stable) {
8980                conn.stableCount--;
8981            } else {
8982                conn.unstableCount--;
8983            }
8984            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8985                cpr.connections.remove(conn);
8986                conn.client.conProviders.remove(conn);
8987                return true;
8988            }
8989            return false;
8990        }
8991        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8992        return false;
8993    }
8994
8995    private void checkTime(long startTime, String where) {
8996        long now = SystemClock.elapsedRealtime();
8997        if ((now-startTime) > 1000) {
8998            // If we are taking more than a second, log about it.
8999            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9000        }
9001    }
9002
9003    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9004            String name, IBinder token, boolean stable, int userId) {
9005        ContentProviderRecord cpr;
9006        ContentProviderConnection conn = null;
9007        ProviderInfo cpi = null;
9008
9009        synchronized(this) {
9010            long startTime = SystemClock.elapsedRealtime();
9011
9012            ProcessRecord r = null;
9013            if (caller != null) {
9014                r = getRecordForAppLocked(caller);
9015                if (r == null) {
9016                    throw new SecurityException(
9017                            "Unable to find app for caller " + caller
9018                          + " (pid=" + Binder.getCallingPid()
9019                          + ") when getting content provider " + name);
9020                }
9021            }
9022
9023            boolean checkCrossUser = true;
9024
9025            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9026
9027            // First check if this content provider has been published...
9028            cpr = mProviderMap.getProviderByName(name, userId);
9029            // If that didn't work, check if it exists for user 0 and then
9030            // verify that it's a singleton provider before using it.
9031            if (cpr == null && userId != UserHandle.USER_OWNER) {
9032                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9033                if (cpr != null) {
9034                    cpi = cpr.info;
9035                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9036                            cpi.name, cpi.flags)
9037                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9038                        userId = UserHandle.USER_OWNER;
9039                        checkCrossUser = false;
9040                    } else {
9041                        cpr = null;
9042                        cpi = null;
9043                    }
9044                }
9045            }
9046
9047            boolean providerRunning = cpr != null;
9048            if (providerRunning) {
9049                cpi = cpr.info;
9050                String msg;
9051                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9052                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9053                        != null) {
9054                    throw new SecurityException(msg);
9055                }
9056                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9057
9058                if (r != null && cpr.canRunHere(r)) {
9059                    // This provider has been published or is in the process
9060                    // of being published...  but it is also allowed to run
9061                    // in the caller's process, so don't make a connection
9062                    // and just let the caller instantiate its own instance.
9063                    ContentProviderHolder holder = cpr.newHolder(null);
9064                    // don't give caller the provider object, it needs
9065                    // to make its own.
9066                    holder.provider = null;
9067                    return holder;
9068                }
9069
9070                final long origId = Binder.clearCallingIdentity();
9071
9072                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9073
9074                // In this case the provider instance already exists, so we can
9075                // return it right away.
9076                conn = incProviderCountLocked(r, cpr, token, stable);
9077                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9078                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9079                        // If this is a perceptible app accessing the provider,
9080                        // make sure to count it as being accessed and thus
9081                        // back up on the LRU list.  This is good because
9082                        // content providers are often expensive to start.
9083                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9084                        updateLruProcessLocked(cpr.proc, false, null);
9085                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9086                    }
9087                }
9088
9089                if (cpr.proc != null) {
9090                    if (false) {
9091                        if (cpr.name.flattenToShortString().equals(
9092                                "com.android.providers.calendar/.CalendarProvider2")) {
9093                            Slog.v(TAG, "****************** KILLING "
9094                                + cpr.name.flattenToShortString());
9095                            Process.killProcess(cpr.proc.pid);
9096                        }
9097                    }
9098                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9099                    boolean success = updateOomAdjLocked(cpr.proc);
9100                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9101                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9102                    // NOTE: there is still a race here where a signal could be
9103                    // pending on the process even though we managed to update its
9104                    // adj level.  Not sure what to do about this, but at least
9105                    // the race is now smaller.
9106                    if (!success) {
9107                        // Uh oh...  it looks like the provider's process
9108                        // has been killed on us.  We need to wait for a new
9109                        // process to be started, and make sure its death
9110                        // doesn't kill our process.
9111                        Slog.i(TAG,
9112                                "Existing provider " + cpr.name.flattenToShortString()
9113                                + " is crashing; detaching " + r);
9114                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9115                        checkTime(startTime, "getContentProviderImpl: before appDied");
9116                        appDiedLocked(cpr.proc);
9117                        checkTime(startTime, "getContentProviderImpl: after appDied");
9118                        if (!lastRef) {
9119                            // This wasn't the last ref our process had on
9120                            // the provider...  we have now been killed, bail.
9121                            return null;
9122                        }
9123                        providerRunning = false;
9124                        conn = null;
9125                    }
9126                }
9127
9128                Binder.restoreCallingIdentity(origId);
9129            }
9130
9131            boolean singleton;
9132            if (!providerRunning) {
9133                try {
9134                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9135                    cpi = AppGlobals.getPackageManager().
9136                        resolveContentProvider(name,
9137                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9138                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9139                } catch (RemoteException ex) {
9140                }
9141                if (cpi == null) {
9142                    return null;
9143                }
9144                // If the provider is a singleton AND
9145                // (it's a call within the same user || the provider is a
9146                // privileged app)
9147                // Then allow connecting to the singleton provider
9148                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9149                        cpi.name, cpi.flags)
9150                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9151                if (singleton) {
9152                    userId = UserHandle.USER_OWNER;
9153                }
9154                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9155                checkTime(startTime, "getContentProviderImpl: got app info for user");
9156
9157                String msg;
9158                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9159                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9160                        != null) {
9161                    throw new SecurityException(msg);
9162                }
9163                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9164
9165                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9166                        && !cpi.processName.equals("system")) {
9167                    // If this content provider does not run in the system
9168                    // process, and the system is not yet ready to run other
9169                    // processes, then fail fast instead of hanging.
9170                    throw new IllegalArgumentException(
9171                            "Attempt to launch content provider before system ready");
9172                }
9173
9174                // Make sure that the user who owns this provider is started.  If not,
9175                // we don't want to allow it to run.
9176                if (mStartedUsers.get(userId) == null) {
9177                    Slog.w(TAG, "Unable to launch app "
9178                            + cpi.applicationInfo.packageName + "/"
9179                            + cpi.applicationInfo.uid + " for provider "
9180                            + name + ": user " + userId + " is stopped");
9181                    return null;
9182                }
9183
9184                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9185                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9186                cpr = mProviderMap.getProviderByClass(comp, userId);
9187                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9188                final boolean firstClass = cpr == null;
9189                if (firstClass) {
9190                    try {
9191                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9192                        ApplicationInfo ai =
9193                            AppGlobals.getPackageManager().
9194                                getApplicationInfo(
9195                                        cpi.applicationInfo.packageName,
9196                                        STOCK_PM_FLAGS, userId);
9197                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9198                        if (ai == null) {
9199                            Slog.w(TAG, "No package info for content provider "
9200                                    + cpi.name);
9201                            return null;
9202                        }
9203                        ai = getAppInfoForUser(ai, userId);
9204                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9205                    } catch (RemoteException ex) {
9206                        // pm is in same process, this will never happen.
9207                    }
9208                }
9209
9210                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9211
9212                if (r != null && cpr.canRunHere(r)) {
9213                    // If this is a multiprocess provider, then just return its
9214                    // info and allow the caller to instantiate it.  Only do
9215                    // this if the provider is the same user as the caller's
9216                    // process, or can run as root (so can be in any process).
9217                    return cpr.newHolder(null);
9218                }
9219
9220                if (DEBUG_PROVIDER) {
9221                    RuntimeException e = new RuntimeException("here");
9222                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9223                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9224                }
9225
9226                // This is single process, and our app is now connecting to it.
9227                // See if we are already in the process of launching this
9228                // provider.
9229                final int N = mLaunchingProviders.size();
9230                int i;
9231                for (i=0; i<N; i++) {
9232                    if (mLaunchingProviders.get(i) == cpr) {
9233                        break;
9234                    }
9235                }
9236
9237                // If the provider is not already being launched, then get it
9238                // started.
9239                if (i >= N) {
9240                    final long origId = Binder.clearCallingIdentity();
9241
9242                    try {
9243                        // Content provider is now in use, its package can't be stopped.
9244                        try {
9245                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9246                            AppGlobals.getPackageManager().setPackageStoppedState(
9247                                    cpr.appInfo.packageName, false, userId);
9248                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9249                        } catch (RemoteException e) {
9250                        } catch (IllegalArgumentException e) {
9251                            Slog.w(TAG, "Failed trying to unstop package "
9252                                    + cpr.appInfo.packageName + ": " + e);
9253                        }
9254
9255                        // Use existing process if already started
9256                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9257                        ProcessRecord proc = getProcessRecordLocked(
9258                                cpi.processName, cpr.appInfo.uid, false);
9259                        if (proc != null && proc.thread != null) {
9260                            if (DEBUG_PROVIDER) {
9261                                Slog.d(TAG, "Installing in existing process " + proc);
9262                            }
9263                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9264                            proc.pubProviders.put(cpi.name, cpr);
9265                            try {
9266                                proc.thread.scheduleInstallProvider(cpi);
9267                            } catch (RemoteException e) {
9268                            }
9269                        } else {
9270                            checkTime(startTime, "getContentProviderImpl: before start process");
9271                            proc = startProcessLocked(cpi.processName,
9272                                    cpr.appInfo, false, 0, "content provider",
9273                                    new ComponentName(cpi.applicationInfo.packageName,
9274                                            cpi.name), false, false, false);
9275                            checkTime(startTime, "getContentProviderImpl: after start process");
9276                            if (proc == null) {
9277                                Slog.w(TAG, "Unable to launch app "
9278                                        + cpi.applicationInfo.packageName + "/"
9279                                        + cpi.applicationInfo.uid + " for provider "
9280                                        + name + ": process is bad");
9281                                return null;
9282                            }
9283                        }
9284                        cpr.launchingApp = proc;
9285                        mLaunchingProviders.add(cpr);
9286                    } finally {
9287                        Binder.restoreCallingIdentity(origId);
9288                    }
9289                }
9290
9291                checkTime(startTime, "getContentProviderImpl: updating data structures");
9292
9293                // Make sure the provider is published (the same provider class
9294                // may be published under multiple names).
9295                if (firstClass) {
9296                    mProviderMap.putProviderByClass(comp, cpr);
9297                }
9298
9299                mProviderMap.putProviderByName(name, cpr);
9300                conn = incProviderCountLocked(r, cpr, token, stable);
9301                if (conn != null) {
9302                    conn.waiting = true;
9303                }
9304            }
9305            checkTime(startTime, "getContentProviderImpl: done!");
9306        }
9307
9308        // Wait for the provider to be published...
9309        synchronized (cpr) {
9310            while (cpr.provider == null) {
9311                if (cpr.launchingApp == null) {
9312                    Slog.w(TAG, "Unable to launch app "
9313                            + cpi.applicationInfo.packageName + "/"
9314                            + cpi.applicationInfo.uid + " for provider "
9315                            + name + ": launching app became null");
9316                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9317                            UserHandle.getUserId(cpi.applicationInfo.uid),
9318                            cpi.applicationInfo.packageName,
9319                            cpi.applicationInfo.uid, name);
9320                    return null;
9321                }
9322                try {
9323                    if (DEBUG_MU) {
9324                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9325                                + cpr.launchingApp);
9326                    }
9327                    if (conn != null) {
9328                        conn.waiting = true;
9329                    }
9330                    cpr.wait();
9331                } catch (InterruptedException ex) {
9332                } finally {
9333                    if (conn != null) {
9334                        conn.waiting = false;
9335                    }
9336                }
9337            }
9338        }
9339        return cpr != null ? cpr.newHolder(conn) : null;
9340    }
9341
9342    @Override
9343    public final ContentProviderHolder getContentProvider(
9344            IApplicationThread caller, String name, int userId, boolean stable) {
9345        enforceNotIsolatedCaller("getContentProvider");
9346        if (caller == null) {
9347            String msg = "null IApplicationThread when getting content provider "
9348                    + name;
9349            Slog.w(TAG, msg);
9350            throw new SecurityException(msg);
9351        }
9352        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9353        // with cross-user grant.
9354        return getContentProviderImpl(caller, name, null, stable, userId);
9355    }
9356
9357    public ContentProviderHolder getContentProviderExternal(
9358            String name, int userId, IBinder token) {
9359        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9360            "Do not have permission in call getContentProviderExternal()");
9361        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9362                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9363        return getContentProviderExternalUnchecked(name, token, userId);
9364    }
9365
9366    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9367            IBinder token, int userId) {
9368        return getContentProviderImpl(null, name, token, true, userId);
9369    }
9370
9371    /**
9372     * Drop a content provider from a ProcessRecord's bookkeeping
9373     */
9374    public void removeContentProvider(IBinder connection, boolean stable) {
9375        enforceNotIsolatedCaller("removeContentProvider");
9376        long ident = Binder.clearCallingIdentity();
9377        try {
9378            synchronized (this) {
9379                ContentProviderConnection conn;
9380                try {
9381                    conn = (ContentProviderConnection)connection;
9382                } catch (ClassCastException e) {
9383                    String msg ="removeContentProvider: " + connection
9384                            + " not a ContentProviderConnection";
9385                    Slog.w(TAG, msg);
9386                    throw new IllegalArgumentException(msg);
9387                }
9388                if (conn == null) {
9389                    throw new NullPointerException("connection is null");
9390                }
9391                if (decProviderCountLocked(conn, null, null, stable)) {
9392                    updateOomAdjLocked();
9393                }
9394            }
9395        } finally {
9396            Binder.restoreCallingIdentity(ident);
9397        }
9398    }
9399
9400    public void removeContentProviderExternal(String name, IBinder token) {
9401        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9402            "Do not have permission in call removeContentProviderExternal()");
9403        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9404    }
9405
9406    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9407        synchronized (this) {
9408            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9409            if(cpr == null) {
9410                //remove from mProvidersByClass
9411                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9412                return;
9413            }
9414
9415            //update content provider record entry info
9416            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9417            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9418            if (localCpr.hasExternalProcessHandles()) {
9419                if (localCpr.removeExternalProcessHandleLocked(token)) {
9420                    updateOomAdjLocked();
9421                } else {
9422                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9423                            + " with no external reference for token: "
9424                            + token + ".");
9425                }
9426            } else {
9427                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9428                        + " with no external references.");
9429            }
9430        }
9431    }
9432
9433    public final void publishContentProviders(IApplicationThread caller,
9434            List<ContentProviderHolder> providers) {
9435        if (providers == null) {
9436            return;
9437        }
9438
9439        enforceNotIsolatedCaller("publishContentProviders");
9440        synchronized (this) {
9441            final ProcessRecord r = getRecordForAppLocked(caller);
9442            if (DEBUG_MU)
9443                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9444            if (r == null) {
9445                throw new SecurityException(
9446                        "Unable to find app for caller " + caller
9447                      + " (pid=" + Binder.getCallingPid()
9448                      + ") when publishing content providers");
9449            }
9450
9451            final long origId = Binder.clearCallingIdentity();
9452
9453            final int N = providers.size();
9454            for (int i=0; i<N; i++) {
9455                ContentProviderHolder src = providers.get(i);
9456                if (src == null || src.info == null || src.provider == null) {
9457                    continue;
9458                }
9459                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9460                if (DEBUG_MU)
9461                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9462                if (dst != null) {
9463                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9464                    mProviderMap.putProviderByClass(comp, dst);
9465                    String names[] = dst.info.authority.split(";");
9466                    for (int j = 0; j < names.length; j++) {
9467                        mProviderMap.putProviderByName(names[j], dst);
9468                    }
9469
9470                    int NL = mLaunchingProviders.size();
9471                    int j;
9472                    for (j=0; j<NL; j++) {
9473                        if (mLaunchingProviders.get(j) == dst) {
9474                            mLaunchingProviders.remove(j);
9475                            j--;
9476                            NL--;
9477                        }
9478                    }
9479                    synchronized (dst) {
9480                        dst.provider = src.provider;
9481                        dst.proc = r;
9482                        dst.notifyAll();
9483                    }
9484                    updateOomAdjLocked(r);
9485                }
9486            }
9487
9488            Binder.restoreCallingIdentity(origId);
9489        }
9490    }
9491
9492    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9493        ContentProviderConnection conn;
9494        try {
9495            conn = (ContentProviderConnection)connection;
9496        } catch (ClassCastException e) {
9497            String msg ="refContentProvider: " + connection
9498                    + " not a ContentProviderConnection";
9499            Slog.w(TAG, msg);
9500            throw new IllegalArgumentException(msg);
9501        }
9502        if (conn == null) {
9503            throw new NullPointerException("connection is null");
9504        }
9505
9506        synchronized (this) {
9507            if (stable > 0) {
9508                conn.numStableIncs += stable;
9509            }
9510            stable = conn.stableCount + stable;
9511            if (stable < 0) {
9512                throw new IllegalStateException("stableCount < 0: " + stable);
9513            }
9514
9515            if (unstable > 0) {
9516                conn.numUnstableIncs += unstable;
9517            }
9518            unstable = conn.unstableCount + unstable;
9519            if (unstable < 0) {
9520                throw new IllegalStateException("unstableCount < 0: " + unstable);
9521            }
9522
9523            if ((stable+unstable) <= 0) {
9524                throw new IllegalStateException("ref counts can't go to zero here: stable="
9525                        + stable + " unstable=" + unstable);
9526            }
9527            conn.stableCount = stable;
9528            conn.unstableCount = unstable;
9529            return !conn.dead;
9530        }
9531    }
9532
9533    public void unstableProviderDied(IBinder connection) {
9534        ContentProviderConnection conn;
9535        try {
9536            conn = (ContentProviderConnection)connection;
9537        } catch (ClassCastException e) {
9538            String msg ="refContentProvider: " + connection
9539                    + " not a ContentProviderConnection";
9540            Slog.w(TAG, msg);
9541            throw new IllegalArgumentException(msg);
9542        }
9543        if (conn == null) {
9544            throw new NullPointerException("connection is null");
9545        }
9546
9547        // Safely retrieve the content provider associated with the connection.
9548        IContentProvider provider;
9549        synchronized (this) {
9550            provider = conn.provider.provider;
9551        }
9552
9553        if (provider == null) {
9554            // Um, yeah, we're way ahead of you.
9555            return;
9556        }
9557
9558        // Make sure the caller is being honest with us.
9559        if (provider.asBinder().pingBinder()) {
9560            // Er, no, still looks good to us.
9561            synchronized (this) {
9562                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9563                        + " says " + conn + " died, but we don't agree");
9564                return;
9565            }
9566        }
9567
9568        // Well look at that!  It's dead!
9569        synchronized (this) {
9570            if (conn.provider.provider != provider) {
9571                // But something changed...  good enough.
9572                return;
9573            }
9574
9575            ProcessRecord proc = conn.provider.proc;
9576            if (proc == null || proc.thread == null) {
9577                // Seems like the process is already cleaned up.
9578                return;
9579            }
9580
9581            // As far as we're concerned, this is just like receiving a
9582            // death notification...  just a bit prematurely.
9583            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9584                    + ") early provider death");
9585            final long ident = Binder.clearCallingIdentity();
9586            try {
9587                appDiedLocked(proc);
9588            } finally {
9589                Binder.restoreCallingIdentity(ident);
9590            }
9591        }
9592    }
9593
9594    @Override
9595    public void appNotRespondingViaProvider(IBinder connection) {
9596        enforceCallingPermission(
9597                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9598
9599        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9600        if (conn == null) {
9601            Slog.w(TAG, "ContentProviderConnection is null");
9602            return;
9603        }
9604
9605        final ProcessRecord host = conn.provider.proc;
9606        if (host == null) {
9607            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9608            return;
9609        }
9610
9611        final long token = Binder.clearCallingIdentity();
9612        try {
9613            appNotResponding(host, null, null, false, "ContentProvider not responding");
9614        } finally {
9615            Binder.restoreCallingIdentity(token);
9616        }
9617    }
9618
9619    public final void installSystemProviders() {
9620        List<ProviderInfo> providers;
9621        synchronized (this) {
9622            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9623            providers = generateApplicationProvidersLocked(app);
9624            if (providers != null) {
9625                for (int i=providers.size()-1; i>=0; i--) {
9626                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9627                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9628                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9629                                + ": not system .apk");
9630                        providers.remove(i);
9631                    }
9632                }
9633            }
9634        }
9635        if (providers != null) {
9636            mSystemThread.installSystemProviders(providers);
9637        }
9638
9639        mCoreSettingsObserver = new CoreSettingsObserver(this);
9640
9641        //mUsageStatsService.monitorPackages();
9642    }
9643
9644    /**
9645     * Allows apps to retrieve the MIME type of a URI.
9646     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9647     * users, then it does not need permission to access the ContentProvider.
9648     * Either, it needs cross-user uri grants.
9649     *
9650     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9651     *
9652     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9653     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9654     */
9655    public String getProviderMimeType(Uri uri, int userId) {
9656        enforceNotIsolatedCaller("getProviderMimeType");
9657        final String name = uri.getAuthority();
9658        int callingUid = Binder.getCallingUid();
9659        int callingPid = Binder.getCallingPid();
9660        long ident = 0;
9661        boolean clearedIdentity = false;
9662        userId = unsafeConvertIncomingUser(userId);
9663        if (UserHandle.getUserId(callingUid) != userId) {
9664            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9665                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9666                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9667                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9668                clearedIdentity = true;
9669                ident = Binder.clearCallingIdentity();
9670            }
9671        }
9672        ContentProviderHolder holder = null;
9673        try {
9674            holder = getContentProviderExternalUnchecked(name, null, userId);
9675            if (holder != null) {
9676                return holder.provider.getType(uri);
9677            }
9678        } catch (RemoteException e) {
9679            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9680            return null;
9681        } finally {
9682            // We need to clear the identity to call removeContentProviderExternalUnchecked
9683            if (!clearedIdentity) {
9684                ident = Binder.clearCallingIdentity();
9685            }
9686            try {
9687                if (holder != null) {
9688                    removeContentProviderExternalUnchecked(name, null, userId);
9689                }
9690            } finally {
9691                Binder.restoreCallingIdentity(ident);
9692            }
9693        }
9694
9695        return null;
9696    }
9697
9698    // =========================================================
9699    // GLOBAL MANAGEMENT
9700    // =========================================================
9701
9702    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9703            boolean isolated, int isolatedUid) {
9704        String proc = customProcess != null ? customProcess : info.processName;
9705        BatteryStatsImpl.Uid.Proc ps = null;
9706        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9707        int uid = info.uid;
9708        if (isolated) {
9709            if (isolatedUid == 0) {
9710                int userId = UserHandle.getUserId(uid);
9711                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9712                while (true) {
9713                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9714                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9715                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9716                    }
9717                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9718                    mNextIsolatedProcessUid++;
9719                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9720                        // No process for this uid, use it.
9721                        break;
9722                    }
9723                    stepsLeft--;
9724                    if (stepsLeft <= 0) {
9725                        return null;
9726                    }
9727                }
9728            } else {
9729                // Special case for startIsolatedProcess (internal only), where
9730                // the uid of the isolated process is specified by the caller.
9731                uid = isolatedUid;
9732            }
9733        }
9734        return new ProcessRecord(stats, info, proc, uid);
9735    }
9736
9737    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9738            String abiOverride) {
9739        ProcessRecord app;
9740        if (!isolated) {
9741            app = getProcessRecordLocked(info.processName, info.uid, true);
9742        } else {
9743            app = null;
9744        }
9745
9746        if (app == null) {
9747            app = newProcessRecordLocked(info, null, isolated, 0);
9748            mProcessNames.put(info.processName, app.uid, app);
9749            if (isolated) {
9750                mIsolatedProcesses.put(app.uid, app);
9751            }
9752            updateLruProcessLocked(app, false, null);
9753            updateOomAdjLocked();
9754        }
9755
9756        // This package really, really can not be stopped.
9757        try {
9758            AppGlobals.getPackageManager().setPackageStoppedState(
9759                    info.packageName, false, UserHandle.getUserId(app.uid));
9760        } catch (RemoteException e) {
9761        } catch (IllegalArgumentException e) {
9762            Slog.w(TAG, "Failed trying to unstop package "
9763                    + info.packageName + ": " + e);
9764        }
9765
9766        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9767                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9768            app.persistent = true;
9769            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9770        }
9771        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9772            mPersistentStartingProcesses.add(app);
9773            startProcessLocked(app, "added application", app.processName, abiOverride,
9774                    null /* entryPoint */, null /* entryPointArgs */);
9775        }
9776
9777        return app;
9778    }
9779
9780    public void unhandledBack() {
9781        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9782                "unhandledBack()");
9783
9784        synchronized(this) {
9785            final long origId = Binder.clearCallingIdentity();
9786            try {
9787                getFocusedStack().unhandledBackLocked();
9788            } finally {
9789                Binder.restoreCallingIdentity(origId);
9790            }
9791        }
9792    }
9793
9794    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9795        enforceNotIsolatedCaller("openContentUri");
9796        final int userId = UserHandle.getCallingUserId();
9797        String name = uri.getAuthority();
9798        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9799        ParcelFileDescriptor pfd = null;
9800        if (cph != null) {
9801            // We record the binder invoker's uid in thread-local storage before
9802            // going to the content provider to open the file.  Later, in the code
9803            // that handles all permissions checks, we look for this uid and use
9804            // that rather than the Activity Manager's own uid.  The effect is that
9805            // we do the check against the caller's permissions even though it looks
9806            // to the content provider like the Activity Manager itself is making
9807            // the request.
9808            sCallerIdentity.set(new Identity(
9809                    Binder.getCallingPid(), Binder.getCallingUid()));
9810            try {
9811                pfd = cph.provider.openFile(null, uri, "r", null);
9812            } catch (FileNotFoundException e) {
9813                // do nothing; pfd will be returned null
9814            } finally {
9815                // Ensure that whatever happens, we clean up the identity state
9816                sCallerIdentity.remove();
9817            }
9818
9819            // We've got the fd now, so we're done with the provider.
9820            removeContentProviderExternalUnchecked(name, null, userId);
9821        } else {
9822            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9823        }
9824        return pfd;
9825    }
9826
9827    // Actually is sleeping or shutting down or whatever else in the future
9828    // is an inactive state.
9829    public boolean isSleepingOrShuttingDown() {
9830        return mSleeping || mShuttingDown;
9831    }
9832
9833    public boolean isSleeping() {
9834        return mSleeping;
9835    }
9836
9837    void goingToSleep() {
9838        synchronized(this) {
9839            mWentToSleep = true;
9840            updateEventDispatchingLocked();
9841            goToSleepIfNeededLocked();
9842        }
9843    }
9844
9845    void finishRunningVoiceLocked() {
9846        if (mRunningVoice) {
9847            mRunningVoice = false;
9848            goToSleepIfNeededLocked();
9849        }
9850    }
9851
9852    void goToSleepIfNeededLocked() {
9853        if (mWentToSleep && !mRunningVoice) {
9854            if (!mSleeping) {
9855                mSleeping = true;
9856                mStackSupervisor.goingToSleepLocked();
9857
9858                // Initialize the wake times of all processes.
9859                checkExcessivePowerUsageLocked(false);
9860                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9861                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9862                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9863            }
9864        }
9865    }
9866
9867    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9868        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9869            // Never persist the home stack.
9870            return;
9871        }
9872        mTaskPersister.wakeup(task, flush);
9873    }
9874
9875    @Override
9876    public boolean shutdown(int timeout) {
9877        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9878                != PackageManager.PERMISSION_GRANTED) {
9879            throw new SecurityException("Requires permission "
9880                    + android.Manifest.permission.SHUTDOWN);
9881        }
9882
9883        boolean timedout = false;
9884
9885        synchronized(this) {
9886            mShuttingDown = true;
9887            updateEventDispatchingLocked();
9888            timedout = mStackSupervisor.shutdownLocked(timeout);
9889        }
9890
9891        mAppOpsService.shutdown();
9892        if (mUsageStatsService != null) {
9893            mUsageStatsService.prepareShutdown();
9894        }
9895        mBatteryStatsService.shutdown();
9896        synchronized (this) {
9897            mProcessStats.shutdownLocked();
9898        }
9899        notifyTaskPersisterLocked(null, true);
9900
9901        return timedout;
9902    }
9903
9904    public final void activitySlept(IBinder token) {
9905        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9906
9907        final long origId = Binder.clearCallingIdentity();
9908
9909        synchronized (this) {
9910            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9911            if (r != null) {
9912                mStackSupervisor.activitySleptLocked(r);
9913            }
9914        }
9915
9916        Binder.restoreCallingIdentity(origId);
9917    }
9918
9919    void logLockScreen(String msg) {
9920        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9921                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9922                mWentToSleep + " mSleeping=" + mSleeping);
9923    }
9924
9925    private void comeOutOfSleepIfNeededLocked() {
9926        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9927            if (mSleeping) {
9928                mSleeping = false;
9929                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9930            }
9931        }
9932    }
9933
9934    void wakingUp() {
9935        synchronized(this) {
9936            mWentToSleep = false;
9937            updateEventDispatchingLocked();
9938            comeOutOfSleepIfNeededLocked();
9939        }
9940    }
9941
9942    void startRunningVoiceLocked() {
9943        if (!mRunningVoice) {
9944            mRunningVoice = true;
9945            comeOutOfSleepIfNeededLocked();
9946        }
9947    }
9948
9949    private void updateEventDispatchingLocked() {
9950        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9951    }
9952
9953    public void setLockScreenShown(boolean shown) {
9954        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9955                != PackageManager.PERMISSION_GRANTED) {
9956            throw new SecurityException("Requires permission "
9957                    + android.Manifest.permission.DEVICE_POWER);
9958        }
9959
9960        synchronized(this) {
9961            long ident = Binder.clearCallingIdentity();
9962            try {
9963                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9964                mLockScreenShown = shown;
9965                comeOutOfSleepIfNeededLocked();
9966            } finally {
9967                Binder.restoreCallingIdentity(ident);
9968            }
9969        }
9970    }
9971
9972    @Override
9973    public void stopAppSwitches() {
9974        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9975                != PackageManager.PERMISSION_GRANTED) {
9976            throw new SecurityException("Requires permission "
9977                    + android.Manifest.permission.STOP_APP_SWITCHES);
9978        }
9979
9980        synchronized(this) {
9981            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9982                    + APP_SWITCH_DELAY_TIME;
9983            mDidAppSwitch = false;
9984            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9985            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9986            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9987        }
9988    }
9989
9990    public void resumeAppSwitches() {
9991        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9992                != PackageManager.PERMISSION_GRANTED) {
9993            throw new SecurityException("Requires permission "
9994                    + android.Manifest.permission.STOP_APP_SWITCHES);
9995        }
9996
9997        synchronized(this) {
9998            // Note that we don't execute any pending app switches... we will
9999            // let those wait until either the timeout, or the next start
10000            // activity request.
10001            mAppSwitchesAllowedTime = 0;
10002        }
10003    }
10004
10005    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10006            String name) {
10007        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10008            return true;
10009        }
10010
10011        final int perm = checkComponentPermission(
10012                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10013                callingUid, -1, true);
10014        if (perm == PackageManager.PERMISSION_GRANTED) {
10015            return true;
10016        }
10017
10018        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10019        return false;
10020    }
10021
10022    public void setDebugApp(String packageName, boolean waitForDebugger,
10023            boolean persistent) {
10024        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10025                "setDebugApp()");
10026
10027        long ident = Binder.clearCallingIdentity();
10028        try {
10029            // Note that this is not really thread safe if there are multiple
10030            // callers into it at the same time, but that's not a situation we
10031            // care about.
10032            if (persistent) {
10033                final ContentResolver resolver = mContext.getContentResolver();
10034                Settings.Global.putString(
10035                    resolver, Settings.Global.DEBUG_APP,
10036                    packageName);
10037                Settings.Global.putInt(
10038                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10039                    waitForDebugger ? 1 : 0);
10040            }
10041
10042            synchronized (this) {
10043                if (!persistent) {
10044                    mOrigDebugApp = mDebugApp;
10045                    mOrigWaitForDebugger = mWaitForDebugger;
10046                }
10047                mDebugApp = packageName;
10048                mWaitForDebugger = waitForDebugger;
10049                mDebugTransient = !persistent;
10050                if (packageName != null) {
10051                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10052                            false, UserHandle.USER_ALL, "set debug app");
10053                }
10054            }
10055        } finally {
10056            Binder.restoreCallingIdentity(ident);
10057        }
10058    }
10059
10060    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10061        synchronized (this) {
10062            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10063            if (!isDebuggable) {
10064                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10065                    throw new SecurityException("Process not debuggable: " + app.packageName);
10066                }
10067            }
10068
10069            mOpenGlTraceApp = processName;
10070        }
10071    }
10072
10073    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10074        synchronized (this) {
10075            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10076            if (!isDebuggable) {
10077                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10078                    throw new SecurityException("Process not debuggable: " + app.packageName);
10079                }
10080            }
10081            mProfileApp = processName;
10082            mProfileFile = profilerInfo.profileFile;
10083            if (mProfileFd != null) {
10084                try {
10085                    mProfileFd.close();
10086                } catch (IOException e) {
10087                }
10088                mProfileFd = null;
10089            }
10090            mProfileFd = profilerInfo.profileFd;
10091            mSamplingInterval = profilerInfo.samplingInterval;
10092            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10093            mProfileType = 0;
10094        }
10095    }
10096
10097    @Override
10098    public void setAlwaysFinish(boolean enabled) {
10099        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10100                "setAlwaysFinish()");
10101
10102        Settings.Global.putInt(
10103                mContext.getContentResolver(),
10104                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10105
10106        synchronized (this) {
10107            mAlwaysFinishActivities = enabled;
10108        }
10109    }
10110
10111    @Override
10112    public void setActivityController(IActivityController controller) {
10113        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10114                "setActivityController()");
10115        synchronized (this) {
10116            mController = controller;
10117            Watchdog.getInstance().setActivityController(controller);
10118        }
10119    }
10120
10121    @Override
10122    public void setUserIsMonkey(boolean userIsMonkey) {
10123        synchronized (this) {
10124            synchronized (mPidsSelfLocked) {
10125                final int callingPid = Binder.getCallingPid();
10126                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10127                if (precessRecord == null) {
10128                    throw new SecurityException("Unknown process: " + callingPid);
10129                }
10130                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10131                    throw new SecurityException("Only an instrumentation process "
10132                            + "with a UiAutomation can call setUserIsMonkey");
10133                }
10134            }
10135            mUserIsMonkey = userIsMonkey;
10136        }
10137    }
10138
10139    @Override
10140    public boolean isUserAMonkey() {
10141        synchronized (this) {
10142            // If there is a controller also implies the user is a monkey.
10143            return (mUserIsMonkey || mController != null);
10144        }
10145    }
10146
10147    public void requestBugReport() {
10148        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10149        SystemProperties.set("ctl.start", "bugreport");
10150    }
10151
10152    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10153        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10154    }
10155
10156    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10157        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10158            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10159        }
10160        return KEY_DISPATCHING_TIMEOUT;
10161    }
10162
10163    @Override
10164    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10165        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10166                != PackageManager.PERMISSION_GRANTED) {
10167            throw new SecurityException("Requires permission "
10168                    + android.Manifest.permission.FILTER_EVENTS);
10169        }
10170        ProcessRecord proc;
10171        long timeout;
10172        synchronized (this) {
10173            synchronized (mPidsSelfLocked) {
10174                proc = mPidsSelfLocked.get(pid);
10175            }
10176            timeout = getInputDispatchingTimeoutLocked(proc);
10177        }
10178
10179        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10180            return -1;
10181        }
10182
10183        return timeout;
10184    }
10185
10186    /**
10187     * Handle input dispatching timeouts.
10188     * Returns whether input dispatching should be aborted or not.
10189     */
10190    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10191            final ActivityRecord activity, final ActivityRecord parent,
10192            final boolean aboveSystem, String reason) {
10193        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10194                != PackageManager.PERMISSION_GRANTED) {
10195            throw new SecurityException("Requires permission "
10196                    + android.Manifest.permission.FILTER_EVENTS);
10197        }
10198
10199        final String annotation;
10200        if (reason == null) {
10201            annotation = "Input dispatching timed out";
10202        } else {
10203            annotation = "Input dispatching timed out (" + reason + ")";
10204        }
10205
10206        if (proc != null) {
10207            synchronized (this) {
10208                if (proc.debugging) {
10209                    return false;
10210                }
10211
10212                if (mDidDexOpt) {
10213                    // Give more time since we were dexopting.
10214                    mDidDexOpt = false;
10215                    return false;
10216                }
10217
10218                if (proc.instrumentationClass != null) {
10219                    Bundle info = new Bundle();
10220                    info.putString("shortMsg", "keyDispatchingTimedOut");
10221                    info.putString("longMsg", annotation);
10222                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10223                    return true;
10224                }
10225            }
10226            mHandler.post(new Runnable() {
10227                @Override
10228                public void run() {
10229                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10230                }
10231            });
10232        }
10233
10234        return true;
10235    }
10236
10237    public Bundle getAssistContextExtras(int requestType) {
10238        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10239                "getAssistContextExtras()");
10240        PendingAssistExtras pae;
10241        Bundle extras = new Bundle();
10242        synchronized (this) {
10243            ActivityRecord activity = getFocusedStack().mResumedActivity;
10244            if (activity == null) {
10245                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10246                return null;
10247            }
10248            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10249            if (activity.app == null || activity.app.thread == null) {
10250                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10251                return extras;
10252            }
10253            if (activity.app.pid == Binder.getCallingPid()) {
10254                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10255                return extras;
10256            }
10257            pae = new PendingAssistExtras(activity);
10258            try {
10259                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10260                        requestType);
10261                mPendingAssistExtras.add(pae);
10262                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10263            } catch (RemoteException e) {
10264                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10265                return extras;
10266            }
10267        }
10268        synchronized (pae) {
10269            while (!pae.haveResult) {
10270                try {
10271                    pae.wait();
10272                } catch (InterruptedException e) {
10273                }
10274            }
10275            if (pae.result != null) {
10276                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10277            }
10278        }
10279        synchronized (this) {
10280            mPendingAssistExtras.remove(pae);
10281            mHandler.removeCallbacks(pae);
10282        }
10283        return extras;
10284    }
10285
10286    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10287        PendingAssistExtras pae = (PendingAssistExtras)token;
10288        synchronized (pae) {
10289            pae.result = extras;
10290            pae.haveResult = true;
10291            pae.notifyAll();
10292        }
10293    }
10294
10295    public void registerProcessObserver(IProcessObserver observer) {
10296        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10297                "registerProcessObserver()");
10298        synchronized (this) {
10299            mProcessObservers.register(observer);
10300        }
10301    }
10302
10303    @Override
10304    public void unregisterProcessObserver(IProcessObserver observer) {
10305        synchronized (this) {
10306            mProcessObservers.unregister(observer);
10307        }
10308    }
10309
10310    @Override
10311    public boolean convertFromTranslucent(IBinder token) {
10312        final long origId = Binder.clearCallingIdentity();
10313        try {
10314            synchronized (this) {
10315                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10316                if (r == null) {
10317                    return false;
10318                }
10319                final boolean translucentChanged = r.changeWindowTranslucency(true);
10320                if (translucentChanged) {
10321                    r.task.stack.releaseBackgroundResources();
10322                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10323                }
10324                mWindowManager.setAppFullscreen(token, true);
10325                return translucentChanged;
10326            }
10327        } finally {
10328            Binder.restoreCallingIdentity(origId);
10329        }
10330    }
10331
10332    @Override
10333    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10334        final long origId = Binder.clearCallingIdentity();
10335        try {
10336            synchronized (this) {
10337                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10338                if (r == null) {
10339                    return false;
10340                }
10341                int index = r.task.mActivities.lastIndexOf(r);
10342                if (index > 0) {
10343                    ActivityRecord under = r.task.mActivities.get(index - 1);
10344                    under.returningOptions = options;
10345                }
10346                final boolean translucentChanged = r.changeWindowTranslucency(false);
10347                if (translucentChanged) {
10348                    r.task.stack.convertToTranslucent(r);
10349                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10350                }
10351                mWindowManager.setAppFullscreen(token, false);
10352                return translucentChanged;
10353            }
10354        } finally {
10355            Binder.restoreCallingIdentity(origId);
10356        }
10357    }
10358
10359    @Override
10360    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10361        final long origId = Binder.clearCallingIdentity();
10362        try {
10363            synchronized (this) {
10364                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10365                if (r != null) {
10366                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10367                }
10368            }
10369            return false;
10370        } finally {
10371            Binder.restoreCallingIdentity(origId);
10372        }
10373    }
10374
10375    @Override
10376    public boolean isBackgroundVisibleBehind(IBinder token) {
10377        final long origId = Binder.clearCallingIdentity();
10378        try {
10379            synchronized (this) {
10380                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10381                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10382                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10383                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10384                return visible;
10385            }
10386        } finally {
10387            Binder.restoreCallingIdentity(origId);
10388        }
10389    }
10390
10391    @Override
10392    public ActivityOptions getActivityOptions(IBinder token) {
10393        final long origId = Binder.clearCallingIdentity();
10394        try {
10395            synchronized (this) {
10396                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10397                if (r != null) {
10398                    final ActivityOptions activityOptions = r.pendingOptions;
10399                    r.pendingOptions = null;
10400                    return activityOptions;
10401                }
10402                return null;
10403            }
10404        } finally {
10405            Binder.restoreCallingIdentity(origId);
10406        }
10407    }
10408
10409    @Override
10410    public void setImmersive(IBinder token, boolean immersive) {
10411        synchronized(this) {
10412            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10413            if (r == null) {
10414                throw new IllegalArgumentException();
10415            }
10416            r.immersive = immersive;
10417
10418            // update associated state if we're frontmost
10419            if (r == mFocusedActivity) {
10420                if (DEBUG_IMMERSIVE) {
10421                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10422                }
10423                applyUpdateLockStateLocked(r);
10424            }
10425        }
10426    }
10427
10428    @Override
10429    public boolean isImmersive(IBinder token) {
10430        synchronized (this) {
10431            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10432            if (r == null) {
10433                throw new IllegalArgumentException();
10434            }
10435            return r.immersive;
10436        }
10437    }
10438
10439    public boolean isTopActivityImmersive() {
10440        enforceNotIsolatedCaller("startActivity");
10441        synchronized (this) {
10442            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10443            return (r != null) ? r.immersive : false;
10444        }
10445    }
10446
10447    @Override
10448    public boolean isTopOfTask(IBinder token) {
10449        synchronized (this) {
10450            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10451            if (r == null) {
10452                throw new IllegalArgumentException();
10453            }
10454            return r.task.getTopActivity() == r;
10455        }
10456    }
10457
10458    public final void enterSafeMode() {
10459        synchronized(this) {
10460            // It only makes sense to do this before the system is ready
10461            // and started launching other packages.
10462            if (!mSystemReady) {
10463                try {
10464                    AppGlobals.getPackageManager().enterSafeMode();
10465                } catch (RemoteException e) {
10466                }
10467            }
10468
10469            mSafeMode = true;
10470        }
10471    }
10472
10473    public final void showSafeModeOverlay() {
10474        View v = LayoutInflater.from(mContext).inflate(
10475                com.android.internal.R.layout.safe_mode, null);
10476        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10477        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10478        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10479        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10480        lp.gravity = Gravity.BOTTOM | Gravity.START;
10481        lp.format = v.getBackground().getOpacity();
10482        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10483                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10484        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10485        ((WindowManager)mContext.getSystemService(
10486                Context.WINDOW_SERVICE)).addView(v, lp);
10487    }
10488
10489    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10490        if (!(sender instanceof PendingIntentRecord)) {
10491            return;
10492        }
10493        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10494        synchronized (stats) {
10495            if (mBatteryStatsService.isOnBattery()) {
10496                mBatteryStatsService.enforceCallingPermission();
10497                PendingIntentRecord rec = (PendingIntentRecord)sender;
10498                int MY_UID = Binder.getCallingUid();
10499                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10500                BatteryStatsImpl.Uid.Pkg pkg =
10501                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10502                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10503                pkg.incWakeupsLocked();
10504            }
10505        }
10506    }
10507
10508    public boolean killPids(int[] pids, String pReason, boolean secure) {
10509        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10510            throw new SecurityException("killPids only available to the system");
10511        }
10512        String reason = (pReason == null) ? "Unknown" : pReason;
10513        // XXX Note: don't acquire main activity lock here, because the window
10514        // manager calls in with its locks held.
10515
10516        boolean killed = false;
10517        synchronized (mPidsSelfLocked) {
10518            int[] types = new int[pids.length];
10519            int worstType = 0;
10520            for (int i=0; i<pids.length; i++) {
10521                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10522                if (proc != null) {
10523                    int type = proc.setAdj;
10524                    types[i] = type;
10525                    if (type > worstType) {
10526                        worstType = type;
10527                    }
10528                }
10529            }
10530
10531            // If the worst oom_adj is somewhere in the cached proc LRU range,
10532            // then constrain it so we will kill all cached procs.
10533            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10534                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10535                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10536            }
10537
10538            // If this is not a secure call, don't let it kill processes that
10539            // are important.
10540            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10541                worstType = ProcessList.SERVICE_ADJ;
10542            }
10543
10544            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10545            for (int i=0; i<pids.length; i++) {
10546                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10547                if (proc == null) {
10548                    continue;
10549                }
10550                int adj = proc.setAdj;
10551                if (adj >= worstType && !proc.killedByAm) {
10552                    proc.kill(reason, true);
10553                    killed = true;
10554                }
10555            }
10556        }
10557        return killed;
10558    }
10559
10560    @Override
10561    public void killUid(int uid, String reason) {
10562        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10563            throw new SecurityException("killUid only available to the system");
10564        }
10565        synchronized (this) {
10566            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10567                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10568                    reason != null ? reason : "kill uid");
10569        }
10570    }
10571
10572    @Override
10573    public boolean killProcessesBelowForeground(String reason) {
10574        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10575            throw new SecurityException("killProcessesBelowForeground() only available to system");
10576        }
10577
10578        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10579    }
10580
10581    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10582        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10583            throw new SecurityException("killProcessesBelowAdj() only available to system");
10584        }
10585
10586        boolean killed = false;
10587        synchronized (mPidsSelfLocked) {
10588            final int size = mPidsSelfLocked.size();
10589            for (int i = 0; i < size; i++) {
10590                final int pid = mPidsSelfLocked.keyAt(i);
10591                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10592                if (proc == null) continue;
10593
10594                final int adj = proc.setAdj;
10595                if (adj > belowAdj && !proc.killedByAm) {
10596                    proc.kill(reason, true);
10597                    killed = true;
10598                }
10599            }
10600        }
10601        return killed;
10602    }
10603
10604    @Override
10605    public void hang(final IBinder who, boolean allowRestart) {
10606        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10607                != PackageManager.PERMISSION_GRANTED) {
10608            throw new SecurityException("Requires permission "
10609                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10610        }
10611
10612        final IBinder.DeathRecipient death = new DeathRecipient() {
10613            @Override
10614            public void binderDied() {
10615                synchronized (this) {
10616                    notifyAll();
10617                }
10618            }
10619        };
10620
10621        try {
10622            who.linkToDeath(death, 0);
10623        } catch (RemoteException e) {
10624            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10625            return;
10626        }
10627
10628        synchronized (this) {
10629            Watchdog.getInstance().setAllowRestart(allowRestart);
10630            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10631            synchronized (death) {
10632                while (who.isBinderAlive()) {
10633                    try {
10634                        death.wait();
10635                    } catch (InterruptedException e) {
10636                    }
10637                }
10638            }
10639            Watchdog.getInstance().setAllowRestart(true);
10640        }
10641    }
10642
10643    @Override
10644    public void restart() {
10645        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10646                != PackageManager.PERMISSION_GRANTED) {
10647            throw new SecurityException("Requires permission "
10648                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10649        }
10650
10651        Log.i(TAG, "Sending shutdown broadcast...");
10652
10653        BroadcastReceiver br = new BroadcastReceiver() {
10654            @Override public void onReceive(Context context, Intent intent) {
10655                // Now the broadcast is done, finish up the low-level shutdown.
10656                Log.i(TAG, "Shutting down activity manager...");
10657                shutdown(10000);
10658                Log.i(TAG, "Shutdown complete, restarting!");
10659                Process.killProcess(Process.myPid());
10660                System.exit(10);
10661            }
10662        };
10663
10664        // First send the high-level shut down broadcast.
10665        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10666        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10667        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10668        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10669        mContext.sendOrderedBroadcastAsUser(intent,
10670                UserHandle.ALL, null, br, mHandler, 0, null, null);
10671        */
10672        br.onReceive(mContext, intent);
10673    }
10674
10675    private long getLowRamTimeSinceIdle(long now) {
10676        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10677    }
10678
10679    @Override
10680    public void performIdleMaintenance() {
10681        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10682                != PackageManager.PERMISSION_GRANTED) {
10683            throw new SecurityException("Requires permission "
10684                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10685        }
10686
10687        synchronized (this) {
10688            final long now = SystemClock.uptimeMillis();
10689            final long timeSinceLastIdle = now - mLastIdleTime;
10690            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10691            mLastIdleTime = now;
10692            mLowRamTimeSinceLastIdle = 0;
10693            if (mLowRamStartTime != 0) {
10694                mLowRamStartTime = now;
10695            }
10696
10697            StringBuilder sb = new StringBuilder(128);
10698            sb.append("Idle maintenance over ");
10699            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10700            sb.append(" low RAM for ");
10701            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10702            Slog.i(TAG, sb.toString());
10703
10704            // If at least 1/3 of our time since the last idle period has been spent
10705            // with RAM low, then we want to kill processes.
10706            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10707
10708            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10709                ProcessRecord proc = mLruProcesses.get(i);
10710                if (proc.notCachedSinceIdle) {
10711                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10712                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10713                        if (doKilling && proc.initialIdlePss != 0
10714                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10715                            proc.kill("idle maint (pss " + proc.lastPss
10716                                    + " from " + proc.initialIdlePss + ")", true);
10717                        }
10718                    }
10719                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10720                    proc.notCachedSinceIdle = true;
10721                    proc.initialIdlePss = 0;
10722                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10723                            isSleeping(), now);
10724                }
10725            }
10726
10727            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10728            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10729        }
10730    }
10731
10732    private void retrieveSettings() {
10733        final ContentResolver resolver = mContext.getContentResolver();
10734        String debugApp = Settings.Global.getString(
10735            resolver, Settings.Global.DEBUG_APP);
10736        boolean waitForDebugger = Settings.Global.getInt(
10737            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10738        boolean alwaysFinishActivities = Settings.Global.getInt(
10739            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10740        boolean forceRtl = Settings.Global.getInt(
10741                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10742        // Transfer any global setting for forcing RTL layout, into a System Property
10743        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10744
10745        Configuration configuration = new Configuration();
10746        Settings.System.getConfiguration(resolver, configuration);
10747        if (forceRtl) {
10748            // This will take care of setting the correct layout direction flags
10749            configuration.setLayoutDirection(configuration.locale);
10750        }
10751
10752        synchronized (this) {
10753            mDebugApp = mOrigDebugApp = debugApp;
10754            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10755            mAlwaysFinishActivities = alwaysFinishActivities;
10756            // This happens before any activities are started, so we can
10757            // change mConfiguration in-place.
10758            updateConfigurationLocked(configuration, null, false, true);
10759            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10760        }
10761    }
10762
10763    /** Loads resources after the current configuration has been set. */
10764    private void loadResourcesOnSystemReady() {
10765        final Resources res = mContext.getResources();
10766        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10767        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10768        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10769    }
10770
10771    public boolean testIsSystemReady() {
10772        // no need to synchronize(this) just to read & return the value
10773        return mSystemReady;
10774    }
10775
10776    private static File getCalledPreBootReceiversFile() {
10777        File dataDir = Environment.getDataDirectory();
10778        File systemDir = new File(dataDir, "system");
10779        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10780        return fname;
10781    }
10782
10783    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10784        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10785        File file = getCalledPreBootReceiversFile();
10786        FileInputStream fis = null;
10787        try {
10788            fis = new FileInputStream(file);
10789            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10790            int fvers = dis.readInt();
10791            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10792                String vers = dis.readUTF();
10793                String codename = dis.readUTF();
10794                String build = dis.readUTF();
10795                if (android.os.Build.VERSION.RELEASE.equals(vers)
10796                        && android.os.Build.VERSION.CODENAME.equals(codename)
10797                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10798                    int num = dis.readInt();
10799                    while (num > 0) {
10800                        num--;
10801                        String pkg = dis.readUTF();
10802                        String cls = dis.readUTF();
10803                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10804                    }
10805                }
10806            }
10807        } catch (FileNotFoundException e) {
10808        } catch (IOException e) {
10809            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10810        } finally {
10811            if (fis != null) {
10812                try {
10813                    fis.close();
10814                } catch (IOException e) {
10815                }
10816            }
10817        }
10818        return lastDoneReceivers;
10819    }
10820
10821    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10822        File file = getCalledPreBootReceiversFile();
10823        FileOutputStream fos = null;
10824        DataOutputStream dos = null;
10825        try {
10826            fos = new FileOutputStream(file);
10827            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10828            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10829            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10830            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10831            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10832            dos.writeInt(list.size());
10833            for (int i=0; i<list.size(); i++) {
10834                dos.writeUTF(list.get(i).getPackageName());
10835                dos.writeUTF(list.get(i).getClassName());
10836            }
10837        } catch (IOException e) {
10838            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10839            file.delete();
10840        } finally {
10841            FileUtils.sync(fos);
10842            if (dos != null) {
10843                try {
10844                    dos.close();
10845                } catch (IOException e) {
10846                    // TODO Auto-generated catch block
10847                    e.printStackTrace();
10848                }
10849            }
10850        }
10851    }
10852
10853    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10854            ArrayList<ComponentName> doneReceivers, int userId) {
10855        boolean waitingUpdate = false;
10856        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10857        List<ResolveInfo> ris = null;
10858        try {
10859            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10860                    intent, null, 0, userId);
10861        } catch (RemoteException e) {
10862        }
10863        if (ris != null) {
10864            for (int i=ris.size()-1; i>=0; i--) {
10865                if ((ris.get(i).activityInfo.applicationInfo.flags
10866                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10867                    ris.remove(i);
10868                }
10869            }
10870            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10871
10872            // For User 0, load the version number. When delivering to a new user, deliver
10873            // to all receivers.
10874            if (userId == UserHandle.USER_OWNER) {
10875                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10876                for (int i=0; i<ris.size(); i++) {
10877                    ActivityInfo ai = ris.get(i).activityInfo;
10878                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10879                    if (lastDoneReceivers.contains(comp)) {
10880                        // We already did the pre boot receiver for this app with the current
10881                        // platform version, so don't do it again...
10882                        ris.remove(i);
10883                        i--;
10884                        // ...however, do keep it as one that has been done, so we don't
10885                        // forget about it when rewriting the file of last done receivers.
10886                        doneReceivers.add(comp);
10887                    }
10888                }
10889            }
10890
10891            // If primary user, send broadcast to all available users, else just to userId
10892            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10893                    : new int[] { userId };
10894            for (int i = 0; i < ris.size(); i++) {
10895                ActivityInfo ai = ris.get(i).activityInfo;
10896                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10897                doneReceivers.add(comp);
10898                intent.setComponent(comp);
10899                for (int j=0; j<users.length; j++) {
10900                    IIntentReceiver finisher = null;
10901                    // On last receiver and user, set up a completion callback
10902                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10903                        finisher = new IIntentReceiver.Stub() {
10904                            public void performReceive(Intent intent, int resultCode,
10905                                    String data, Bundle extras, boolean ordered,
10906                                    boolean sticky, int sendingUser) {
10907                                // The raw IIntentReceiver interface is called
10908                                // with the AM lock held, so redispatch to
10909                                // execute our code without the lock.
10910                                mHandler.post(onFinishCallback);
10911                            }
10912                        };
10913                    }
10914                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10915                            + " for user " + users[j]);
10916                    broadcastIntentLocked(null, null, intent, null, finisher,
10917                            0, null, null, null, AppOpsManager.OP_NONE,
10918                            true, false, MY_PID, Process.SYSTEM_UID,
10919                            users[j]);
10920                    if (finisher != null) {
10921                        waitingUpdate = true;
10922                    }
10923                }
10924            }
10925        }
10926
10927        return waitingUpdate;
10928    }
10929
10930    public void systemReady(final Runnable goingCallback) {
10931        synchronized(this) {
10932            if (mSystemReady) {
10933                // If we're done calling all the receivers, run the next "boot phase" passed in
10934                // by the SystemServer
10935                if (goingCallback != null) {
10936                    goingCallback.run();
10937                }
10938                return;
10939            }
10940
10941            // Make sure we have the current profile info, since it is needed for
10942            // security checks.
10943            updateCurrentProfileIdsLocked();
10944
10945            if (mRecentTasks == null) {
10946                mRecentTasks = mTaskPersister.restoreTasksLocked();
10947                if (!mRecentTasks.isEmpty()) {
10948                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10949                }
10950                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10951                mTaskPersister.startPersisting();
10952            }
10953
10954            // Check to see if there are any update receivers to run.
10955            if (!mDidUpdate) {
10956                if (mWaitingUpdate) {
10957                    return;
10958                }
10959                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10960                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10961                    public void run() {
10962                        synchronized (ActivityManagerService.this) {
10963                            mDidUpdate = true;
10964                        }
10965                        writeLastDonePreBootReceivers(doneReceivers);
10966                        showBootMessage(mContext.getText(
10967                                R.string.android_upgrading_complete),
10968                                false);
10969                        systemReady(goingCallback);
10970                    }
10971                }, doneReceivers, UserHandle.USER_OWNER);
10972
10973                if (mWaitingUpdate) {
10974                    return;
10975                }
10976                mDidUpdate = true;
10977            }
10978
10979            mAppOpsService.systemReady();
10980            mSystemReady = true;
10981        }
10982
10983        ArrayList<ProcessRecord> procsToKill = null;
10984        synchronized(mPidsSelfLocked) {
10985            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10986                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10987                if (!isAllowedWhileBooting(proc.info)){
10988                    if (procsToKill == null) {
10989                        procsToKill = new ArrayList<ProcessRecord>();
10990                    }
10991                    procsToKill.add(proc);
10992                }
10993            }
10994        }
10995
10996        synchronized(this) {
10997            if (procsToKill != null) {
10998                for (int i=procsToKill.size()-1; i>=0; i--) {
10999                    ProcessRecord proc = procsToKill.get(i);
11000                    Slog.i(TAG, "Removing system update proc: " + proc);
11001                    removeProcessLocked(proc, true, false, "system update done");
11002                }
11003            }
11004
11005            // Now that we have cleaned up any update processes, we
11006            // are ready to start launching real processes and know that
11007            // we won't trample on them any more.
11008            mProcessesReady = true;
11009        }
11010
11011        Slog.i(TAG, "System now ready");
11012        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11013            SystemClock.uptimeMillis());
11014
11015        synchronized(this) {
11016            // Make sure we have no pre-ready processes sitting around.
11017
11018            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11019                ResolveInfo ri = mContext.getPackageManager()
11020                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11021                                STOCK_PM_FLAGS);
11022                CharSequence errorMsg = null;
11023                if (ri != null) {
11024                    ActivityInfo ai = ri.activityInfo;
11025                    ApplicationInfo app = ai.applicationInfo;
11026                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11027                        mTopAction = Intent.ACTION_FACTORY_TEST;
11028                        mTopData = null;
11029                        mTopComponent = new ComponentName(app.packageName,
11030                                ai.name);
11031                    } else {
11032                        errorMsg = mContext.getResources().getText(
11033                                com.android.internal.R.string.factorytest_not_system);
11034                    }
11035                } else {
11036                    errorMsg = mContext.getResources().getText(
11037                            com.android.internal.R.string.factorytest_no_action);
11038                }
11039                if (errorMsg != null) {
11040                    mTopAction = null;
11041                    mTopData = null;
11042                    mTopComponent = null;
11043                    Message msg = Message.obtain();
11044                    msg.what = SHOW_FACTORY_ERROR_MSG;
11045                    msg.getData().putCharSequence("msg", errorMsg);
11046                    mHandler.sendMessage(msg);
11047                }
11048            }
11049        }
11050
11051        retrieveSettings();
11052        loadResourcesOnSystemReady();
11053
11054        synchronized (this) {
11055            readGrantedUriPermissionsLocked();
11056        }
11057
11058        if (goingCallback != null) goingCallback.run();
11059
11060        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11061                Integer.toString(mCurrentUserId), mCurrentUserId);
11062        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11063                Integer.toString(mCurrentUserId), mCurrentUserId);
11064        mSystemServiceManager.startUser(mCurrentUserId);
11065
11066        synchronized (this) {
11067            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11068                try {
11069                    List apps = AppGlobals.getPackageManager().
11070                        getPersistentApplications(STOCK_PM_FLAGS);
11071                    if (apps != null) {
11072                        int N = apps.size();
11073                        int i;
11074                        for (i=0; i<N; i++) {
11075                            ApplicationInfo info
11076                                = (ApplicationInfo)apps.get(i);
11077                            if (info != null &&
11078                                    !info.packageName.equals("android")) {
11079                                addAppLocked(info, false, null /* ABI override */);
11080                            }
11081                        }
11082                    }
11083                } catch (RemoteException ex) {
11084                    // pm is in same process, this will never happen.
11085                }
11086            }
11087
11088            // Start up initial activity.
11089            mBooting = true;
11090
11091            try {
11092                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11093                    Message msg = Message.obtain();
11094                    msg.what = SHOW_UID_ERROR_MSG;
11095                    mHandler.sendMessage(msg);
11096                }
11097            } catch (RemoteException e) {
11098            }
11099
11100            long ident = Binder.clearCallingIdentity();
11101            try {
11102                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11103                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11104                        | Intent.FLAG_RECEIVER_FOREGROUND);
11105                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11106                broadcastIntentLocked(null, null, intent,
11107                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11108                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11109                intent = new Intent(Intent.ACTION_USER_STARTING);
11110                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11111                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11112                broadcastIntentLocked(null, null, intent,
11113                        null, new IIntentReceiver.Stub() {
11114                            @Override
11115                            public void performReceive(Intent intent, int resultCode, String data,
11116                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11117                                    throws RemoteException {
11118                            }
11119                        }, 0, null, null,
11120                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11121                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11122            } catch (Throwable t) {
11123                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11124            } finally {
11125                Binder.restoreCallingIdentity(ident);
11126            }
11127            mStackSupervisor.resumeTopActivitiesLocked();
11128            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11129        }
11130    }
11131
11132    private boolean makeAppCrashingLocked(ProcessRecord app,
11133            String shortMsg, String longMsg, String stackTrace) {
11134        app.crashing = true;
11135        app.crashingReport = generateProcessError(app,
11136                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11137        startAppProblemLocked(app);
11138        app.stopFreezingAllLocked();
11139        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11140    }
11141
11142    private void makeAppNotRespondingLocked(ProcessRecord app,
11143            String activity, String shortMsg, String longMsg) {
11144        app.notResponding = true;
11145        app.notRespondingReport = generateProcessError(app,
11146                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11147                activity, shortMsg, longMsg, null);
11148        startAppProblemLocked(app);
11149        app.stopFreezingAllLocked();
11150    }
11151
11152    /**
11153     * Generate a process error record, suitable for attachment to a ProcessRecord.
11154     *
11155     * @param app The ProcessRecord in which the error occurred.
11156     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11157     *                      ActivityManager.AppErrorStateInfo
11158     * @param activity The activity associated with the crash, if known.
11159     * @param shortMsg Short message describing the crash.
11160     * @param longMsg Long message describing the crash.
11161     * @param stackTrace Full crash stack trace, may be null.
11162     *
11163     * @return Returns a fully-formed AppErrorStateInfo record.
11164     */
11165    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11166            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11167        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11168
11169        report.condition = condition;
11170        report.processName = app.processName;
11171        report.pid = app.pid;
11172        report.uid = app.info.uid;
11173        report.tag = activity;
11174        report.shortMsg = shortMsg;
11175        report.longMsg = longMsg;
11176        report.stackTrace = stackTrace;
11177
11178        return report;
11179    }
11180
11181    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11182        synchronized (this) {
11183            app.crashing = false;
11184            app.crashingReport = null;
11185            app.notResponding = false;
11186            app.notRespondingReport = null;
11187            if (app.anrDialog == fromDialog) {
11188                app.anrDialog = null;
11189            }
11190            if (app.waitDialog == fromDialog) {
11191                app.waitDialog = null;
11192            }
11193            if (app.pid > 0 && app.pid != MY_PID) {
11194                handleAppCrashLocked(app, null, null, null);
11195                app.kill("user request after error", true);
11196            }
11197        }
11198    }
11199
11200    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11201            String stackTrace) {
11202        long now = SystemClock.uptimeMillis();
11203
11204        Long crashTime;
11205        if (!app.isolated) {
11206            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11207        } else {
11208            crashTime = null;
11209        }
11210        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11211            // This process loses!
11212            Slog.w(TAG, "Process " + app.info.processName
11213                    + " has crashed too many times: killing!");
11214            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11215                    app.userId, app.info.processName, app.uid);
11216            mStackSupervisor.handleAppCrashLocked(app);
11217            if (!app.persistent) {
11218                // We don't want to start this process again until the user
11219                // explicitly does so...  but for persistent process, we really
11220                // need to keep it running.  If a persistent process is actually
11221                // repeatedly crashing, then badness for everyone.
11222                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11223                        app.info.processName);
11224                if (!app.isolated) {
11225                    // XXX We don't have a way to mark isolated processes
11226                    // as bad, since they don't have a peristent identity.
11227                    mBadProcesses.put(app.info.processName, app.uid,
11228                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11229                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11230                }
11231                app.bad = true;
11232                app.removed = true;
11233                // Don't let services in this process be restarted and potentially
11234                // annoy the user repeatedly.  Unless it is persistent, since those
11235                // processes run critical code.
11236                removeProcessLocked(app, false, false, "crash");
11237                mStackSupervisor.resumeTopActivitiesLocked();
11238                return false;
11239            }
11240            mStackSupervisor.resumeTopActivitiesLocked();
11241        } else {
11242            mStackSupervisor.finishTopRunningActivityLocked(app);
11243        }
11244
11245        // Bump up the crash count of any services currently running in the proc.
11246        for (int i=app.services.size()-1; i>=0; i--) {
11247            // Any services running in the application need to be placed
11248            // back in the pending list.
11249            ServiceRecord sr = app.services.valueAt(i);
11250            sr.crashCount++;
11251        }
11252
11253        // If the crashing process is what we consider to be the "home process" and it has been
11254        // replaced by a third-party app, clear the package preferred activities from packages
11255        // with a home activity running in the process to prevent a repeatedly crashing app
11256        // from blocking the user to manually clear the list.
11257        final ArrayList<ActivityRecord> activities = app.activities;
11258        if (app == mHomeProcess && activities.size() > 0
11259                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11260            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11261                final ActivityRecord r = activities.get(activityNdx);
11262                if (r.isHomeActivity()) {
11263                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11264                    try {
11265                        ActivityThread.getPackageManager()
11266                                .clearPackagePreferredActivities(r.packageName);
11267                    } catch (RemoteException c) {
11268                        // pm is in same process, this will never happen.
11269                    }
11270                }
11271            }
11272        }
11273
11274        if (!app.isolated) {
11275            // XXX Can't keep track of crash times for isolated processes,
11276            // because they don't have a perisistent identity.
11277            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11278        }
11279
11280        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11281        return true;
11282    }
11283
11284    void startAppProblemLocked(ProcessRecord app) {
11285        // If this app is not running under the current user, then we
11286        // can't give it a report button because that would require
11287        // launching the report UI under a different user.
11288        app.errorReportReceiver = null;
11289
11290        for (int userId : mCurrentProfileIds) {
11291            if (app.userId == userId) {
11292                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11293                        mContext, app.info.packageName, app.info.flags);
11294            }
11295        }
11296        skipCurrentReceiverLocked(app);
11297    }
11298
11299    void skipCurrentReceiverLocked(ProcessRecord app) {
11300        for (BroadcastQueue queue : mBroadcastQueues) {
11301            queue.skipCurrentReceiverLocked(app);
11302        }
11303    }
11304
11305    /**
11306     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11307     * The application process will exit immediately after this call returns.
11308     * @param app object of the crashing app, null for the system server
11309     * @param crashInfo describing the exception
11310     */
11311    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11312        ProcessRecord r = findAppProcess(app, "Crash");
11313        final String processName = app == null ? "system_server"
11314                : (r == null ? "unknown" : r.processName);
11315
11316        handleApplicationCrashInner("crash", r, processName, crashInfo);
11317    }
11318
11319    /* Native crash reporting uses this inner version because it needs to be somewhat
11320     * decoupled from the AM-managed cleanup lifecycle
11321     */
11322    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11323            ApplicationErrorReport.CrashInfo crashInfo) {
11324        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11325                UserHandle.getUserId(Binder.getCallingUid()), processName,
11326                r == null ? -1 : r.info.flags,
11327                crashInfo.exceptionClassName,
11328                crashInfo.exceptionMessage,
11329                crashInfo.throwFileName,
11330                crashInfo.throwLineNumber);
11331
11332        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11333
11334        crashApplication(r, crashInfo);
11335    }
11336
11337    public void handleApplicationStrictModeViolation(
11338            IBinder app,
11339            int violationMask,
11340            StrictMode.ViolationInfo info) {
11341        ProcessRecord r = findAppProcess(app, "StrictMode");
11342        if (r == null) {
11343            return;
11344        }
11345
11346        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11347            Integer stackFingerprint = info.hashCode();
11348            boolean logIt = true;
11349            synchronized (mAlreadyLoggedViolatedStacks) {
11350                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11351                    logIt = false;
11352                    // TODO: sub-sample into EventLog for these, with
11353                    // the info.durationMillis?  Then we'd get
11354                    // the relative pain numbers, without logging all
11355                    // the stack traces repeatedly.  We'd want to do
11356                    // likewise in the client code, which also does
11357                    // dup suppression, before the Binder call.
11358                } else {
11359                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11360                        mAlreadyLoggedViolatedStacks.clear();
11361                    }
11362                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11363                }
11364            }
11365            if (logIt) {
11366                logStrictModeViolationToDropBox(r, info);
11367            }
11368        }
11369
11370        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11371            AppErrorResult result = new AppErrorResult();
11372            synchronized (this) {
11373                final long origId = Binder.clearCallingIdentity();
11374
11375                Message msg = Message.obtain();
11376                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11377                HashMap<String, Object> data = new HashMap<String, Object>();
11378                data.put("result", result);
11379                data.put("app", r);
11380                data.put("violationMask", violationMask);
11381                data.put("info", info);
11382                msg.obj = data;
11383                mHandler.sendMessage(msg);
11384
11385                Binder.restoreCallingIdentity(origId);
11386            }
11387            int res = result.get();
11388            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11389        }
11390    }
11391
11392    // Depending on the policy in effect, there could be a bunch of
11393    // these in quick succession so we try to batch these together to
11394    // minimize disk writes, number of dropbox entries, and maximize
11395    // compression, by having more fewer, larger records.
11396    private void logStrictModeViolationToDropBox(
11397            ProcessRecord process,
11398            StrictMode.ViolationInfo info) {
11399        if (info == null) {
11400            return;
11401        }
11402        final boolean isSystemApp = process == null ||
11403                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11404                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11405        final String processName = process == null ? "unknown" : process.processName;
11406        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11407        final DropBoxManager dbox = (DropBoxManager)
11408                mContext.getSystemService(Context.DROPBOX_SERVICE);
11409
11410        // Exit early if the dropbox isn't configured to accept this report type.
11411        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11412
11413        boolean bufferWasEmpty;
11414        boolean needsFlush;
11415        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11416        synchronized (sb) {
11417            bufferWasEmpty = sb.length() == 0;
11418            appendDropBoxProcessHeaders(process, processName, sb);
11419            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11420            sb.append("System-App: ").append(isSystemApp).append("\n");
11421            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11422            if (info.violationNumThisLoop != 0) {
11423                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11424            }
11425            if (info.numAnimationsRunning != 0) {
11426                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11427            }
11428            if (info.broadcastIntentAction != null) {
11429                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11430            }
11431            if (info.durationMillis != -1) {
11432                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11433            }
11434            if (info.numInstances != -1) {
11435                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11436            }
11437            if (info.tags != null) {
11438                for (String tag : info.tags) {
11439                    sb.append("Span-Tag: ").append(tag).append("\n");
11440                }
11441            }
11442            sb.append("\n");
11443            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11444                sb.append(info.crashInfo.stackTrace);
11445            }
11446            sb.append("\n");
11447
11448            // Only buffer up to ~64k.  Various logging bits truncate
11449            // things at 128k.
11450            needsFlush = (sb.length() > 64 * 1024);
11451        }
11452
11453        // Flush immediately if the buffer's grown too large, or this
11454        // is a non-system app.  Non-system apps are isolated with a
11455        // different tag & policy and not batched.
11456        //
11457        // Batching is useful during internal testing with
11458        // StrictMode settings turned up high.  Without batching,
11459        // thousands of separate files could be created on boot.
11460        if (!isSystemApp || needsFlush) {
11461            new Thread("Error dump: " + dropboxTag) {
11462                @Override
11463                public void run() {
11464                    String report;
11465                    synchronized (sb) {
11466                        report = sb.toString();
11467                        sb.delete(0, sb.length());
11468                        sb.trimToSize();
11469                    }
11470                    if (report.length() != 0) {
11471                        dbox.addText(dropboxTag, report);
11472                    }
11473                }
11474            }.start();
11475            return;
11476        }
11477
11478        // System app batching:
11479        if (!bufferWasEmpty) {
11480            // An existing dropbox-writing thread is outstanding, so
11481            // we don't need to start it up.  The existing thread will
11482            // catch the buffer appends we just did.
11483            return;
11484        }
11485
11486        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11487        // (After this point, we shouldn't access AMS internal data structures.)
11488        new Thread("Error dump: " + dropboxTag) {
11489            @Override
11490            public void run() {
11491                // 5 second sleep to let stacks arrive and be batched together
11492                try {
11493                    Thread.sleep(5000);  // 5 seconds
11494                } catch (InterruptedException e) {}
11495
11496                String errorReport;
11497                synchronized (mStrictModeBuffer) {
11498                    errorReport = mStrictModeBuffer.toString();
11499                    if (errorReport.length() == 0) {
11500                        return;
11501                    }
11502                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11503                    mStrictModeBuffer.trimToSize();
11504                }
11505                dbox.addText(dropboxTag, errorReport);
11506            }
11507        }.start();
11508    }
11509
11510    /**
11511     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11512     * @param app object of the crashing app, null for the system server
11513     * @param tag reported by the caller
11514     * @param system whether this wtf is coming from the system
11515     * @param crashInfo describing the context of the error
11516     * @return true if the process should exit immediately (WTF is fatal)
11517     */
11518    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11519            final ApplicationErrorReport.CrashInfo crashInfo) {
11520        final ProcessRecord r = findAppProcess(app, "WTF");
11521        final String processName = app == null ? "system_server"
11522                : (r == null ? "unknown" : r.processName);
11523
11524        EventLog.writeEvent(EventLogTags.AM_WTF,
11525                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11526                processName,
11527                r == null ? -1 : r.info.flags,
11528                tag, crashInfo.exceptionMessage);
11529
11530        if (system) {
11531            // If this is coming from the system, we could very well have low-level
11532            // system locks held, so we want to do this all asynchronously.  And we
11533            // never want this to become fatal, so there is that too.
11534            mHandler.post(new Runnable() {
11535                @Override public void run() {
11536                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11537                            crashInfo);
11538                }
11539            });
11540            return false;
11541        }
11542
11543        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11544
11545        if (r != null && r.pid != Process.myPid() &&
11546                Settings.Global.getInt(mContext.getContentResolver(),
11547                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11548            crashApplication(r, crashInfo);
11549            return true;
11550        } else {
11551            return false;
11552        }
11553    }
11554
11555    /**
11556     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11557     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11558     */
11559    private ProcessRecord findAppProcess(IBinder app, String reason) {
11560        if (app == null) {
11561            return null;
11562        }
11563
11564        synchronized (this) {
11565            final int NP = mProcessNames.getMap().size();
11566            for (int ip=0; ip<NP; ip++) {
11567                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11568                final int NA = apps.size();
11569                for (int ia=0; ia<NA; ia++) {
11570                    ProcessRecord p = apps.valueAt(ia);
11571                    if (p.thread != null && p.thread.asBinder() == app) {
11572                        return p;
11573                    }
11574                }
11575            }
11576
11577            Slog.w(TAG, "Can't find mystery application for " + reason
11578                    + " from pid=" + Binder.getCallingPid()
11579                    + " uid=" + Binder.getCallingUid() + ": " + app);
11580            return null;
11581        }
11582    }
11583
11584    /**
11585     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11586     * to append various headers to the dropbox log text.
11587     */
11588    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11589            StringBuilder sb) {
11590        // Watchdog thread ends up invoking this function (with
11591        // a null ProcessRecord) to add the stack file to dropbox.
11592        // Do not acquire a lock on this (am) in such cases, as it
11593        // could cause a potential deadlock, if and when watchdog
11594        // is invoked due to unavailability of lock on am and it
11595        // would prevent watchdog from killing system_server.
11596        if (process == null) {
11597            sb.append("Process: ").append(processName).append("\n");
11598            return;
11599        }
11600        // Note: ProcessRecord 'process' is guarded by the service
11601        // instance.  (notably process.pkgList, which could otherwise change
11602        // concurrently during execution of this method)
11603        synchronized (this) {
11604            sb.append("Process: ").append(processName).append("\n");
11605            int flags = process.info.flags;
11606            IPackageManager pm = AppGlobals.getPackageManager();
11607            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11608            for (int ip=0; ip<process.pkgList.size(); ip++) {
11609                String pkg = process.pkgList.keyAt(ip);
11610                sb.append("Package: ").append(pkg);
11611                try {
11612                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11613                    if (pi != null) {
11614                        sb.append(" v").append(pi.versionCode);
11615                        if (pi.versionName != null) {
11616                            sb.append(" (").append(pi.versionName).append(")");
11617                        }
11618                    }
11619                } catch (RemoteException e) {
11620                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11621                }
11622                sb.append("\n");
11623            }
11624        }
11625    }
11626
11627    private static String processClass(ProcessRecord process) {
11628        if (process == null || process.pid == MY_PID) {
11629            return "system_server";
11630        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11631            return "system_app";
11632        } else {
11633            return "data_app";
11634        }
11635    }
11636
11637    /**
11638     * Write a description of an error (crash, WTF, ANR) to the drop box.
11639     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11640     * @param process which caused the error, null means the system server
11641     * @param activity which triggered the error, null if unknown
11642     * @param parent activity related to the error, null if unknown
11643     * @param subject line related to the error, null if absent
11644     * @param report in long form describing the error, null if absent
11645     * @param logFile to include in the report, null if none
11646     * @param crashInfo giving an application stack trace, null if absent
11647     */
11648    public void addErrorToDropBox(String eventType,
11649            ProcessRecord process, String processName, ActivityRecord activity,
11650            ActivityRecord parent, String subject,
11651            final String report, final File logFile,
11652            final ApplicationErrorReport.CrashInfo crashInfo) {
11653        // NOTE -- this must never acquire the ActivityManagerService lock,
11654        // otherwise the watchdog may be prevented from resetting the system.
11655
11656        final String dropboxTag = processClass(process) + "_" + eventType;
11657        final DropBoxManager dbox = (DropBoxManager)
11658                mContext.getSystemService(Context.DROPBOX_SERVICE);
11659
11660        // Exit early if the dropbox isn't configured to accept this report type.
11661        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11662
11663        final StringBuilder sb = new StringBuilder(1024);
11664        appendDropBoxProcessHeaders(process, processName, sb);
11665        if (activity != null) {
11666            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11667        }
11668        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11669            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11670        }
11671        if (parent != null && parent != activity) {
11672            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11673        }
11674        if (subject != null) {
11675            sb.append("Subject: ").append(subject).append("\n");
11676        }
11677        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11678        if (Debug.isDebuggerConnected()) {
11679            sb.append("Debugger: Connected\n");
11680        }
11681        sb.append("\n");
11682
11683        // Do the rest in a worker thread to avoid blocking the caller on I/O
11684        // (After this point, we shouldn't access AMS internal data structures.)
11685        Thread worker = new Thread("Error dump: " + dropboxTag) {
11686            @Override
11687            public void run() {
11688                if (report != null) {
11689                    sb.append(report);
11690                }
11691                if (logFile != null) {
11692                    try {
11693                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11694                                    "\n\n[[TRUNCATED]]"));
11695                    } catch (IOException e) {
11696                        Slog.e(TAG, "Error reading " + logFile, e);
11697                    }
11698                }
11699                if (crashInfo != null && crashInfo.stackTrace != null) {
11700                    sb.append(crashInfo.stackTrace);
11701                }
11702
11703                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11704                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11705                if (lines > 0) {
11706                    sb.append("\n");
11707
11708                    // Merge several logcat streams, and take the last N lines
11709                    InputStreamReader input = null;
11710                    try {
11711                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11712                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11713                                "-b", "crash",
11714                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11715
11716                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11717                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11718                        input = new InputStreamReader(logcat.getInputStream());
11719
11720                        int num;
11721                        char[] buf = new char[8192];
11722                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11723                    } catch (IOException e) {
11724                        Slog.e(TAG, "Error running logcat", e);
11725                    } finally {
11726                        if (input != null) try { input.close(); } catch (IOException e) {}
11727                    }
11728                }
11729
11730                dbox.addText(dropboxTag, sb.toString());
11731            }
11732        };
11733
11734        if (process == null) {
11735            // If process is null, we are being called from some internal code
11736            // and may be about to die -- run this synchronously.
11737            worker.run();
11738        } else {
11739            worker.start();
11740        }
11741    }
11742
11743    /**
11744     * Bring up the "unexpected error" dialog box for a crashing app.
11745     * Deal with edge cases (intercepts from instrumented applications,
11746     * ActivityController, error intent receivers, that sort of thing).
11747     * @param r the application crashing
11748     * @param crashInfo describing the failure
11749     */
11750    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11751        long timeMillis = System.currentTimeMillis();
11752        String shortMsg = crashInfo.exceptionClassName;
11753        String longMsg = crashInfo.exceptionMessage;
11754        String stackTrace = crashInfo.stackTrace;
11755        if (shortMsg != null && longMsg != null) {
11756            longMsg = shortMsg + ": " + longMsg;
11757        } else if (shortMsg != null) {
11758            longMsg = shortMsg;
11759        }
11760
11761        AppErrorResult result = new AppErrorResult();
11762        synchronized (this) {
11763            if (mController != null) {
11764                try {
11765                    String name = r != null ? r.processName : null;
11766                    int pid = r != null ? r.pid : Binder.getCallingPid();
11767                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11768                    if (!mController.appCrashed(name, pid,
11769                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11770                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11771                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11772                            Slog.w(TAG, "Skip killing native crashed app " + name
11773                                    + "(" + pid + ") during testing");
11774                        } else {
11775                            Slog.w(TAG, "Force-killing crashed app " + name
11776                                    + " at watcher's request");
11777                            if (r != null) {
11778                                r.kill("crash", true);
11779                            } else {
11780                                // Huh.
11781                                Process.killProcess(pid);
11782                                Process.killProcessGroup(uid, pid);
11783                            }
11784                        }
11785                        return;
11786                    }
11787                } catch (RemoteException e) {
11788                    mController = null;
11789                    Watchdog.getInstance().setActivityController(null);
11790                }
11791            }
11792
11793            final long origId = Binder.clearCallingIdentity();
11794
11795            // If this process is running instrumentation, finish it.
11796            if (r != null && r.instrumentationClass != null) {
11797                Slog.w(TAG, "Error in app " + r.processName
11798                      + " running instrumentation " + r.instrumentationClass + ":");
11799                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11800                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11801                Bundle info = new Bundle();
11802                info.putString("shortMsg", shortMsg);
11803                info.putString("longMsg", longMsg);
11804                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11805                Binder.restoreCallingIdentity(origId);
11806                return;
11807            }
11808
11809            // If we can't identify the process or it's already exceeded its crash quota,
11810            // quit right away without showing a crash dialog.
11811            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11812                Binder.restoreCallingIdentity(origId);
11813                return;
11814            }
11815
11816            Message msg = Message.obtain();
11817            msg.what = SHOW_ERROR_MSG;
11818            HashMap data = new HashMap();
11819            data.put("result", result);
11820            data.put("app", r);
11821            msg.obj = data;
11822            mHandler.sendMessage(msg);
11823
11824            Binder.restoreCallingIdentity(origId);
11825        }
11826
11827        int res = result.get();
11828
11829        Intent appErrorIntent = null;
11830        synchronized (this) {
11831            if (r != null && !r.isolated) {
11832                // XXX Can't keep track of crash time for isolated processes,
11833                // since they don't have a persistent identity.
11834                mProcessCrashTimes.put(r.info.processName, r.uid,
11835                        SystemClock.uptimeMillis());
11836            }
11837            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11838                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11839            }
11840        }
11841
11842        if (appErrorIntent != null) {
11843            try {
11844                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11845            } catch (ActivityNotFoundException e) {
11846                Slog.w(TAG, "bug report receiver dissappeared", e);
11847            }
11848        }
11849    }
11850
11851    Intent createAppErrorIntentLocked(ProcessRecord r,
11852            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11853        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11854        if (report == null) {
11855            return null;
11856        }
11857        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11858        result.setComponent(r.errorReportReceiver);
11859        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11860        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11861        return result;
11862    }
11863
11864    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11865            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11866        if (r.errorReportReceiver == null) {
11867            return null;
11868        }
11869
11870        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11871            return null;
11872        }
11873
11874        ApplicationErrorReport report = new ApplicationErrorReport();
11875        report.packageName = r.info.packageName;
11876        report.installerPackageName = r.errorReportReceiver.getPackageName();
11877        report.processName = r.processName;
11878        report.time = timeMillis;
11879        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11880
11881        if (r.crashing || r.forceCrashReport) {
11882            report.type = ApplicationErrorReport.TYPE_CRASH;
11883            report.crashInfo = crashInfo;
11884        } else if (r.notResponding) {
11885            report.type = ApplicationErrorReport.TYPE_ANR;
11886            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11887
11888            report.anrInfo.activity = r.notRespondingReport.tag;
11889            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11890            report.anrInfo.info = r.notRespondingReport.longMsg;
11891        }
11892
11893        return report;
11894    }
11895
11896    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11897        enforceNotIsolatedCaller("getProcessesInErrorState");
11898        // assume our apps are happy - lazy create the list
11899        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11900
11901        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11902                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11903        int userId = UserHandle.getUserId(Binder.getCallingUid());
11904
11905        synchronized (this) {
11906
11907            // iterate across all processes
11908            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11909                ProcessRecord app = mLruProcesses.get(i);
11910                if (!allUsers && app.userId != userId) {
11911                    continue;
11912                }
11913                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11914                    // This one's in trouble, so we'll generate a report for it
11915                    // crashes are higher priority (in case there's a crash *and* an anr)
11916                    ActivityManager.ProcessErrorStateInfo report = null;
11917                    if (app.crashing) {
11918                        report = app.crashingReport;
11919                    } else if (app.notResponding) {
11920                        report = app.notRespondingReport;
11921                    }
11922
11923                    if (report != null) {
11924                        if (errList == null) {
11925                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11926                        }
11927                        errList.add(report);
11928                    } else {
11929                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11930                                " crashing = " + app.crashing +
11931                                " notResponding = " + app.notResponding);
11932                    }
11933                }
11934            }
11935        }
11936
11937        return errList;
11938    }
11939
11940    static int procStateToImportance(int procState, int memAdj,
11941            ActivityManager.RunningAppProcessInfo currApp) {
11942        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11943        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11944            currApp.lru = memAdj;
11945        } else {
11946            currApp.lru = 0;
11947        }
11948        return imp;
11949    }
11950
11951    private void fillInProcMemInfo(ProcessRecord app,
11952            ActivityManager.RunningAppProcessInfo outInfo) {
11953        outInfo.pid = app.pid;
11954        outInfo.uid = app.info.uid;
11955        if (mHeavyWeightProcess == app) {
11956            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11957        }
11958        if (app.persistent) {
11959            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11960        }
11961        if (app.activities.size() > 0) {
11962            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11963        }
11964        outInfo.lastTrimLevel = app.trimMemoryLevel;
11965        int adj = app.curAdj;
11966        int procState = app.curProcState;
11967        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11968        outInfo.importanceReasonCode = app.adjTypeCode;
11969        outInfo.processState = app.curProcState;
11970    }
11971
11972    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11973        enforceNotIsolatedCaller("getRunningAppProcesses");
11974        // Lazy instantiation of list
11975        List<ActivityManager.RunningAppProcessInfo> runList = null;
11976        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11977                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11978        int userId = UserHandle.getUserId(Binder.getCallingUid());
11979        synchronized (this) {
11980            // Iterate across all processes
11981            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11982                ProcessRecord app = mLruProcesses.get(i);
11983                if (!allUsers && app.userId != userId) {
11984                    continue;
11985                }
11986                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11987                    // Generate process state info for running application
11988                    ActivityManager.RunningAppProcessInfo currApp =
11989                        new ActivityManager.RunningAppProcessInfo(app.processName,
11990                                app.pid, app.getPackageList());
11991                    fillInProcMemInfo(app, currApp);
11992                    if (app.adjSource instanceof ProcessRecord) {
11993                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11994                        currApp.importanceReasonImportance =
11995                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11996                                        app.adjSourceProcState);
11997                    } else if (app.adjSource instanceof ActivityRecord) {
11998                        ActivityRecord r = (ActivityRecord)app.adjSource;
11999                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12000                    }
12001                    if (app.adjTarget instanceof ComponentName) {
12002                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12003                    }
12004                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12005                    //        + " lru=" + currApp.lru);
12006                    if (runList == null) {
12007                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12008                    }
12009                    runList.add(currApp);
12010                }
12011            }
12012        }
12013        return runList;
12014    }
12015
12016    public List<ApplicationInfo> getRunningExternalApplications() {
12017        enforceNotIsolatedCaller("getRunningExternalApplications");
12018        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12019        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12020        if (runningApps != null && runningApps.size() > 0) {
12021            Set<String> extList = new HashSet<String>();
12022            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12023                if (app.pkgList != null) {
12024                    for (String pkg : app.pkgList) {
12025                        extList.add(pkg);
12026                    }
12027                }
12028            }
12029            IPackageManager pm = AppGlobals.getPackageManager();
12030            for (String pkg : extList) {
12031                try {
12032                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12033                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12034                        retList.add(info);
12035                    }
12036                } catch (RemoteException e) {
12037                }
12038            }
12039        }
12040        return retList;
12041    }
12042
12043    @Override
12044    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12045        enforceNotIsolatedCaller("getMyMemoryState");
12046        synchronized (this) {
12047            ProcessRecord proc;
12048            synchronized (mPidsSelfLocked) {
12049                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12050            }
12051            fillInProcMemInfo(proc, outInfo);
12052        }
12053    }
12054
12055    @Override
12056    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12057        if (checkCallingPermission(android.Manifest.permission.DUMP)
12058                != PackageManager.PERMISSION_GRANTED) {
12059            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12060                    + Binder.getCallingPid()
12061                    + ", uid=" + Binder.getCallingUid()
12062                    + " without permission "
12063                    + android.Manifest.permission.DUMP);
12064            return;
12065        }
12066
12067        boolean dumpAll = false;
12068        boolean dumpClient = false;
12069        String dumpPackage = null;
12070
12071        int opti = 0;
12072        while (opti < args.length) {
12073            String opt = args[opti];
12074            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12075                break;
12076            }
12077            opti++;
12078            if ("-a".equals(opt)) {
12079                dumpAll = true;
12080            } else if ("-c".equals(opt)) {
12081                dumpClient = true;
12082            } else if ("-h".equals(opt)) {
12083                pw.println("Activity manager dump options:");
12084                pw.println("  [-a] [-c] [-h] [cmd] ...");
12085                pw.println("  cmd may be one of:");
12086                pw.println("    a[ctivities]: activity stack state");
12087                pw.println("    r[recents]: recent activities state");
12088                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12089                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12090                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12091                pw.println("    o[om]: out of memory management");
12092                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12093                pw.println("    provider [COMP_SPEC]: provider client-side state");
12094                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12095                pw.println("    service [COMP_SPEC]: service client-side state");
12096                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12097                pw.println("    all: dump all activities");
12098                pw.println("    top: dump the top activity");
12099                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12100                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12101                pw.println("    a partial substring in a component name, a");
12102                pw.println("    hex object identifier.");
12103                pw.println("  -a: include all available server state.");
12104                pw.println("  -c: include client state.");
12105                return;
12106            } else {
12107                pw.println("Unknown argument: " + opt + "; use -h for help");
12108            }
12109        }
12110
12111        long origId = Binder.clearCallingIdentity();
12112        boolean more = false;
12113        // Is the caller requesting to dump a particular piece of data?
12114        if (opti < args.length) {
12115            String cmd = args[opti];
12116            opti++;
12117            if ("activities".equals(cmd) || "a".equals(cmd)) {
12118                synchronized (this) {
12119                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12120                }
12121            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12122                synchronized (this) {
12123                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12124                }
12125            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12126                String[] newArgs;
12127                String name;
12128                if (opti >= args.length) {
12129                    name = null;
12130                    newArgs = EMPTY_STRING_ARRAY;
12131                } else {
12132                    name = args[opti];
12133                    opti++;
12134                    newArgs = new String[args.length - opti];
12135                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12136                            args.length - opti);
12137                }
12138                synchronized (this) {
12139                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12140                }
12141            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12142                String[] newArgs;
12143                String name;
12144                if (opti >= args.length) {
12145                    name = null;
12146                    newArgs = EMPTY_STRING_ARRAY;
12147                } else {
12148                    name = args[opti];
12149                    opti++;
12150                    newArgs = new String[args.length - opti];
12151                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12152                            args.length - opti);
12153                }
12154                synchronized (this) {
12155                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12156                }
12157            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12158                String[] newArgs;
12159                String name;
12160                if (opti >= args.length) {
12161                    name = null;
12162                    newArgs = EMPTY_STRING_ARRAY;
12163                } else {
12164                    name = args[opti];
12165                    opti++;
12166                    newArgs = new String[args.length - opti];
12167                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12168                            args.length - opti);
12169                }
12170                synchronized (this) {
12171                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12172                }
12173            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12174                synchronized (this) {
12175                    dumpOomLocked(fd, pw, args, opti, true);
12176                }
12177            } else if ("provider".equals(cmd)) {
12178                String[] newArgs;
12179                String name;
12180                if (opti >= args.length) {
12181                    name = null;
12182                    newArgs = EMPTY_STRING_ARRAY;
12183                } else {
12184                    name = args[opti];
12185                    opti++;
12186                    newArgs = new String[args.length - opti];
12187                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12188                }
12189                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12190                    pw.println("No providers match: " + name);
12191                    pw.println("Use -h for help.");
12192                }
12193            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12194                synchronized (this) {
12195                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12196                }
12197            } else if ("service".equals(cmd)) {
12198                String[] newArgs;
12199                String name;
12200                if (opti >= args.length) {
12201                    name = null;
12202                    newArgs = EMPTY_STRING_ARRAY;
12203                } else {
12204                    name = args[opti];
12205                    opti++;
12206                    newArgs = new String[args.length - opti];
12207                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12208                            args.length - opti);
12209                }
12210                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12211                    pw.println("No services match: " + name);
12212                    pw.println("Use -h for help.");
12213                }
12214            } else if ("package".equals(cmd)) {
12215                String[] newArgs;
12216                if (opti >= args.length) {
12217                    pw.println("package: no package name specified");
12218                    pw.println("Use -h for help.");
12219                } else {
12220                    dumpPackage = args[opti];
12221                    opti++;
12222                    newArgs = new String[args.length - opti];
12223                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12224                            args.length - opti);
12225                    args = newArgs;
12226                    opti = 0;
12227                    more = true;
12228                }
12229            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12230                synchronized (this) {
12231                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12232                }
12233            } else {
12234                // Dumping a single activity?
12235                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12236                    pw.println("Bad activity command, or no activities match: " + cmd);
12237                    pw.println("Use -h for help.");
12238                }
12239            }
12240            if (!more) {
12241                Binder.restoreCallingIdentity(origId);
12242                return;
12243            }
12244        }
12245
12246        // No piece of data specified, dump everything.
12247        synchronized (this) {
12248            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12249            pw.println();
12250            if (dumpAll) {
12251                pw.println("-------------------------------------------------------------------------------");
12252            }
12253            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12254            pw.println();
12255            if (dumpAll) {
12256                pw.println("-------------------------------------------------------------------------------");
12257            }
12258            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12259            pw.println();
12260            if (dumpAll) {
12261                pw.println("-------------------------------------------------------------------------------");
12262            }
12263            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12264            pw.println();
12265            if (dumpAll) {
12266                pw.println("-------------------------------------------------------------------------------");
12267            }
12268            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12269            pw.println();
12270            if (dumpAll) {
12271                pw.println("-------------------------------------------------------------------------------");
12272            }
12273            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12274            pw.println();
12275            if (dumpAll) {
12276                pw.println("-------------------------------------------------------------------------------");
12277            }
12278            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12279        }
12280        Binder.restoreCallingIdentity(origId);
12281    }
12282
12283    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12284            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12285        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12286
12287        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12288                dumpPackage);
12289        boolean needSep = printedAnything;
12290
12291        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12292                dumpPackage, needSep, "  mFocusedActivity: ");
12293        if (printed) {
12294            printedAnything = true;
12295            needSep = false;
12296        }
12297
12298        if (dumpPackage == null) {
12299            if (needSep) {
12300                pw.println();
12301            }
12302            needSep = true;
12303            printedAnything = true;
12304            mStackSupervisor.dump(pw, "  ");
12305        }
12306
12307        if (!printedAnything) {
12308            pw.println("  (nothing)");
12309        }
12310    }
12311
12312    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12313            int opti, boolean dumpAll, String dumpPackage) {
12314        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12315
12316        boolean printedAnything = false;
12317
12318        if (mRecentTasks.size() > 0) {
12319            boolean printedHeader = false;
12320
12321            final int N = mRecentTasks.size();
12322            for (int i=0; i<N; i++) {
12323                TaskRecord tr = mRecentTasks.get(i);
12324                if (dumpPackage != null) {
12325                    if (tr.realActivity == null ||
12326                            !dumpPackage.equals(tr.realActivity)) {
12327                        continue;
12328                    }
12329                }
12330                if (!printedHeader) {
12331                    pw.println("  Recent tasks:");
12332                    printedHeader = true;
12333                    printedAnything = true;
12334                }
12335                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12336                        pw.println(tr);
12337                if (dumpAll) {
12338                    mRecentTasks.get(i).dump(pw, "    ");
12339                }
12340            }
12341        }
12342
12343        if (!printedAnything) {
12344            pw.println("  (nothing)");
12345        }
12346    }
12347
12348    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12349            int opti, boolean dumpAll, String dumpPackage) {
12350        boolean needSep = false;
12351        boolean printedAnything = false;
12352        int numPers = 0;
12353
12354        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12355
12356        if (dumpAll) {
12357            final int NP = mProcessNames.getMap().size();
12358            for (int ip=0; ip<NP; ip++) {
12359                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12360                final int NA = procs.size();
12361                for (int ia=0; ia<NA; ia++) {
12362                    ProcessRecord r = procs.valueAt(ia);
12363                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12364                        continue;
12365                    }
12366                    if (!needSep) {
12367                        pw.println("  All known processes:");
12368                        needSep = true;
12369                        printedAnything = true;
12370                    }
12371                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12372                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12373                        pw.print(" "); pw.println(r);
12374                    r.dump(pw, "    ");
12375                    if (r.persistent) {
12376                        numPers++;
12377                    }
12378                }
12379            }
12380        }
12381
12382        if (mIsolatedProcesses.size() > 0) {
12383            boolean printed = false;
12384            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12385                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12386                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12387                    continue;
12388                }
12389                if (!printed) {
12390                    if (needSep) {
12391                        pw.println();
12392                    }
12393                    pw.println("  Isolated process list (sorted by uid):");
12394                    printedAnything = true;
12395                    printed = true;
12396                    needSep = true;
12397                }
12398                pw.println(String.format("%sIsolated #%2d: %s",
12399                        "    ", i, r.toString()));
12400            }
12401        }
12402
12403        if (mLruProcesses.size() > 0) {
12404            if (needSep) {
12405                pw.println();
12406            }
12407            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12408                    pw.print(" total, non-act at ");
12409                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12410                    pw.print(", non-svc at ");
12411                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12412                    pw.println("):");
12413            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12414            needSep = true;
12415            printedAnything = true;
12416        }
12417
12418        if (dumpAll || dumpPackage != null) {
12419            synchronized (mPidsSelfLocked) {
12420                boolean printed = false;
12421                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12422                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12423                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12424                        continue;
12425                    }
12426                    if (!printed) {
12427                        if (needSep) pw.println();
12428                        needSep = true;
12429                        pw.println("  PID mappings:");
12430                        printed = true;
12431                        printedAnything = true;
12432                    }
12433                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12434                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12435                }
12436            }
12437        }
12438
12439        if (mForegroundProcesses.size() > 0) {
12440            synchronized (mPidsSelfLocked) {
12441                boolean printed = false;
12442                for (int i=0; i<mForegroundProcesses.size(); i++) {
12443                    ProcessRecord r = mPidsSelfLocked.get(
12444                            mForegroundProcesses.valueAt(i).pid);
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("  Foreground Processes:");
12453                        printed = true;
12454                        printedAnything = true;
12455                    }
12456                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12457                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12458                }
12459            }
12460        }
12461
12462        if (mPersistentStartingProcesses.size() > 0) {
12463            if (needSep) pw.println();
12464            needSep = true;
12465            printedAnything = true;
12466            pw.println("  Persisent processes that are starting:");
12467            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12468                    "Starting Norm", "Restarting PERS", dumpPackage);
12469        }
12470
12471        if (mRemovedProcesses.size() > 0) {
12472            if (needSep) pw.println();
12473            needSep = true;
12474            printedAnything = true;
12475            pw.println("  Processes that are being removed:");
12476            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12477                    "Removed Norm", "Removed PERS", dumpPackage);
12478        }
12479
12480        if (mProcessesOnHold.size() > 0) {
12481            if (needSep) pw.println();
12482            needSep = true;
12483            printedAnything = true;
12484            pw.println("  Processes that are on old until the system is ready:");
12485            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12486                    "OnHold Norm", "OnHold PERS", dumpPackage);
12487        }
12488
12489        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12490
12491        if (mProcessCrashTimes.getMap().size() > 0) {
12492            boolean printed = false;
12493            long now = SystemClock.uptimeMillis();
12494            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12495            final int NP = pmap.size();
12496            for (int ip=0; ip<NP; ip++) {
12497                String pname = pmap.keyAt(ip);
12498                SparseArray<Long> uids = pmap.valueAt(ip);
12499                final int N = uids.size();
12500                for (int i=0; i<N; i++) {
12501                    int puid = uids.keyAt(i);
12502                    ProcessRecord r = mProcessNames.get(pname, puid);
12503                    if (dumpPackage != null && (r == null
12504                            || !r.pkgList.containsKey(dumpPackage))) {
12505                        continue;
12506                    }
12507                    if (!printed) {
12508                        if (needSep) pw.println();
12509                        needSep = true;
12510                        pw.println("  Time since processes crashed:");
12511                        printed = true;
12512                        printedAnything = true;
12513                    }
12514                    pw.print("    Process "); pw.print(pname);
12515                            pw.print(" uid "); pw.print(puid);
12516                            pw.print(": last crashed ");
12517                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12518                            pw.println(" ago");
12519                }
12520            }
12521        }
12522
12523        if (mBadProcesses.getMap().size() > 0) {
12524            boolean printed = false;
12525            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12526            final int NP = pmap.size();
12527            for (int ip=0; ip<NP; ip++) {
12528                String pname = pmap.keyAt(ip);
12529                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12530                final int N = uids.size();
12531                for (int i=0; i<N; i++) {
12532                    int puid = uids.keyAt(i);
12533                    ProcessRecord r = mProcessNames.get(pname, puid);
12534                    if (dumpPackage != null && (r == null
12535                            || !r.pkgList.containsKey(dumpPackage))) {
12536                        continue;
12537                    }
12538                    if (!printed) {
12539                        if (needSep) pw.println();
12540                        needSep = true;
12541                        pw.println("  Bad processes:");
12542                        printedAnything = true;
12543                    }
12544                    BadProcessInfo info = uids.valueAt(i);
12545                    pw.print("    Bad process "); pw.print(pname);
12546                            pw.print(" uid "); pw.print(puid);
12547                            pw.print(": crashed at time "); pw.println(info.time);
12548                    if (info.shortMsg != null) {
12549                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12550                    }
12551                    if (info.longMsg != null) {
12552                        pw.print("      Long msg: "); pw.println(info.longMsg);
12553                    }
12554                    if (info.stack != null) {
12555                        pw.println("      Stack:");
12556                        int lastPos = 0;
12557                        for (int pos=0; pos<info.stack.length(); pos++) {
12558                            if (info.stack.charAt(pos) == '\n') {
12559                                pw.print("        ");
12560                                pw.write(info.stack, lastPos, pos-lastPos);
12561                                pw.println();
12562                                lastPos = pos+1;
12563                            }
12564                        }
12565                        if (lastPos < info.stack.length()) {
12566                            pw.print("        ");
12567                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12568                            pw.println();
12569                        }
12570                    }
12571                }
12572            }
12573        }
12574
12575        if (dumpPackage == null) {
12576            pw.println();
12577            needSep = false;
12578            pw.println("  mStartedUsers:");
12579            for (int i=0; i<mStartedUsers.size(); i++) {
12580                UserStartedState uss = mStartedUsers.valueAt(i);
12581                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12582                        pw.print(": "); uss.dump("", pw);
12583            }
12584            pw.print("  mStartedUserArray: [");
12585            for (int i=0; i<mStartedUserArray.length; i++) {
12586                if (i > 0) pw.print(", ");
12587                pw.print(mStartedUserArray[i]);
12588            }
12589            pw.println("]");
12590            pw.print("  mUserLru: [");
12591            for (int i=0; i<mUserLru.size(); i++) {
12592                if (i > 0) pw.print(", ");
12593                pw.print(mUserLru.get(i));
12594            }
12595            pw.println("]");
12596            if (dumpAll) {
12597                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12598            }
12599            synchronized (mUserProfileGroupIdsSelfLocked) {
12600                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12601                    pw.println("  mUserProfileGroupIds:");
12602                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12603                        pw.print("    User #");
12604                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12605                        pw.print(" -> profile #");
12606                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12607                    }
12608                }
12609            }
12610        }
12611        if (mHomeProcess != null && (dumpPackage == null
12612                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12613            if (needSep) {
12614                pw.println();
12615                needSep = false;
12616            }
12617            pw.println("  mHomeProcess: " + mHomeProcess);
12618        }
12619        if (mPreviousProcess != null && (dumpPackage == null
12620                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12621            if (needSep) {
12622                pw.println();
12623                needSep = false;
12624            }
12625            pw.println("  mPreviousProcess: " + mPreviousProcess);
12626        }
12627        if (dumpAll) {
12628            StringBuilder sb = new StringBuilder(128);
12629            sb.append("  mPreviousProcessVisibleTime: ");
12630            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12631            pw.println(sb);
12632        }
12633        if (mHeavyWeightProcess != null && (dumpPackage == null
12634                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12635            if (needSep) {
12636                pw.println();
12637                needSep = false;
12638            }
12639            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12640        }
12641        if (dumpPackage == null) {
12642            pw.println("  mConfiguration: " + mConfiguration);
12643        }
12644        if (dumpAll) {
12645            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12646            if (mCompatModePackages.getPackages().size() > 0) {
12647                boolean printed = false;
12648                for (Map.Entry<String, Integer> entry
12649                        : mCompatModePackages.getPackages().entrySet()) {
12650                    String pkg = entry.getKey();
12651                    int mode = entry.getValue();
12652                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12653                        continue;
12654                    }
12655                    if (!printed) {
12656                        pw.println("  mScreenCompatPackages:");
12657                        printed = true;
12658                    }
12659                    pw.print("    "); pw.print(pkg); pw.print(": ");
12660                            pw.print(mode); pw.println();
12661                }
12662            }
12663        }
12664        if (dumpPackage == null) {
12665            if (mSleeping || mWentToSleep || mLockScreenShown) {
12666                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12667                        + " mLockScreenShown " + mLockScreenShown);
12668            }
12669            if (mShuttingDown || mRunningVoice) {
12670                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12671            }
12672        }
12673        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12674                || mOrigWaitForDebugger) {
12675            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12676                    || dumpPackage.equals(mOrigDebugApp)) {
12677                if (needSep) {
12678                    pw.println();
12679                    needSep = false;
12680                }
12681                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12682                        + " mDebugTransient=" + mDebugTransient
12683                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12684            }
12685        }
12686        if (mOpenGlTraceApp != null) {
12687            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12688                if (needSep) {
12689                    pw.println();
12690                    needSep = false;
12691                }
12692                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12693            }
12694        }
12695        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12696                || mProfileFd != null) {
12697            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12698                if (needSep) {
12699                    pw.println();
12700                    needSep = false;
12701                }
12702                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12703                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12704                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12705                        + mAutoStopProfiler);
12706                pw.println("  mProfileType=" + mProfileType);
12707            }
12708        }
12709        if (dumpPackage == null) {
12710            if (mAlwaysFinishActivities || mController != null) {
12711                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12712                        + " mController=" + mController);
12713            }
12714            if (dumpAll) {
12715                pw.println("  Total persistent processes: " + numPers);
12716                pw.println("  mProcessesReady=" + mProcessesReady
12717                        + " mSystemReady=" + mSystemReady);
12718                pw.println("  mBooting=" + mBooting
12719                        + " mBooted=" + mBooted
12720                        + " mFactoryTest=" + mFactoryTest);
12721                pw.print("  mLastPowerCheckRealtime=");
12722                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12723                        pw.println("");
12724                pw.print("  mLastPowerCheckUptime=");
12725                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12726                        pw.println("");
12727                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12728                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12729                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12730                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12731                        + " (" + mLruProcesses.size() + " total)"
12732                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12733                        + " mNumServiceProcs=" + mNumServiceProcs
12734                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12735                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12736                        + " mLastMemoryLevel" + mLastMemoryLevel
12737                        + " mLastNumProcesses" + mLastNumProcesses);
12738                long now = SystemClock.uptimeMillis();
12739                pw.print("  mLastIdleTime=");
12740                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12741                        pw.print(" mLowRamSinceLastIdle=");
12742                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12743                        pw.println();
12744            }
12745        }
12746
12747        if (!printedAnything) {
12748            pw.println("  (nothing)");
12749        }
12750    }
12751
12752    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12753            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12754        if (mProcessesToGc.size() > 0) {
12755            boolean printed = false;
12756            long now = SystemClock.uptimeMillis();
12757            for (int i=0; i<mProcessesToGc.size(); i++) {
12758                ProcessRecord proc = mProcessesToGc.get(i);
12759                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12760                    continue;
12761                }
12762                if (!printed) {
12763                    if (needSep) pw.println();
12764                    needSep = true;
12765                    pw.println("  Processes that are waiting to GC:");
12766                    printed = true;
12767                }
12768                pw.print("    Process "); pw.println(proc);
12769                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12770                        pw.print(", last gced=");
12771                        pw.print(now-proc.lastRequestedGc);
12772                        pw.print(" ms ago, last lowMem=");
12773                        pw.print(now-proc.lastLowMemory);
12774                        pw.println(" ms ago");
12775
12776            }
12777        }
12778        return needSep;
12779    }
12780
12781    void printOomLevel(PrintWriter pw, String name, int adj) {
12782        pw.print("    ");
12783        if (adj >= 0) {
12784            pw.print(' ');
12785            if (adj < 10) pw.print(' ');
12786        } else {
12787            if (adj > -10) pw.print(' ');
12788        }
12789        pw.print(adj);
12790        pw.print(": ");
12791        pw.print(name);
12792        pw.print(" (");
12793        pw.print(mProcessList.getMemLevel(adj)/1024);
12794        pw.println(" kB)");
12795    }
12796
12797    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12798            int opti, boolean dumpAll) {
12799        boolean needSep = false;
12800
12801        if (mLruProcesses.size() > 0) {
12802            if (needSep) pw.println();
12803            needSep = true;
12804            pw.println("  OOM levels:");
12805            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12806            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12807            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12808            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12809            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12810            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12811            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12812            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12813            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12814            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12815            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12816            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12817            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12818
12819            if (needSep) pw.println();
12820            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12821                    pw.print(" total, non-act at ");
12822                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12823                    pw.print(", non-svc at ");
12824                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12825                    pw.println("):");
12826            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12827            needSep = true;
12828        }
12829
12830        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12831
12832        pw.println();
12833        pw.println("  mHomeProcess: " + mHomeProcess);
12834        pw.println("  mPreviousProcess: " + mPreviousProcess);
12835        if (mHeavyWeightProcess != null) {
12836            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12837        }
12838
12839        return true;
12840    }
12841
12842    /**
12843     * There are three ways to call this:
12844     *  - no provider specified: dump all the providers
12845     *  - a flattened component name that matched an existing provider was specified as the
12846     *    first arg: dump that one provider
12847     *  - the first arg isn't the flattened component name of an existing provider:
12848     *    dump all providers whose component contains the first arg as a substring
12849     */
12850    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12851            int opti, boolean dumpAll) {
12852        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12853    }
12854
12855    static class ItemMatcher {
12856        ArrayList<ComponentName> components;
12857        ArrayList<String> strings;
12858        ArrayList<Integer> objects;
12859        boolean all;
12860
12861        ItemMatcher() {
12862            all = true;
12863        }
12864
12865        void build(String name) {
12866            ComponentName componentName = ComponentName.unflattenFromString(name);
12867            if (componentName != null) {
12868                if (components == null) {
12869                    components = new ArrayList<ComponentName>();
12870                }
12871                components.add(componentName);
12872                all = false;
12873            } else {
12874                int objectId = 0;
12875                // Not a '/' separated full component name; maybe an object ID?
12876                try {
12877                    objectId = Integer.parseInt(name, 16);
12878                    if (objects == null) {
12879                        objects = new ArrayList<Integer>();
12880                    }
12881                    objects.add(objectId);
12882                    all = false;
12883                } catch (RuntimeException e) {
12884                    // Not an integer; just do string match.
12885                    if (strings == null) {
12886                        strings = new ArrayList<String>();
12887                    }
12888                    strings.add(name);
12889                    all = false;
12890                }
12891            }
12892        }
12893
12894        int build(String[] args, int opti) {
12895            for (; opti<args.length; opti++) {
12896                String name = args[opti];
12897                if ("--".equals(name)) {
12898                    return opti+1;
12899                }
12900                build(name);
12901            }
12902            return opti;
12903        }
12904
12905        boolean match(Object object, ComponentName comp) {
12906            if (all) {
12907                return true;
12908            }
12909            if (components != null) {
12910                for (int i=0; i<components.size(); i++) {
12911                    if (components.get(i).equals(comp)) {
12912                        return true;
12913                    }
12914                }
12915            }
12916            if (objects != null) {
12917                for (int i=0; i<objects.size(); i++) {
12918                    if (System.identityHashCode(object) == objects.get(i)) {
12919                        return true;
12920                    }
12921                }
12922            }
12923            if (strings != null) {
12924                String flat = comp.flattenToString();
12925                for (int i=0; i<strings.size(); i++) {
12926                    if (flat.contains(strings.get(i))) {
12927                        return true;
12928                    }
12929                }
12930            }
12931            return false;
12932        }
12933    }
12934
12935    /**
12936     * There are three things that cmd can be:
12937     *  - a flattened component name that matches an existing activity
12938     *  - the cmd arg isn't the flattened component name of an existing activity:
12939     *    dump all activity whose component contains the cmd as a substring
12940     *  - A hex number of the ActivityRecord object instance.
12941     */
12942    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12943            int opti, boolean dumpAll) {
12944        ArrayList<ActivityRecord> activities;
12945
12946        synchronized (this) {
12947            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12948        }
12949
12950        if (activities.size() <= 0) {
12951            return false;
12952        }
12953
12954        String[] newArgs = new String[args.length - opti];
12955        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12956
12957        TaskRecord lastTask = null;
12958        boolean needSep = false;
12959        for (int i=activities.size()-1; i>=0; i--) {
12960            ActivityRecord r = activities.get(i);
12961            if (needSep) {
12962                pw.println();
12963            }
12964            needSep = true;
12965            synchronized (this) {
12966                if (lastTask != r.task) {
12967                    lastTask = r.task;
12968                    pw.print("TASK "); pw.print(lastTask.affinity);
12969                            pw.print(" id="); pw.println(lastTask.taskId);
12970                    if (dumpAll) {
12971                        lastTask.dump(pw, "  ");
12972                    }
12973                }
12974            }
12975            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12976        }
12977        return true;
12978    }
12979
12980    /**
12981     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12982     * there is a thread associated with the activity.
12983     */
12984    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12985            final ActivityRecord r, String[] args, boolean dumpAll) {
12986        String innerPrefix = prefix + "  ";
12987        synchronized (this) {
12988            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12989                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12990                    pw.print(" pid=");
12991                    if (r.app != null) pw.println(r.app.pid);
12992                    else pw.println("(not running)");
12993            if (dumpAll) {
12994                r.dump(pw, innerPrefix);
12995            }
12996        }
12997        if (r.app != null && r.app.thread != null) {
12998            // flush anything that is already in the PrintWriter since the thread is going
12999            // to write to the file descriptor directly
13000            pw.flush();
13001            try {
13002                TransferPipe tp = new TransferPipe();
13003                try {
13004                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13005                            r.appToken, innerPrefix, args);
13006                    tp.go(fd);
13007                } finally {
13008                    tp.kill();
13009                }
13010            } catch (IOException e) {
13011                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13012            } catch (RemoteException e) {
13013                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13014            }
13015        }
13016    }
13017
13018    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13019            int opti, boolean dumpAll, String dumpPackage) {
13020        boolean needSep = false;
13021        boolean onlyHistory = false;
13022        boolean printedAnything = false;
13023
13024        if ("history".equals(dumpPackage)) {
13025            if (opti < args.length && "-s".equals(args[opti])) {
13026                dumpAll = false;
13027            }
13028            onlyHistory = true;
13029            dumpPackage = null;
13030        }
13031
13032        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13033        if (!onlyHistory && dumpAll) {
13034            if (mRegisteredReceivers.size() > 0) {
13035                boolean printed = false;
13036                Iterator it = mRegisteredReceivers.values().iterator();
13037                while (it.hasNext()) {
13038                    ReceiverList r = (ReceiverList)it.next();
13039                    if (dumpPackage != null && (r.app == null ||
13040                            !dumpPackage.equals(r.app.info.packageName))) {
13041                        continue;
13042                    }
13043                    if (!printed) {
13044                        pw.println("  Registered Receivers:");
13045                        needSep = true;
13046                        printed = true;
13047                        printedAnything = true;
13048                    }
13049                    pw.print("  * "); pw.println(r);
13050                    r.dump(pw, "    ");
13051                }
13052            }
13053
13054            if (mReceiverResolver.dump(pw, needSep ?
13055                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13056                    "    ", dumpPackage, false)) {
13057                needSep = true;
13058                printedAnything = true;
13059            }
13060        }
13061
13062        for (BroadcastQueue q : mBroadcastQueues) {
13063            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13064            printedAnything |= needSep;
13065        }
13066
13067        needSep = true;
13068
13069        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13070            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13071                if (needSep) {
13072                    pw.println();
13073                }
13074                needSep = true;
13075                printedAnything = true;
13076                pw.print("  Sticky broadcasts for user ");
13077                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13078                StringBuilder sb = new StringBuilder(128);
13079                for (Map.Entry<String, ArrayList<Intent>> ent
13080                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13081                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13082                    if (dumpAll) {
13083                        pw.println(":");
13084                        ArrayList<Intent> intents = ent.getValue();
13085                        final int N = intents.size();
13086                        for (int i=0; i<N; i++) {
13087                            sb.setLength(0);
13088                            sb.append("    Intent: ");
13089                            intents.get(i).toShortString(sb, false, true, false, false);
13090                            pw.println(sb.toString());
13091                            Bundle bundle = intents.get(i).getExtras();
13092                            if (bundle != null) {
13093                                pw.print("      ");
13094                                pw.println(bundle.toString());
13095                            }
13096                        }
13097                    } else {
13098                        pw.println("");
13099                    }
13100                }
13101            }
13102        }
13103
13104        if (!onlyHistory && dumpAll) {
13105            pw.println();
13106            for (BroadcastQueue queue : mBroadcastQueues) {
13107                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13108                        + queue.mBroadcastsScheduled);
13109            }
13110            pw.println("  mHandler:");
13111            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13112            needSep = true;
13113            printedAnything = true;
13114        }
13115
13116        if (!printedAnything) {
13117            pw.println("  (nothing)");
13118        }
13119    }
13120
13121    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13122            int opti, boolean dumpAll, String dumpPackage) {
13123        boolean needSep;
13124        boolean printedAnything = false;
13125
13126        ItemMatcher matcher = new ItemMatcher();
13127        matcher.build(args, opti);
13128
13129        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13130
13131        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13132        printedAnything |= needSep;
13133
13134        if (mLaunchingProviders.size() > 0) {
13135            boolean printed = false;
13136            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13137                ContentProviderRecord r = mLaunchingProviders.get(i);
13138                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13139                    continue;
13140                }
13141                if (!printed) {
13142                    if (needSep) pw.println();
13143                    needSep = true;
13144                    pw.println("  Launching content providers:");
13145                    printed = true;
13146                    printedAnything = true;
13147                }
13148                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13149                        pw.println(r);
13150            }
13151        }
13152
13153        if (mGrantedUriPermissions.size() > 0) {
13154            boolean printed = false;
13155            int dumpUid = -2;
13156            if (dumpPackage != null) {
13157                try {
13158                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13159                } catch (NameNotFoundException e) {
13160                    dumpUid = -1;
13161                }
13162            }
13163            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13164                int uid = mGrantedUriPermissions.keyAt(i);
13165                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13166                    continue;
13167                }
13168                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13169                if (!printed) {
13170                    if (needSep) pw.println();
13171                    needSep = true;
13172                    pw.println("  Granted Uri Permissions:");
13173                    printed = true;
13174                    printedAnything = true;
13175                }
13176                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13177                for (UriPermission perm : perms.values()) {
13178                    pw.print("    "); pw.println(perm);
13179                    if (dumpAll) {
13180                        perm.dump(pw, "      ");
13181                    }
13182                }
13183            }
13184        }
13185
13186        if (!printedAnything) {
13187            pw.println("  (nothing)");
13188        }
13189    }
13190
13191    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13192            int opti, boolean dumpAll, String dumpPackage) {
13193        boolean printed = false;
13194
13195        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13196
13197        if (mIntentSenderRecords.size() > 0) {
13198            Iterator<WeakReference<PendingIntentRecord>> it
13199                    = mIntentSenderRecords.values().iterator();
13200            while (it.hasNext()) {
13201                WeakReference<PendingIntentRecord> ref = it.next();
13202                PendingIntentRecord rec = ref != null ? ref.get(): null;
13203                if (dumpPackage != null && (rec == null
13204                        || !dumpPackage.equals(rec.key.packageName))) {
13205                    continue;
13206                }
13207                printed = true;
13208                if (rec != null) {
13209                    pw.print("  * "); pw.println(rec);
13210                    if (dumpAll) {
13211                        rec.dump(pw, "    ");
13212                    }
13213                } else {
13214                    pw.print("  * "); pw.println(ref);
13215                }
13216            }
13217        }
13218
13219        if (!printed) {
13220            pw.println("  (nothing)");
13221        }
13222    }
13223
13224    private static final int dumpProcessList(PrintWriter pw,
13225            ActivityManagerService service, List list,
13226            String prefix, String normalLabel, String persistentLabel,
13227            String dumpPackage) {
13228        int numPers = 0;
13229        final int N = list.size()-1;
13230        for (int i=N; i>=0; i--) {
13231            ProcessRecord r = (ProcessRecord)list.get(i);
13232            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13233                continue;
13234            }
13235            pw.println(String.format("%s%s #%2d: %s",
13236                    prefix, (r.persistent ? persistentLabel : normalLabel),
13237                    i, r.toString()));
13238            if (r.persistent) {
13239                numPers++;
13240            }
13241        }
13242        return numPers;
13243    }
13244
13245    private static final boolean dumpProcessOomList(PrintWriter pw,
13246            ActivityManagerService service, List<ProcessRecord> origList,
13247            String prefix, String normalLabel, String persistentLabel,
13248            boolean inclDetails, String dumpPackage) {
13249
13250        ArrayList<Pair<ProcessRecord, Integer>> list
13251                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13252        for (int i=0; i<origList.size(); i++) {
13253            ProcessRecord r = origList.get(i);
13254            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13255                continue;
13256            }
13257            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13258        }
13259
13260        if (list.size() <= 0) {
13261            return false;
13262        }
13263
13264        Comparator<Pair<ProcessRecord, Integer>> comparator
13265                = new Comparator<Pair<ProcessRecord, Integer>>() {
13266            @Override
13267            public int compare(Pair<ProcessRecord, Integer> object1,
13268                    Pair<ProcessRecord, Integer> object2) {
13269                if (object1.first.setAdj != object2.first.setAdj) {
13270                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13271                }
13272                if (object1.second.intValue() != object2.second.intValue()) {
13273                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13274                }
13275                return 0;
13276            }
13277        };
13278
13279        Collections.sort(list, comparator);
13280
13281        final long curRealtime = SystemClock.elapsedRealtime();
13282        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13283        final long curUptime = SystemClock.uptimeMillis();
13284        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13285
13286        for (int i=list.size()-1; i>=0; i--) {
13287            ProcessRecord r = list.get(i).first;
13288            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13289            char schedGroup;
13290            switch (r.setSchedGroup) {
13291                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13292                    schedGroup = 'B';
13293                    break;
13294                case Process.THREAD_GROUP_DEFAULT:
13295                    schedGroup = 'F';
13296                    break;
13297                default:
13298                    schedGroup = '?';
13299                    break;
13300            }
13301            char foreground;
13302            if (r.foregroundActivities) {
13303                foreground = 'A';
13304            } else if (r.foregroundServices) {
13305                foreground = 'S';
13306            } else {
13307                foreground = ' ';
13308            }
13309            String procState = ProcessList.makeProcStateString(r.curProcState);
13310            pw.print(prefix);
13311            pw.print(r.persistent ? persistentLabel : normalLabel);
13312            pw.print(" #");
13313            int num = (origList.size()-1)-list.get(i).second;
13314            if (num < 10) pw.print(' ');
13315            pw.print(num);
13316            pw.print(": ");
13317            pw.print(oomAdj);
13318            pw.print(' ');
13319            pw.print(schedGroup);
13320            pw.print('/');
13321            pw.print(foreground);
13322            pw.print('/');
13323            pw.print(procState);
13324            pw.print(" trm:");
13325            if (r.trimMemoryLevel < 10) pw.print(' ');
13326            pw.print(r.trimMemoryLevel);
13327            pw.print(' ');
13328            pw.print(r.toShortString());
13329            pw.print(" (");
13330            pw.print(r.adjType);
13331            pw.println(')');
13332            if (r.adjSource != null || r.adjTarget != null) {
13333                pw.print(prefix);
13334                pw.print("    ");
13335                if (r.adjTarget instanceof ComponentName) {
13336                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13337                } else if (r.adjTarget != null) {
13338                    pw.print(r.adjTarget.toString());
13339                } else {
13340                    pw.print("{null}");
13341                }
13342                pw.print("<=");
13343                if (r.adjSource instanceof ProcessRecord) {
13344                    pw.print("Proc{");
13345                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13346                    pw.println("}");
13347                } else if (r.adjSource != null) {
13348                    pw.println(r.adjSource.toString());
13349                } else {
13350                    pw.println("{null}");
13351                }
13352            }
13353            if (inclDetails) {
13354                pw.print(prefix);
13355                pw.print("    ");
13356                pw.print("oom: max="); pw.print(r.maxAdj);
13357                pw.print(" curRaw="); pw.print(r.curRawAdj);
13358                pw.print(" setRaw="); pw.print(r.setRawAdj);
13359                pw.print(" cur="); pw.print(r.curAdj);
13360                pw.print(" set="); pw.println(r.setAdj);
13361                pw.print(prefix);
13362                pw.print("    ");
13363                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13364                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13365                pw.print(" lastPss="); pw.print(r.lastPss);
13366                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13367                pw.print(prefix);
13368                pw.print("    ");
13369                pw.print("cached="); pw.print(r.cached);
13370                pw.print(" empty="); pw.print(r.empty);
13371                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13372
13373                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13374                    if (r.lastWakeTime != 0) {
13375                        long wtime;
13376                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13377                        synchronized (stats) {
13378                            wtime = stats.getProcessWakeTime(r.info.uid,
13379                                    r.pid, curRealtime);
13380                        }
13381                        long timeUsed = wtime - r.lastWakeTime;
13382                        pw.print(prefix);
13383                        pw.print("    ");
13384                        pw.print("keep awake over ");
13385                        TimeUtils.formatDuration(realtimeSince, pw);
13386                        pw.print(" used ");
13387                        TimeUtils.formatDuration(timeUsed, pw);
13388                        pw.print(" (");
13389                        pw.print((timeUsed*100)/realtimeSince);
13390                        pw.println("%)");
13391                    }
13392                    if (r.lastCpuTime != 0) {
13393                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13394                        pw.print(prefix);
13395                        pw.print("    ");
13396                        pw.print("run cpu over ");
13397                        TimeUtils.formatDuration(uptimeSince, pw);
13398                        pw.print(" used ");
13399                        TimeUtils.formatDuration(timeUsed, pw);
13400                        pw.print(" (");
13401                        pw.print((timeUsed*100)/uptimeSince);
13402                        pw.println("%)");
13403                    }
13404                }
13405            }
13406        }
13407        return true;
13408    }
13409
13410    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13411        ArrayList<ProcessRecord> procs;
13412        synchronized (this) {
13413            if (args != null && args.length > start
13414                    && args[start].charAt(0) != '-') {
13415                procs = new ArrayList<ProcessRecord>();
13416                int pid = -1;
13417                try {
13418                    pid = Integer.parseInt(args[start]);
13419                } catch (NumberFormatException e) {
13420                }
13421                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13422                    ProcessRecord proc = mLruProcesses.get(i);
13423                    if (proc.pid == pid) {
13424                        procs.add(proc);
13425                    } else if (proc.processName.equals(args[start])) {
13426                        procs.add(proc);
13427                    }
13428                }
13429                if (procs.size() <= 0) {
13430                    return null;
13431                }
13432            } else {
13433                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13434            }
13435        }
13436        return procs;
13437    }
13438
13439    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13440            PrintWriter pw, String[] args) {
13441        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13442        if (procs == null) {
13443            pw.println("No process found for: " + args[0]);
13444            return;
13445        }
13446
13447        long uptime = SystemClock.uptimeMillis();
13448        long realtime = SystemClock.elapsedRealtime();
13449        pw.println("Applications Graphics Acceleration Info:");
13450        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13451
13452        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13453            ProcessRecord r = procs.get(i);
13454            if (r.thread != null) {
13455                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13456                pw.flush();
13457                try {
13458                    TransferPipe tp = new TransferPipe();
13459                    try {
13460                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13461                        tp.go(fd);
13462                    } finally {
13463                        tp.kill();
13464                    }
13465                } catch (IOException e) {
13466                    pw.println("Failure while dumping the app: " + r);
13467                    pw.flush();
13468                } catch (RemoteException e) {
13469                    pw.println("Got a RemoteException while dumping the app " + r);
13470                    pw.flush();
13471                }
13472            }
13473        }
13474    }
13475
13476    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13477        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13478        if (procs == null) {
13479            pw.println("No process found for: " + args[0]);
13480            return;
13481        }
13482
13483        pw.println("Applications Database Info:");
13484
13485        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13486            ProcessRecord r = procs.get(i);
13487            if (r.thread != null) {
13488                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13489                pw.flush();
13490                try {
13491                    TransferPipe tp = new TransferPipe();
13492                    try {
13493                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13494                        tp.go(fd);
13495                    } finally {
13496                        tp.kill();
13497                    }
13498                } catch (IOException e) {
13499                    pw.println("Failure while dumping the app: " + r);
13500                    pw.flush();
13501                } catch (RemoteException e) {
13502                    pw.println("Got a RemoteException while dumping the app " + r);
13503                    pw.flush();
13504                }
13505            }
13506        }
13507    }
13508
13509    final static class MemItem {
13510        final boolean isProc;
13511        final String label;
13512        final String shortLabel;
13513        final long pss;
13514        final int id;
13515        final boolean hasActivities;
13516        ArrayList<MemItem> subitems;
13517
13518        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13519                boolean _hasActivities) {
13520            isProc = true;
13521            label = _label;
13522            shortLabel = _shortLabel;
13523            pss = _pss;
13524            id = _id;
13525            hasActivities = _hasActivities;
13526        }
13527
13528        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13529            isProc = false;
13530            label = _label;
13531            shortLabel = _shortLabel;
13532            pss = _pss;
13533            id = _id;
13534            hasActivities = false;
13535        }
13536    }
13537
13538    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13539            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13540        if (sort && !isCompact) {
13541            Collections.sort(items, new Comparator<MemItem>() {
13542                @Override
13543                public int compare(MemItem lhs, MemItem rhs) {
13544                    if (lhs.pss < rhs.pss) {
13545                        return 1;
13546                    } else if (lhs.pss > rhs.pss) {
13547                        return -1;
13548                    }
13549                    return 0;
13550                }
13551            });
13552        }
13553
13554        for (int i=0; i<items.size(); i++) {
13555            MemItem mi = items.get(i);
13556            if (!isCompact) {
13557                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13558            } else if (mi.isProc) {
13559                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13560                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13561                pw.println(mi.hasActivities ? ",a" : ",e");
13562            } else {
13563                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13564                pw.println(mi.pss);
13565            }
13566            if (mi.subitems != null) {
13567                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13568                        true, isCompact);
13569            }
13570        }
13571    }
13572
13573    // These are in KB.
13574    static final long[] DUMP_MEM_BUCKETS = new long[] {
13575        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13576        120*1024, 160*1024, 200*1024,
13577        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13578        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13579    };
13580
13581    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13582            boolean stackLike) {
13583        int start = label.lastIndexOf('.');
13584        if (start >= 0) start++;
13585        else start = 0;
13586        int end = label.length();
13587        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13588            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13589                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13590                out.append(bucket);
13591                out.append(stackLike ? "MB." : "MB ");
13592                out.append(label, start, end);
13593                return;
13594            }
13595        }
13596        out.append(memKB/1024);
13597        out.append(stackLike ? "MB." : "MB ");
13598        out.append(label, start, end);
13599    }
13600
13601    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13602            ProcessList.NATIVE_ADJ,
13603            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13604            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13605            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13606            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13607            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13608    };
13609    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13610            "Native",
13611            "System", "Persistent", "Foreground",
13612            "Visible", "Perceptible",
13613            "Heavy Weight", "Backup",
13614            "A Services", "Home",
13615            "Previous", "B Services", "Cached"
13616    };
13617    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13618            "native",
13619            "sys", "pers", "fore",
13620            "vis", "percept",
13621            "heavy", "backup",
13622            "servicea", "home",
13623            "prev", "serviceb", "cached"
13624    };
13625
13626    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13627            long realtime, boolean isCheckinRequest, boolean isCompact) {
13628        if (isCheckinRequest || isCompact) {
13629            // short checkin version
13630            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13631        } else {
13632            pw.println("Applications Memory Usage (kB):");
13633            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13634        }
13635    }
13636
13637    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13638            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13639        boolean dumpDetails = false;
13640        boolean dumpFullDetails = false;
13641        boolean dumpDalvik = false;
13642        boolean oomOnly = false;
13643        boolean isCompact = false;
13644        boolean localOnly = false;
13645
13646        int opti = 0;
13647        while (opti < args.length) {
13648            String opt = args[opti];
13649            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13650                break;
13651            }
13652            opti++;
13653            if ("-a".equals(opt)) {
13654                dumpDetails = true;
13655                dumpFullDetails = true;
13656                dumpDalvik = true;
13657            } else if ("-d".equals(opt)) {
13658                dumpDalvik = true;
13659            } else if ("-c".equals(opt)) {
13660                isCompact = true;
13661            } else if ("--oom".equals(opt)) {
13662                oomOnly = true;
13663            } else if ("--local".equals(opt)) {
13664                localOnly = true;
13665            } else if ("-h".equals(opt)) {
13666                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13667                pw.println("  -a: include all available information for each process.");
13668                pw.println("  -d: include dalvik details when dumping process details.");
13669                pw.println("  -c: dump in a compact machine-parseable representation.");
13670                pw.println("  --oom: only show processes organized by oom adj.");
13671                pw.println("  --local: only collect details locally, don't call process.");
13672                pw.println("If [process] is specified it can be the name or ");
13673                pw.println("pid of a specific process to dump.");
13674                return;
13675            } else {
13676                pw.println("Unknown argument: " + opt + "; use -h for help");
13677            }
13678        }
13679
13680        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13681        long uptime = SystemClock.uptimeMillis();
13682        long realtime = SystemClock.elapsedRealtime();
13683        final long[] tmpLong = new long[1];
13684
13685        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13686        if (procs == null) {
13687            // No Java processes.  Maybe they want to print a native process.
13688            if (args != null && args.length > opti
13689                    && args[opti].charAt(0) != '-') {
13690                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13691                        = new ArrayList<ProcessCpuTracker.Stats>();
13692                updateCpuStatsNow();
13693                int findPid = -1;
13694                try {
13695                    findPid = Integer.parseInt(args[opti]);
13696                } catch (NumberFormatException e) {
13697                }
13698                synchronized (mProcessCpuThread) {
13699                    final int N = mProcessCpuTracker.countStats();
13700                    for (int i=0; i<N; i++) {
13701                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13702                        if (st.pid == findPid || (st.baseName != null
13703                                && st.baseName.equals(args[opti]))) {
13704                            nativeProcs.add(st);
13705                        }
13706                    }
13707                }
13708                if (nativeProcs.size() > 0) {
13709                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13710                            isCompact);
13711                    Debug.MemoryInfo mi = null;
13712                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13713                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13714                        final int pid = r.pid;
13715                        if (!isCheckinRequest && dumpDetails) {
13716                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13717                        }
13718                        if (mi == null) {
13719                            mi = new Debug.MemoryInfo();
13720                        }
13721                        if (dumpDetails || (!brief && !oomOnly)) {
13722                            Debug.getMemoryInfo(pid, mi);
13723                        } else {
13724                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13725                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13726                        }
13727                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13728                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13729                        if (isCheckinRequest) {
13730                            pw.println();
13731                        }
13732                    }
13733                    return;
13734                }
13735            }
13736            pw.println("No process found for: " + args[opti]);
13737            return;
13738        }
13739
13740        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13741            dumpDetails = true;
13742        }
13743
13744        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13745
13746        String[] innerArgs = new String[args.length-opti];
13747        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13748
13749        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13750        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13751        long nativePss=0, dalvikPss=0, otherPss=0;
13752        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13753
13754        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13755        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13756                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13757
13758        long totalPss = 0;
13759        long cachedPss = 0;
13760
13761        Debug.MemoryInfo mi = null;
13762        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13763            final ProcessRecord r = procs.get(i);
13764            final IApplicationThread thread;
13765            final int pid;
13766            final int oomAdj;
13767            final boolean hasActivities;
13768            synchronized (this) {
13769                thread = r.thread;
13770                pid = r.pid;
13771                oomAdj = r.getSetAdjWithServices();
13772                hasActivities = r.activities.size() > 0;
13773            }
13774            if (thread != null) {
13775                if (!isCheckinRequest && dumpDetails) {
13776                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13777                }
13778                if (mi == null) {
13779                    mi = new Debug.MemoryInfo();
13780                }
13781                if (dumpDetails || (!brief && !oomOnly)) {
13782                    Debug.getMemoryInfo(pid, mi);
13783                } else {
13784                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13785                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13786                }
13787                if (dumpDetails) {
13788                    if (localOnly) {
13789                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13790                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13791                        if (isCheckinRequest) {
13792                            pw.println();
13793                        }
13794                    } else {
13795                        try {
13796                            pw.flush();
13797                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13798                                    dumpDalvik, innerArgs);
13799                        } catch (RemoteException e) {
13800                            if (!isCheckinRequest) {
13801                                pw.println("Got RemoteException!");
13802                                pw.flush();
13803                            }
13804                        }
13805                    }
13806                }
13807
13808                final long myTotalPss = mi.getTotalPss();
13809                final long myTotalUss = mi.getTotalUss();
13810
13811                synchronized (this) {
13812                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13813                        // Record this for posterity if the process has been stable.
13814                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13815                    }
13816                }
13817
13818                if (!isCheckinRequest && mi != null) {
13819                    totalPss += myTotalPss;
13820                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13821                            (hasActivities ? " / activities)" : ")"),
13822                            r.processName, myTotalPss, pid, hasActivities);
13823                    procMems.add(pssItem);
13824                    procMemsMap.put(pid, pssItem);
13825
13826                    nativePss += mi.nativePss;
13827                    dalvikPss += mi.dalvikPss;
13828                    otherPss += mi.otherPss;
13829                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13830                        long mem = mi.getOtherPss(j);
13831                        miscPss[j] += mem;
13832                        otherPss -= mem;
13833                    }
13834
13835                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13836                        cachedPss += myTotalPss;
13837                    }
13838
13839                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13840                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13841                                || oomIndex == (oomPss.length-1)) {
13842                            oomPss[oomIndex] += myTotalPss;
13843                            if (oomProcs[oomIndex] == null) {
13844                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13845                            }
13846                            oomProcs[oomIndex].add(pssItem);
13847                            break;
13848                        }
13849                    }
13850                }
13851            }
13852        }
13853
13854        long nativeProcTotalPss = 0;
13855
13856        if (!isCheckinRequest && procs.size() > 1) {
13857            // If we are showing aggregations, also look for native processes to
13858            // include so that our aggregations are more accurate.
13859            updateCpuStatsNow();
13860            synchronized (mProcessCpuThread) {
13861                final int N = mProcessCpuTracker.countStats();
13862                for (int i=0; i<N; i++) {
13863                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13864                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13865                        if (mi == null) {
13866                            mi = new Debug.MemoryInfo();
13867                        }
13868                        if (!brief && !oomOnly) {
13869                            Debug.getMemoryInfo(st.pid, mi);
13870                        } else {
13871                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13872                            mi.nativePrivateDirty = (int)tmpLong[0];
13873                        }
13874
13875                        final long myTotalPss = mi.getTotalPss();
13876                        totalPss += myTotalPss;
13877                        nativeProcTotalPss += myTotalPss;
13878
13879                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13880                                st.name, myTotalPss, st.pid, false);
13881                        procMems.add(pssItem);
13882
13883                        nativePss += mi.nativePss;
13884                        dalvikPss += mi.dalvikPss;
13885                        otherPss += mi.otherPss;
13886                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13887                            long mem = mi.getOtherPss(j);
13888                            miscPss[j] += mem;
13889                            otherPss -= mem;
13890                        }
13891                        oomPss[0] += myTotalPss;
13892                        if (oomProcs[0] == null) {
13893                            oomProcs[0] = new ArrayList<MemItem>();
13894                        }
13895                        oomProcs[0].add(pssItem);
13896                    }
13897                }
13898            }
13899
13900            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13901
13902            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13903            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13904            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13905            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13906                String label = Debug.MemoryInfo.getOtherLabel(j);
13907                catMems.add(new MemItem(label, label, miscPss[j], j));
13908            }
13909
13910            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13911            for (int j=0; j<oomPss.length; j++) {
13912                if (oomPss[j] != 0) {
13913                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13914                            : DUMP_MEM_OOM_LABEL[j];
13915                    MemItem item = new MemItem(label, label, oomPss[j],
13916                            DUMP_MEM_OOM_ADJ[j]);
13917                    item.subitems = oomProcs[j];
13918                    oomMems.add(item);
13919                }
13920            }
13921
13922            if (!brief && !oomOnly && !isCompact) {
13923                pw.println();
13924                pw.println("Total PSS by process:");
13925                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13926                pw.println();
13927            }
13928            if (!isCompact) {
13929                pw.println("Total PSS by OOM adjustment:");
13930            }
13931            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13932            if (!brief && !oomOnly) {
13933                PrintWriter out = categoryPw != null ? categoryPw : pw;
13934                if (!isCompact) {
13935                    out.println();
13936                    out.println("Total PSS by category:");
13937                }
13938                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13939            }
13940            if (!isCompact) {
13941                pw.println();
13942            }
13943            MemInfoReader memInfo = new MemInfoReader();
13944            memInfo.readMemInfo();
13945            if (nativeProcTotalPss > 0) {
13946                synchronized (this) {
13947                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13948                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13949                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13950                            nativeProcTotalPss);
13951                }
13952            }
13953            if (!brief) {
13954                if (!isCompact) {
13955                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13956                    pw.print(" kB (status ");
13957                    switch (mLastMemoryLevel) {
13958                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13959                            pw.println("normal)");
13960                            break;
13961                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13962                            pw.println("moderate)");
13963                            break;
13964                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13965                            pw.println("low)");
13966                            break;
13967                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13968                            pw.println("critical)");
13969                            break;
13970                        default:
13971                            pw.print(mLastMemoryLevel);
13972                            pw.println(")");
13973                            break;
13974                    }
13975                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13976                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13977                            pw.print(cachedPss); pw.print(" cached pss + ");
13978                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13979                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13980                } else {
13981                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13982                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13983                            + memInfo.getFreeSizeKb()); pw.print(",");
13984                    pw.println(totalPss - cachedPss);
13985                }
13986            }
13987            if (!isCompact) {
13988                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13989                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13990                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13991                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13992                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13993                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13994                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13995                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13996                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13997                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13998                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13999            }
14000            if (!brief) {
14001                if (memInfo.getZramTotalSizeKb() != 0) {
14002                    if (!isCompact) {
14003                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14004                                pw.print(" kB physical used for ");
14005                                pw.print(memInfo.getSwapTotalSizeKb()
14006                                        - memInfo.getSwapFreeSizeKb());
14007                                pw.print(" kB in swap (");
14008                                pw.print(memInfo.getSwapTotalSizeKb());
14009                                pw.println(" kB total swap)");
14010                    } else {
14011                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14012                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14013                                pw.println(memInfo.getSwapFreeSizeKb());
14014                    }
14015                }
14016                final int[] SINGLE_LONG_FORMAT = new int[] {
14017                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14018                };
14019                long[] longOut = new long[1];
14020                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14021                        SINGLE_LONG_FORMAT, null, longOut, null);
14022                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14023                longOut[0] = 0;
14024                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14025                        SINGLE_LONG_FORMAT, null, longOut, null);
14026                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14027                longOut[0] = 0;
14028                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14029                        SINGLE_LONG_FORMAT, null, longOut, null);
14030                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14031                longOut[0] = 0;
14032                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14033                        SINGLE_LONG_FORMAT, null, longOut, null);
14034                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14035                if (!isCompact) {
14036                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14037                        pw.print("      KSM: "); pw.print(sharing);
14038                                pw.print(" kB saved from shared ");
14039                                pw.print(shared); pw.println(" kB");
14040                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14041                                pw.print(voltile); pw.println(" kB volatile");
14042                    }
14043                    pw.print("   Tuning: ");
14044                    pw.print(ActivityManager.staticGetMemoryClass());
14045                    pw.print(" (large ");
14046                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14047                    pw.print("), oom ");
14048                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14049                    pw.print(" kB");
14050                    pw.print(", restore limit ");
14051                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14052                    pw.print(" kB");
14053                    if (ActivityManager.isLowRamDeviceStatic()) {
14054                        pw.print(" (low-ram)");
14055                    }
14056                    if (ActivityManager.isHighEndGfx()) {
14057                        pw.print(" (high-end-gfx)");
14058                    }
14059                    pw.println();
14060                } else {
14061                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14062                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14063                    pw.println(voltile);
14064                    pw.print("tuning,");
14065                    pw.print(ActivityManager.staticGetMemoryClass());
14066                    pw.print(',');
14067                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14068                    pw.print(',');
14069                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14070                    if (ActivityManager.isLowRamDeviceStatic()) {
14071                        pw.print(",low-ram");
14072                    }
14073                    if (ActivityManager.isHighEndGfx()) {
14074                        pw.print(",high-end-gfx");
14075                    }
14076                    pw.println();
14077                }
14078            }
14079        }
14080    }
14081
14082    /**
14083     * Searches array of arguments for the specified string
14084     * @param args array of argument strings
14085     * @param value value to search for
14086     * @return true if the value is contained in the array
14087     */
14088    private static boolean scanArgs(String[] args, String value) {
14089        if (args != null) {
14090            for (String arg : args) {
14091                if (value.equals(arg)) {
14092                    return true;
14093                }
14094            }
14095        }
14096        return false;
14097    }
14098
14099    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14100            ContentProviderRecord cpr, boolean always) {
14101        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14102
14103        if (!inLaunching || always) {
14104            synchronized (cpr) {
14105                cpr.launchingApp = null;
14106                cpr.notifyAll();
14107            }
14108            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14109            String names[] = cpr.info.authority.split(";");
14110            for (int j = 0; j < names.length; j++) {
14111                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14112            }
14113        }
14114
14115        for (int i=0; i<cpr.connections.size(); i++) {
14116            ContentProviderConnection conn = cpr.connections.get(i);
14117            if (conn.waiting) {
14118                // If this connection is waiting for the provider, then we don't
14119                // need to mess with its process unless we are always removing
14120                // or for some reason the provider is not currently launching.
14121                if (inLaunching && !always) {
14122                    continue;
14123                }
14124            }
14125            ProcessRecord capp = conn.client;
14126            conn.dead = true;
14127            if (conn.stableCount > 0) {
14128                if (!capp.persistent && capp.thread != null
14129                        && capp.pid != 0
14130                        && capp.pid != MY_PID) {
14131                    capp.kill("depends on provider "
14132                            + cpr.name.flattenToShortString()
14133                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14134                }
14135            } else if (capp.thread != null && conn.provider.provider != null) {
14136                try {
14137                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14138                } catch (RemoteException e) {
14139                }
14140                // In the protocol here, we don't expect the client to correctly
14141                // clean up this connection, we'll just remove it.
14142                cpr.connections.remove(i);
14143                conn.client.conProviders.remove(conn);
14144            }
14145        }
14146
14147        if (inLaunching && always) {
14148            mLaunchingProviders.remove(cpr);
14149        }
14150        return inLaunching;
14151    }
14152
14153    /**
14154     * Main code for cleaning up a process when it has gone away.  This is
14155     * called both as a result of the process dying, or directly when stopping
14156     * a process when running in single process mode.
14157     */
14158    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14159            boolean restarting, boolean allowRestart, int index) {
14160        if (index >= 0) {
14161            removeLruProcessLocked(app);
14162            ProcessList.remove(app.pid);
14163        }
14164
14165        mProcessesToGc.remove(app);
14166        mPendingPssProcesses.remove(app);
14167
14168        // Dismiss any open dialogs.
14169        if (app.crashDialog != null && !app.forceCrashReport) {
14170            app.crashDialog.dismiss();
14171            app.crashDialog = null;
14172        }
14173        if (app.anrDialog != null) {
14174            app.anrDialog.dismiss();
14175            app.anrDialog = null;
14176        }
14177        if (app.waitDialog != null) {
14178            app.waitDialog.dismiss();
14179            app.waitDialog = null;
14180        }
14181
14182        app.crashing = false;
14183        app.notResponding = false;
14184
14185        app.resetPackageList(mProcessStats);
14186        app.unlinkDeathRecipient();
14187        app.makeInactive(mProcessStats);
14188        app.waitingToKill = null;
14189        app.forcingToForeground = null;
14190        updateProcessForegroundLocked(app, false, false);
14191        app.foregroundActivities = false;
14192        app.hasShownUi = false;
14193        app.treatLikeActivity = false;
14194        app.hasAboveClient = false;
14195        app.hasClientActivities = false;
14196
14197        mServices.killServicesLocked(app, allowRestart);
14198
14199        boolean restart = false;
14200
14201        // Remove published content providers.
14202        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14203            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14204            final boolean always = app.bad || !allowRestart;
14205            if (removeDyingProviderLocked(app, cpr, always) || always) {
14206                // We left the provider in the launching list, need to
14207                // restart it.
14208                restart = true;
14209            }
14210
14211            cpr.provider = null;
14212            cpr.proc = null;
14213        }
14214        app.pubProviders.clear();
14215
14216        // Take care of any launching providers waiting for this process.
14217        if (checkAppInLaunchingProvidersLocked(app, false)) {
14218            restart = true;
14219        }
14220
14221        // Unregister from connected content providers.
14222        if (!app.conProviders.isEmpty()) {
14223            for (int i=0; i<app.conProviders.size(); i++) {
14224                ContentProviderConnection conn = app.conProviders.get(i);
14225                conn.provider.connections.remove(conn);
14226            }
14227            app.conProviders.clear();
14228        }
14229
14230        // At this point there may be remaining entries in mLaunchingProviders
14231        // where we were the only one waiting, so they are no longer of use.
14232        // Look for these and clean up if found.
14233        // XXX Commented out for now.  Trying to figure out a way to reproduce
14234        // the actual situation to identify what is actually going on.
14235        if (false) {
14236            for (int i=0; i<mLaunchingProviders.size(); i++) {
14237                ContentProviderRecord cpr = (ContentProviderRecord)
14238                        mLaunchingProviders.get(i);
14239                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14240                    synchronized (cpr) {
14241                        cpr.launchingApp = null;
14242                        cpr.notifyAll();
14243                    }
14244                }
14245            }
14246        }
14247
14248        skipCurrentReceiverLocked(app);
14249
14250        // Unregister any receivers.
14251        for (int i=app.receivers.size()-1; i>=0; i--) {
14252            removeReceiverLocked(app.receivers.valueAt(i));
14253        }
14254        app.receivers.clear();
14255
14256        // If the app is undergoing backup, tell the backup manager about it
14257        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14258            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14259                    + mBackupTarget.appInfo + " died during backup");
14260            try {
14261                IBackupManager bm = IBackupManager.Stub.asInterface(
14262                        ServiceManager.getService(Context.BACKUP_SERVICE));
14263                bm.agentDisconnected(app.info.packageName);
14264            } catch (RemoteException e) {
14265                // can't happen; backup manager is local
14266            }
14267        }
14268
14269        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14270            ProcessChangeItem item = mPendingProcessChanges.get(i);
14271            if (item.pid == app.pid) {
14272                mPendingProcessChanges.remove(i);
14273                mAvailProcessChanges.add(item);
14274            }
14275        }
14276        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14277
14278        // If the caller is restarting this app, then leave it in its
14279        // current lists and let the caller take care of it.
14280        if (restarting) {
14281            return;
14282        }
14283
14284        if (!app.persistent || app.isolated) {
14285            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14286                    "Removing non-persistent process during cleanup: " + app);
14287            mProcessNames.remove(app.processName, app.uid);
14288            mIsolatedProcesses.remove(app.uid);
14289            if (mHeavyWeightProcess == app) {
14290                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14291                        mHeavyWeightProcess.userId, 0));
14292                mHeavyWeightProcess = null;
14293            }
14294        } else if (!app.removed) {
14295            // This app is persistent, so we need to keep its record around.
14296            // If it is not already on the pending app list, add it there
14297            // and start a new process for it.
14298            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14299                mPersistentStartingProcesses.add(app);
14300                restart = true;
14301            }
14302        }
14303        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14304                "Clean-up removing on hold: " + app);
14305        mProcessesOnHold.remove(app);
14306
14307        if (app == mHomeProcess) {
14308            mHomeProcess = null;
14309        }
14310        if (app == mPreviousProcess) {
14311            mPreviousProcess = null;
14312        }
14313
14314        if (restart && !app.isolated) {
14315            // We have components that still need to be running in the
14316            // process, so re-launch it.
14317            mProcessNames.put(app.processName, app.uid, app);
14318            startProcessLocked(app, "restart", app.processName);
14319        } else if (app.pid > 0 && app.pid != MY_PID) {
14320            // Goodbye!
14321            boolean removed;
14322            synchronized (mPidsSelfLocked) {
14323                mPidsSelfLocked.remove(app.pid);
14324                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14325            }
14326            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14327            if (app.isolated) {
14328                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14329            }
14330            app.setPid(0);
14331        }
14332    }
14333
14334    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14335        // Look through the content providers we are waiting to have launched,
14336        // and if any run in this process then either schedule a restart of
14337        // the process or kill the client waiting for it if this process has
14338        // gone bad.
14339        int NL = mLaunchingProviders.size();
14340        boolean restart = false;
14341        for (int i=0; i<NL; i++) {
14342            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14343            if (cpr.launchingApp == app) {
14344                if (!alwaysBad && !app.bad) {
14345                    restart = true;
14346                } else {
14347                    removeDyingProviderLocked(app, cpr, true);
14348                    // cpr should have been removed from mLaunchingProviders
14349                    NL = mLaunchingProviders.size();
14350                    i--;
14351                }
14352            }
14353        }
14354        return restart;
14355    }
14356
14357    // =========================================================
14358    // SERVICES
14359    // =========================================================
14360
14361    @Override
14362    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14363            int flags) {
14364        enforceNotIsolatedCaller("getServices");
14365        synchronized (this) {
14366            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14367        }
14368    }
14369
14370    @Override
14371    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14372        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14373        synchronized (this) {
14374            return mServices.getRunningServiceControlPanelLocked(name);
14375        }
14376    }
14377
14378    @Override
14379    public ComponentName startService(IApplicationThread caller, Intent service,
14380            String resolvedType, int userId) {
14381        enforceNotIsolatedCaller("startService");
14382        // Refuse possible leaked file descriptors
14383        if (service != null && service.hasFileDescriptors() == true) {
14384            throw new IllegalArgumentException("File descriptors passed in Intent");
14385        }
14386
14387        if (DEBUG_SERVICE)
14388            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14389        synchronized(this) {
14390            final int callingPid = Binder.getCallingPid();
14391            final int callingUid = Binder.getCallingUid();
14392            final long origId = Binder.clearCallingIdentity();
14393            ComponentName res = mServices.startServiceLocked(caller, service,
14394                    resolvedType, callingPid, callingUid, userId);
14395            Binder.restoreCallingIdentity(origId);
14396            return res;
14397        }
14398    }
14399
14400    ComponentName startServiceInPackage(int uid,
14401            Intent service, String resolvedType, int userId) {
14402        synchronized(this) {
14403            if (DEBUG_SERVICE)
14404                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14405            final long origId = Binder.clearCallingIdentity();
14406            ComponentName res = mServices.startServiceLocked(null, service,
14407                    resolvedType, -1, uid, userId);
14408            Binder.restoreCallingIdentity(origId);
14409            return res;
14410        }
14411    }
14412
14413    @Override
14414    public int stopService(IApplicationThread caller, Intent service,
14415            String resolvedType, int userId) {
14416        enforceNotIsolatedCaller("stopService");
14417        // Refuse possible leaked file descriptors
14418        if (service != null && service.hasFileDescriptors() == true) {
14419            throw new IllegalArgumentException("File descriptors passed in Intent");
14420        }
14421
14422        synchronized(this) {
14423            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14424        }
14425    }
14426
14427    @Override
14428    public IBinder peekService(Intent service, String resolvedType) {
14429        enforceNotIsolatedCaller("peekService");
14430        // Refuse possible leaked file descriptors
14431        if (service != null && service.hasFileDescriptors() == true) {
14432            throw new IllegalArgumentException("File descriptors passed in Intent");
14433        }
14434        synchronized(this) {
14435            return mServices.peekServiceLocked(service, resolvedType);
14436        }
14437    }
14438
14439    @Override
14440    public boolean stopServiceToken(ComponentName className, IBinder token,
14441            int startId) {
14442        synchronized(this) {
14443            return mServices.stopServiceTokenLocked(className, token, startId);
14444        }
14445    }
14446
14447    @Override
14448    public void setServiceForeground(ComponentName className, IBinder token,
14449            int id, Notification notification, boolean removeNotification) {
14450        synchronized(this) {
14451            mServices.setServiceForegroundLocked(className, token, id, notification,
14452                    removeNotification);
14453        }
14454    }
14455
14456    @Override
14457    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14458            boolean requireFull, String name, String callerPackage) {
14459        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14460                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14461    }
14462
14463    int unsafeConvertIncomingUser(int userId) {
14464        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14465                ? mCurrentUserId : userId;
14466    }
14467
14468    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14469            int allowMode, String name, String callerPackage) {
14470        final int callingUserId = UserHandle.getUserId(callingUid);
14471        if (callingUserId == userId) {
14472            return userId;
14473        }
14474
14475        // Note that we may be accessing mCurrentUserId outside of a lock...
14476        // shouldn't be a big deal, if this is being called outside
14477        // of a locked context there is intrinsically a race with
14478        // the value the caller will receive and someone else changing it.
14479        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14480        // we will switch to the calling user if access to the current user fails.
14481        int targetUserId = unsafeConvertIncomingUser(userId);
14482
14483        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14484            final boolean allow;
14485            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14486                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14487                // If the caller has this permission, they always pass go.  And collect $200.
14488                allow = true;
14489            } else if (allowMode == ALLOW_FULL_ONLY) {
14490                // We require full access, sucks to be you.
14491                allow = false;
14492            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14493                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14494                // If the caller does not have either permission, they are always doomed.
14495                allow = false;
14496            } else if (allowMode == ALLOW_NON_FULL) {
14497                // We are blanket allowing non-full access, you lucky caller!
14498                allow = true;
14499            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14500                // We may or may not allow this depending on whether the two users are
14501                // in the same profile.
14502                synchronized (mUserProfileGroupIdsSelfLocked) {
14503                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14504                            UserInfo.NO_PROFILE_GROUP_ID);
14505                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14506                            UserInfo.NO_PROFILE_GROUP_ID);
14507                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14508                            && callingProfile == targetProfile;
14509                }
14510            } else {
14511                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14512            }
14513            if (!allow) {
14514                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14515                    // In this case, they would like to just execute as their
14516                    // owner user instead of failing.
14517                    targetUserId = callingUserId;
14518                } else {
14519                    StringBuilder builder = new StringBuilder(128);
14520                    builder.append("Permission Denial: ");
14521                    builder.append(name);
14522                    if (callerPackage != null) {
14523                        builder.append(" from ");
14524                        builder.append(callerPackage);
14525                    }
14526                    builder.append(" asks to run as user ");
14527                    builder.append(userId);
14528                    builder.append(" but is calling from user ");
14529                    builder.append(UserHandle.getUserId(callingUid));
14530                    builder.append("; this requires ");
14531                    builder.append(INTERACT_ACROSS_USERS_FULL);
14532                    if (allowMode != ALLOW_FULL_ONLY) {
14533                        builder.append(" or ");
14534                        builder.append(INTERACT_ACROSS_USERS);
14535                    }
14536                    String msg = builder.toString();
14537                    Slog.w(TAG, msg);
14538                    throw new SecurityException(msg);
14539                }
14540            }
14541        }
14542        if (!allowAll && targetUserId < 0) {
14543            throw new IllegalArgumentException(
14544                    "Call does not support special user #" + targetUserId);
14545        }
14546        return targetUserId;
14547    }
14548
14549    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14550            String className, int flags) {
14551        boolean result = false;
14552        // For apps that don't have pre-defined UIDs, check for permission
14553        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14554            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14555                if (ActivityManager.checkUidPermission(
14556                        INTERACT_ACROSS_USERS,
14557                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14558                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14559                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14560                            + " requests FLAG_SINGLE_USER, but app does not hold "
14561                            + INTERACT_ACROSS_USERS;
14562                    Slog.w(TAG, msg);
14563                    throw new SecurityException(msg);
14564                }
14565                // Permission passed
14566                result = true;
14567            }
14568        } else if ("system".equals(componentProcessName)) {
14569            result = true;
14570        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14571                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14572            // Phone app is allowed to export singleuser providers.
14573            result = true;
14574        } else {
14575            // App with pre-defined UID, check if it's a persistent app
14576            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14577        }
14578        if (DEBUG_MU) {
14579            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14580                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14581        }
14582        return result;
14583    }
14584
14585    /**
14586     * Checks to see if the caller is in the same app as the singleton
14587     * component, or the component is in a special app. It allows special apps
14588     * to export singleton components but prevents exporting singleton
14589     * components for regular apps.
14590     */
14591    boolean isValidSingletonCall(int callingUid, int componentUid) {
14592        int componentAppId = UserHandle.getAppId(componentUid);
14593        return UserHandle.isSameApp(callingUid, componentUid)
14594                || componentAppId == Process.SYSTEM_UID
14595                || componentAppId == Process.PHONE_UID
14596                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14597                        == PackageManager.PERMISSION_GRANTED;
14598    }
14599
14600    public int bindService(IApplicationThread caller, IBinder token,
14601            Intent service, String resolvedType,
14602            IServiceConnection connection, int flags, int userId) {
14603        enforceNotIsolatedCaller("bindService");
14604        // Refuse possible leaked file descriptors
14605        if (service != null && service.hasFileDescriptors() == true) {
14606            throw new IllegalArgumentException("File descriptors passed in Intent");
14607        }
14608
14609        synchronized(this) {
14610            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14611                    connection, flags, userId);
14612        }
14613    }
14614
14615    public boolean unbindService(IServiceConnection connection) {
14616        synchronized (this) {
14617            return mServices.unbindServiceLocked(connection);
14618        }
14619    }
14620
14621    public void publishService(IBinder token, Intent intent, IBinder service) {
14622        // Refuse possible leaked file descriptors
14623        if (intent != null && intent.hasFileDescriptors() == true) {
14624            throw new IllegalArgumentException("File descriptors passed in Intent");
14625        }
14626
14627        synchronized(this) {
14628            if (!(token instanceof ServiceRecord)) {
14629                throw new IllegalArgumentException("Invalid service token");
14630            }
14631            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14632        }
14633    }
14634
14635    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14636        // Refuse possible leaked file descriptors
14637        if (intent != null && intent.hasFileDescriptors() == true) {
14638            throw new IllegalArgumentException("File descriptors passed in Intent");
14639        }
14640
14641        synchronized(this) {
14642            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14643        }
14644    }
14645
14646    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14647        synchronized(this) {
14648            if (!(token instanceof ServiceRecord)) {
14649                throw new IllegalArgumentException("Invalid service token");
14650            }
14651            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14652        }
14653    }
14654
14655    // =========================================================
14656    // BACKUP AND RESTORE
14657    // =========================================================
14658
14659    // Cause the target app to be launched if necessary and its backup agent
14660    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14661    // activity manager to announce its creation.
14662    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14663        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14664        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14665
14666        synchronized(this) {
14667            // !!! TODO: currently no check here that we're already bound
14668            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14669            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14670            synchronized (stats) {
14671                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14672            }
14673
14674            // Backup agent is now in use, its package can't be stopped.
14675            try {
14676                AppGlobals.getPackageManager().setPackageStoppedState(
14677                        app.packageName, false, UserHandle.getUserId(app.uid));
14678            } catch (RemoteException e) {
14679            } catch (IllegalArgumentException e) {
14680                Slog.w(TAG, "Failed trying to unstop package "
14681                        + app.packageName + ": " + e);
14682            }
14683
14684            BackupRecord r = new BackupRecord(ss, app, backupMode);
14685            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14686                    ? new ComponentName(app.packageName, app.backupAgentName)
14687                    : new ComponentName("android", "FullBackupAgent");
14688            // startProcessLocked() returns existing proc's record if it's already running
14689            ProcessRecord proc = startProcessLocked(app.processName, app,
14690                    false, 0, "backup", hostingName, false, false, false);
14691            if (proc == null) {
14692                Slog.e(TAG, "Unable to start backup agent process " + r);
14693                return false;
14694            }
14695
14696            r.app = proc;
14697            mBackupTarget = r;
14698            mBackupAppName = app.packageName;
14699
14700            // Try not to kill the process during backup
14701            updateOomAdjLocked(proc);
14702
14703            // If the process is already attached, schedule the creation of the backup agent now.
14704            // If it is not yet live, this will be done when it attaches to the framework.
14705            if (proc.thread != null) {
14706                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14707                try {
14708                    proc.thread.scheduleCreateBackupAgent(app,
14709                            compatibilityInfoForPackageLocked(app), backupMode);
14710                } catch (RemoteException e) {
14711                    // Will time out on the backup manager side
14712                }
14713            } else {
14714                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14715            }
14716            // Invariants: at this point, the target app process exists and the application
14717            // is either already running or in the process of coming up.  mBackupTarget and
14718            // mBackupAppName describe the app, so that when it binds back to the AM we
14719            // know that it's scheduled for a backup-agent operation.
14720        }
14721
14722        return true;
14723    }
14724
14725    @Override
14726    public void clearPendingBackup() {
14727        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14728        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14729
14730        synchronized (this) {
14731            mBackupTarget = null;
14732            mBackupAppName = null;
14733        }
14734    }
14735
14736    // A backup agent has just come up
14737    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14738        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14739                + " = " + agent);
14740
14741        synchronized(this) {
14742            if (!agentPackageName.equals(mBackupAppName)) {
14743                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14744                return;
14745            }
14746        }
14747
14748        long oldIdent = Binder.clearCallingIdentity();
14749        try {
14750            IBackupManager bm = IBackupManager.Stub.asInterface(
14751                    ServiceManager.getService(Context.BACKUP_SERVICE));
14752            bm.agentConnected(agentPackageName, agent);
14753        } catch (RemoteException e) {
14754            // can't happen; the backup manager service is local
14755        } catch (Exception e) {
14756            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14757            e.printStackTrace();
14758        } finally {
14759            Binder.restoreCallingIdentity(oldIdent);
14760        }
14761    }
14762
14763    // done with this agent
14764    public void unbindBackupAgent(ApplicationInfo appInfo) {
14765        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14766        if (appInfo == null) {
14767            Slog.w(TAG, "unbind backup agent for null app");
14768            return;
14769        }
14770
14771        synchronized(this) {
14772            try {
14773                if (mBackupAppName == null) {
14774                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14775                    return;
14776                }
14777
14778                if (!mBackupAppName.equals(appInfo.packageName)) {
14779                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14780                    return;
14781                }
14782
14783                // Not backing this app up any more; reset its OOM adjustment
14784                final ProcessRecord proc = mBackupTarget.app;
14785                updateOomAdjLocked(proc);
14786
14787                // If the app crashed during backup, 'thread' will be null here
14788                if (proc.thread != null) {
14789                    try {
14790                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14791                                compatibilityInfoForPackageLocked(appInfo));
14792                    } catch (Exception e) {
14793                        Slog.e(TAG, "Exception when unbinding backup agent:");
14794                        e.printStackTrace();
14795                    }
14796                }
14797            } finally {
14798                mBackupTarget = null;
14799                mBackupAppName = null;
14800            }
14801        }
14802    }
14803    // =========================================================
14804    // BROADCASTS
14805    // =========================================================
14806
14807    private final List getStickiesLocked(String action, IntentFilter filter,
14808            List cur, int userId) {
14809        final ContentResolver resolver = mContext.getContentResolver();
14810        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14811        if (stickies == null) {
14812            return cur;
14813        }
14814        final ArrayList<Intent> list = stickies.get(action);
14815        if (list == null) {
14816            return cur;
14817        }
14818        int N = list.size();
14819        for (int i=0; i<N; i++) {
14820            Intent intent = list.get(i);
14821            if (filter.match(resolver, intent, true, TAG) >= 0) {
14822                if (cur == null) {
14823                    cur = new ArrayList<Intent>();
14824                }
14825                cur.add(intent);
14826            }
14827        }
14828        return cur;
14829    }
14830
14831    boolean isPendingBroadcastProcessLocked(int pid) {
14832        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14833                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14834    }
14835
14836    void skipPendingBroadcastLocked(int pid) {
14837            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14838            for (BroadcastQueue queue : mBroadcastQueues) {
14839                queue.skipPendingBroadcastLocked(pid);
14840            }
14841    }
14842
14843    // The app just attached; send any pending broadcasts that it should receive
14844    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14845        boolean didSomething = false;
14846        for (BroadcastQueue queue : mBroadcastQueues) {
14847            didSomething |= queue.sendPendingBroadcastsLocked(app);
14848        }
14849        return didSomething;
14850    }
14851
14852    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14853            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14854        enforceNotIsolatedCaller("registerReceiver");
14855        int callingUid;
14856        int callingPid;
14857        synchronized(this) {
14858            ProcessRecord callerApp = null;
14859            if (caller != null) {
14860                callerApp = getRecordForAppLocked(caller);
14861                if (callerApp == null) {
14862                    throw new SecurityException(
14863                            "Unable to find app for caller " + caller
14864                            + " (pid=" + Binder.getCallingPid()
14865                            + ") when registering receiver " + receiver);
14866                }
14867                if (callerApp.info.uid != Process.SYSTEM_UID &&
14868                        !callerApp.pkgList.containsKey(callerPackage) &&
14869                        !"android".equals(callerPackage)) {
14870                    throw new SecurityException("Given caller package " + callerPackage
14871                            + " is not running in process " + callerApp);
14872                }
14873                callingUid = callerApp.info.uid;
14874                callingPid = callerApp.pid;
14875            } else {
14876                callerPackage = null;
14877                callingUid = Binder.getCallingUid();
14878                callingPid = Binder.getCallingPid();
14879            }
14880
14881            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14882                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14883
14884            List allSticky = null;
14885
14886            // Look for any matching sticky broadcasts...
14887            Iterator actions = filter.actionsIterator();
14888            if (actions != null) {
14889                while (actions.hasNext()) {
14890                    String action = (String)actions.next();
14891                    allSticky = getStickiesLocked(action, filter, allSticky,
14892                            UserHandle.USER_ALL);
14893                    allSticky = getStickiesLocked(action, filter, allSticky,
14894                            UserHandle.getUserId(callingUid));
14895                }
14896            } else {
14897                allSticky = getStickiesLocked(null, filter, allSticky,
14898                        UserHandle.USER_ALL);
14899                allSticky = getStickiesLocked(null, filter, allSticky,
14900                        UserHandle.getUserId(callingUid));
14901            }
14902
14903            // The first sticky in the list is returned directly back to
14904            // the client.
14905            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14906
14907            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14908                    + ": " + sticky);
14909
14910            if (receiver == null) {
14911                return sticky;
14912            }
14913
14914            ReceiverList rl
14915                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14916            if (rl == null) {
14917                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14918                        userId, receiver);
14919                if (rl.app != null) {
14920                    rl.app.receivers.add(rl);
14921                } else {
14922                    try {
14923                        receiver.asBinder().linkToDeath(rl, 0);
14924                    } catch (RemoteException e) {
14925                        return sticky;
14926                    }
14927                    rl.linkedToDeath = true;
14928                }
14929                mRegisteredReceivers.put(receiver.asBinder(), rl);
14930            } else if (rl.uid != callingUid) {
14931                throw new IllegalArgumentException(
14932                        "Receiver requested to register for uid " + callingUid
14933                        + " was previously registered for uid " + rl.uid);
14934            } else if (rl.pid != callingPid) {
14935                throw new IllegalArgumentException(
14936                        "Receiver requested to register for pid " + callingPid
14937                        + " was previously registered for pid " + rl.pid);
14938            } else if (rl.userId != userId) {
14939                throw new IllegalArgumentException(
14940                        "Receiver requested to register for user " + userId
14941                        + " was previously registered for user " + rl.userId);
14942            }
14943            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14944                    permission, callingUid, userId);
14945            rl.add(bf);
14946            if (!bf.debugCheck()) {
14947                Slog.w(TAG, "==> For Dynamic broadast");
14948            }
14949            mReceiverResolver.addFilter(bf);
14950
14951            // Enqueue broadcasts for all existing stickies that match
14952            // this filter.
14953            if (allSticky != null) {
14954                ArrayList receivers = new ArrayList();
14955                receivers.add(bf);
14956
14957                int N = allSticky.size();
14958                for (int i=0; i<N; i++) {
14959                    Intent intent = (Intent)allSticky.get(i);
14960                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14961                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14962                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14963                            null, null, false, true, true, -1);
14964                    queue.enqueueParallelBroadcastLocked(r);
14965                    queue.scheduleBroadcastsLocked();
14966                }
14967            }
14968
14969            return sticky;
14970        }
14971    }
14972
14973    public void unregisterReceiver(IIntentReceiver receiver) {
14974        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14975
14976        final long origId = Binder.clearCallingIdentity();
14977        try {
14978            boolean doTrim = false;
14979
14980            synchronized(this) {
14981                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14982                if (rl != null) {
14983                    if (rl.curBroadcast != null) {
14984                        BroadcastRecord r = rl.curBroadcast;
14985                        final boolean doNext = finishReceiverLocked(
14986                                receiver.asBinder(), r.resultCode, r.resultData,
14987                                r.resultExtras, r.resultAbort);
14988                        if (doNext) {
14989                            doTrim = true;
14990                            r.queue.processNextBroadcast(false);
14991                        }
14992                    }
14993
14994                    if (rl.app != null) {
14995                        rl.app.receivers.remove(rl);
14996                    }
14997                    removeReceiverLocked(rl);
14998                    if (rl.linkedToDeath) {
14999                        rl.linkedToDeath = false;
15000                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15001                    }
15002                }
15003            }
15004
15005            // If we actually concluded any broadcasts, we might now be able
15006            // to trim the recipients' apps from our working set
15007            if (doTrim) {
15008                trimApplications();
15009                return;
15010            }
15011
15012        } finally {
15013            Binder.restoreCallingIdentity(origId);
15014        }
15015    }
15016
15017    void removeReceiverLocked(ReceiverList rl) {
15018        mRegisteredReceivers.remove(rl.receiver.asBinder());
15019        int N = rl.size();
15020        for (int i=0; i<N; i++) {
15021            mReceiverResolver.removeFilter(rl.get(i));
15022        }
15023    }
15024
15025    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15026        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15027            ProcessRecord r = mLruProcesses.get(i);
15028            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15029                try {
15030                    r.thread.dispatchPackageBroadcast(cmd, packages);
15031                } catch (RemoteException ex) {
15032                }
15033            }
15034        }
15035    }
15036
15037    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15038            int[] users) {
15039        List<ResolveInfo> receivers = null;
15040        try {
15041            HashSet<ComponentName> singleUserReceivers = null;
15042            boolean scannedFirstReceivers = false;
15043            for (int user : users) {
15044                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15045                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15046                if (user != 0 && newReceivers != null) {
15047                    // If this is not the primary user, we need to check for
15048                    // any receivers that should be filtered out.
15049                    for (int i=0; i<newReceivers.size(); i++) {
15050                        ResolveInfo ri = newReceivers.get(i);
15051                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15052                            newReceivers.remove(i);
15053                            i--;
15054                        }
15055                    }
15056                }
15057                if (newReceivers != null && newReceivers.size() == 0) {
15058                    newReceivers = null;
15059                }
15060                if (receivers == null) {
15061                    receivers = newReceivers;
15062                } else if (newReceivers != null) {
15063                    // We need to concatenate the additional receivers
15064                    // found with what we have do far.  This would be easy,
15065                    // but we also need to de-dup any receivers that are
15066                    // singleUser.
15067                    if (!scannedFirstReceivers) {
15068                        // Collect any single user receivers we had already retrieved.
15069                        scannedFirstReceivers = true;
15070                        for (int i=0; i<receivers.size(); i++) {
15071                            ResolveInfo ri = receivers.get(i);
15072                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15073                                ComponentName cn = new ComponentName(
15074                                        ri.activityInfo.packageName, ri.activityInfo.name);
15075                                if (singleUserReceivers == null) {
15076                                    singleUserReceivers = new HashSet<ComponentName>();
15077                                }
15078                                singleUserReceivers.add(cn);
15079                            }
15080                        }
15081                    }
15082                    // Add the new results to the existing results, tracking
15083                    // and de-dupping single user receivers.
15084                    for (int i=0; i<newReceivers.size(); i++) {
15085                        ResolveInfo ri = newReceivers.get(i);
15086                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15087                            ComponentName cn = new ComponentName(
15088                                    ri.activityInfo.packageName, ri.activityInfo.name);
15089                            if (singleUserReceivers == null) {
15090                                singleUserReceivers = new HashSet<ComponentName>();
15091                            }
15092                            if (!singleUserReceivers.contains(cn)) {
15093                                singleUserReceivers.add(cn);
15094                                receivers.add(ri);
15095                            }
15096                        } else {
15097                            receivers.add(ri);
15098                        }
15099                    }
15100                }
15101            }
15102        } catch (RemoteException ex) {
15103            // pm is in same process, this will never happen.
15104        }
15105        return receivers;
15106    }
15107
15108    private final int broadcastIntentLocked(ProcessRecord callerApp,
15109            String callerPackage, Intent intent, String resolvedType,
15110            IIntentReceiver resultTo, int resultCode, String resultData,
15111            Bundle map, String requiredPermission, int appOp,
15112            boolean ordered, boolean sticky, int callingPid, int callingUid,
15113            int userId) {
15114        intent = new Intent(intent);
15115
15116        // By default broadcasts do not go to stopped apps.
15117        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15118
15119        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15120            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15121            + " ordered=" + ordered + " userid=" + userId);
15122        if ((resultTo != null) && !ordered) {
15123            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15124        }
15125
15126        userId = handleIncomingUser(callingPid, callingUid, userId,
15127                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15128
15129        // Make sure that the user who is receiving this broadcast is started.
15130        // If not, we will just skip it.
15131
15132
15133        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15134            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15135                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15136                Slog.w(TAG, "Skipping broadcast of " + intent
15137                        + ": user " + userId + " is stopped");
15138                return ActivityManager.BROADCAST_SUCCESS;
15139            }
15140        }
15141
15142        /*
15143         * Prevent non-system code (defined here to be non-persistent
15144         * processes) from sending protected broadcasts.
15145         */
15146        int callingAppId = UserHandle.getAppId(callingUid);
15147        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15148            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15149            || callingAppId == Process.NFC_UID || callingUid == 0) {
15150            // Always okay.
15151        } else if (callerApp == null || !callerApp.persistent) {
15152            try {
15153                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15154                        intent.getAction())) {
15155                    String msg = "Permission Denial: not allowed to send broadcast "
15156                            + intent.getAction() + " from pid="
15157                            + callingPid + ", uid=" + callingUid;
15158                    Slog.w(TAG, msg);
15159                    throw new SecurityException(msg);
15160                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15161                    // Special case for compatibility: we don't want apps to send this,
15162                    // but historically it has not been protected and apps may be using it
15163                    // to poke their own app widget.  So, instead of making it protected,
15164                    // just limit it to the caller.
15165                    if (callerApp == null) {
15166                        String msg = "Permission Denial: not allowed to send broadcast "
15167                                + intent.getAction() + " from unknown caller.";
15168                        Slog.w(TAG, msg);
15169                        throw new SecurityException(msg);
15170                    } else if (intent.getComponent() != null) {
15171                        // They are good enough to send to an explicit component...  verify
15172                        // it is being sent to the calling app.
15173                        if (!intent.getComponent().getPackageName().equals(
15174                                callerApp.info.packageName)) {
15175                            String msg = "Permission Denial: not allowed to send broadcast "
15176                                    + intent.getAction() + " to "
15177                                    + intent.getComponent().getPackageName() + " from "
15178                                    + callerApp.info.packageName;
15179                            Slog.w(TAG, msg);
15180                            throw new SecurityException(msg);
15181                        }
15182                    } else {
15183                        // Limit broadcast to their own package.
15184                        intent.setPackage(callerApp.info.packageName);
15185                    }
15186                }
15187            } catch (RemoteException e) {
15188                Slog.w(TAG, "Remote exception", e);
15189                return ActivityManager.BROADCAST_SUCCESS;
15190            }
15191        }
15192
15193        // Handle special intents: if this broadcast is from the package
15194        // manager about a package being removed, we need to remove all of
15195        // its activities from the history stack.
15196        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15197                intent.getAction());
15198        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15199                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15200                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15201                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15202                || uidRemoved) {
15203            if (checkComponentPermission(
15204                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15205                    callingPid, callingUid, -1, true)
15206                    == PackageManager.PERMISSION_GRANTED) {
15207                if (uidRemoved) {
15208                    final Bundle intentExtras = intent.getExtras();
15209                    final int uid = intentExtras != null
15210                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15211                    if (uid >= 0) {
15212                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15213                        synchronized (bs) {
15214                            bs.removeUidStatsLocked(uid);
15215                        }
15216                        mAppOpsService.uidRemoved(uid);
15217                    }
15218                } else {
15219                    // If resources are unavailable just force stop all
15220                    // those packages and flush the attribute cache as well.
15221                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15222                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15223                        if (list != null && (list.length > 0)) {
15224                            for (String pkg : list) {
15225                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15226                                        "storage unmount");
15227                            }
15228                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15229                            sendPackageBroadcastLocked(
15230                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15231                        }
15232                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15233                            intent.getAction())) {
15234                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15235                    } else {
15236                        Uri data = intent.getData();
15237                        String ssp;
15238                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15239                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15240                                    intent.getAction());
15241                            boolean fullUninstall = removed &&
15242                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15243                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15244                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15245                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15246                                        false, fullUninstall, userId,
15247                                        removed ? "pkg removed" : "pkg changed");
15248                            }
15249                            if (removed) {
15250                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15251                                        new String[] {ssp}, userId);
15252                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15253                                    mAppOpsService.packageRemoved(
15254                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15255
15256                                    // Remove all permissions granted from/to this package
15257                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15258                                }
15259                            }
15260                        }
15261                    }
15262                }
15263            } else {
15264                String msg = "Permission Denial: " + intent.getAction()
15265                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15266                        + ", uid=" + callingUid + ")"
15267                        + " requires "
15268                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15269                Slog.w(TAG, msg);
15270                throw new SecurityException(msg);
15271            }
15272
15273        // Special case for adding a package: by default turn on compatibility
15274        // mode.
15275        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15276            Uri data = intent.getData();
15277            String ssp;
15278            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15279                mCompatModePackages.handlePackageAddedLocked(ssp,
15280                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15281            }
15282        }
15283
15284        /*
15285         * If this is the time zone changed action, queue up a message that will reset the timezone
15286         * of all currently running processes. This message will get queued up before the broadcast
15287         * happens.
15288         */
15289        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15290            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15291        }
15292
15293        /*
15294         * If the user set the time, let all running processes know.
15295         */
15296        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15297            final int is24Hour = intent.getBooleanExtra(
15298                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15299            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15300            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15301            synchronized (stats) {
15302                stats.noteCurrentTimeChangedLocked();
15303            }
15304        }
15305
15306        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15307            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15308        }
15309
15310        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15311            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15312            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15313        }
15314
15315        // Add to the sticky list if requested.
15316        if (sticky) {
15317            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15318                    callingPid, callingUid)
15319                    != PackageManager.PERMISSION_GRANTED) {
15320                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15321                        + callingPid + ", uid=" + callingUid
15322                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15323                Slog.w(TAG, msg);
15324                throw new SecurityException(msg);
15325            }
15326            if (requiredPermission != null) {
15327                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15328                        + " and enforce permission " + requiredPermission);
15329                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15330            }
15331            if (intent.getComponent() != null) {
15332                throw new SecurityException(
15333                        "Sticky broadcasts can't target a specific component");
15334            }
15335            // We use userId directly here, since the "all" target is maintained
15336            // as a separate set of sticky broadcasts.
15337            if (userId != UserHandle.USER_ALL) {
15338                // But first, if this is not a broadcast to all users, then
15339                // make sure it doesn't conflict with an existing broadcast to
15340                // all users.
15341                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15342                        UserHandle.USER_ALL);
15343                if (stickies != null) {
15344                    ArrayList<Intent> list = stickies.get(intent.getAction());
15345                    if (list != null) {
15346                        int N = list.size();
15347                        int i;
15348                        for (i=0; i<N; i++) {
15349                            if (intent.filterEquals(list.get(i))) {
15350                                throw new IllegalArgumentException(
15351                                        "Sticky broadcast " + intent + " for user "
15352                                        + userId + " conflicts with existing global broadcast");
15353                            }
15354                        }
15355                    }
15356                }
15357            }
15358            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15359            if (stickies == null) {
15360                stickies = new ArrayMap<String, ArrayList<Intent>>();
15361                mStickyBroadcasts.put(userId, stickies);
15362            }
15363            ArrayList<Intent> list = stickies.get(intent.getAction());
15364            if (list == null) {
15365                list = new ArrayList<Intent>();
15366                stickies.put(intent.getAction(), list);
15367            }
15368            int N = list.size();
15369            int i;
15370            for (i=0; i<N; i++) {
15371                if (intent.filterEquals(list.get(i))) {
15372                    // This sticky already exists, replace it.
15373                    list.set(i, new Intent(intent));
15374                    break;
15375                }
15376            }
15377            if (i >= N) {
15378                list.add(new Intent(intent));
15379            }
15380        }
15381
15382        int[] users;
15383        if (userId == UserHandle.USER_ALL) {
15384            // Caller wants broadcast to go to all started users.
15385            users = mStartedUserArray;
15386        } else {
15387            // Caller wants broadcast to go to one specific user.
15388            users = new int[] {userId};
15389        }
15390
15391        // Figure out who all will receive this broadcast.
15392        List receivers = null;
15393        List<BroadcastFilter> registeredReceivers = null;
15394        // Need to resolve the intent to interested receivers...
15395        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15396                 == 0) {
15397            receivers = collectReceiverComponents(intent, resolvedType, users);
15398        }
15399        if (intent.getComponent() == null) {
15400            registeredReceivers = mReceiverResolver.queryIntent(intent,
15401                    resolvedType, false, userId);
15402        }
15403
15404        final boolean replacePending =
15405                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15406
15407        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15408                + " replacePending=" + replacePending);
15409
15410        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15411        if (!ordered && NR > 0) {
15412            // If we are not serializing this broadcast, then send the
15413            // registered receivers separately so they don't wait for the
15414            // components to be launched.
15415            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15416            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15417                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15418                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15419                    ordered, sticky, false, userId);
15420            if (DEBUG_BROADCAST) Slog.v(
15421                    TAG, "Enqueueing parallel broadcast " + r);
15422            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15423            if (!replaced) {
15424                queue.enqueueParallelBroadcastLocked(r);
15425                queue.scheduleBroadcastsLocked();
15426            }
15427            registeredReceivers = null;
15428            NR = 0;
15429        }
15430
15431        // Merge into one list.
15432        int ir = 0;
15433        if (receivers != null) {
15434            // A special case for PACKAGE_ADDED: do not allow the package
15435            // being added to see this broadcast.  This prevents them from
15436            // using this as a back door to get run as soon as they are
15437            // installed.  Maybe in the future we want to have a special install
15438            // broadcast or such for apps, but we'd like to deliberately make
15439            // this decision.
15440            String skipPackages[] = null;
15441            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15442                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15443                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15444                Uri data = intent.getData();
15445                if (data != null) {
15446                    String pkgName = data.getSchemeSpecificPart();
15447                    if (pkgName != null) {
15448                        skipPackages = new String[] { pkgName };
15449                    }
15450                }
15451            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15452                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15453            }
15454            if (skipPackages != null && (skipPackages.length > 0)) {
15455                for (String skipPackage : skipPackages) {
15456                    if (skipPackage != null) {
15457                        int NT = receivers.size();
15458                        for (int it=0; it<NT; it++) {
15459                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15460                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15461                                receivers.remove(it);
15462                                it--;
15463                                NT--;
15464                            }
15465                        }
15466                    }
15467                }
15468            }
15469
15470            int NT = receivers != null ? receivers.size() : 0;
15471            int it = 0;
15472            ResolveInfo curt = null;
15473            BroadcastFilter curr = null;
15474            while (it < NT && ir < NR) {
15475                if (curt == null) {
15476                    curt = (ResolveInfo)receivers.get(it);
15477                }
15478                if (curr == null) {
15479                    curr = registeredReceivers.get(ir);
15480                }
15481                if (curr.getPriority() >= curt.priority) {
15482                    // Insert this broadcast record into the final list.
15483                    receivers.add(it, curr);
15484                    ir++;
15485                    curr = null;
15486                    it++;
15487                    NT++;
15488                } else {
15489                    // Skip to the next ResolveInfo in the final list.
15490                    it++;
15491                    curt = null;
15492                }
15493            }
15494        }
15495        while (ir < NR) {
15496            if (receivers == null) {
15497                receivers = new ArrayList();
15498            }
15499            receivers.add(registeredReceivers.get(ir));
15500            ir++;
15501        }
15502
15503        if ((receivers != null && receivers.size() > 0)
15504                || resultTo != null) {
15505            BroadcastQueue queue = broadcastQueueForIntent(intent);
15506            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15507                    callerPackage, callingPid, callingUid, resolvedType,
15508                    requiredPermission, appOp, receivers, resultTo, resultCode,
15509                    resultData, map, ordered, sticky, false, userId);
15510            if (DEBUG_BROADCAST) Slog.v(
15511                    TAG, "Enqueueing ordered broadcast " + r
15512                    + ": prev had " + queue.mOrderedBroadcasts.size());
15513            if (DEBUG_BROADCAST) {
15514                int seq = r.intent.getIntExtra("seq", -1);
15515                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15516            }
15517            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15518            if (!replaced) {
15519                queue.enqueueOrderedBroadcastLocked(r);
15520                queue.scheduleBroadcastsLocked();
15521            }
15522        }
15523
15524        return ActivityManager.BROADCAST_SUCCESS;
15525    }
15526
15527    final Intent verifyBroadcastLocked(Intent intent) {
15528        // Refuse possible leaked file descriptors
15529        if (intent != null && intent.hasFileDescriptors() == true) {
15530            throw new IllegalArgumentException("File descriptors passed in Intent");
15531        }
15532
15533        int flags = intent.getFlags();
15534
15535        if (!mProcessesReady) {
15536            // if the caller really truly claims to know what they're doing, go
15537            // ahead and allow the broadcast without launching any receivers
15538            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15539                intent = new Intent(intent);
15540                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15541            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15542                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15543                        + " before boot completion");
15544                throw new IllegalStateException("Cannot broadcast before boot completed");
15545            }
15546        }
15547
15548        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15549            throw new IllegalArgumentException(
15550                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15551        }
15552
15553        return intent;
15554    }
15555
15556    public final int broadcastIntent(IApplicationThread caller,
15557            Intent intent, String resolvedType, IIntentReceiver resultTo,
15558            int resultCode, String resultData, Bundle map,
15559            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15560        enforceNotIsolatedCaller("broadcastIntent");
15561        synchronized(this) {
15562            intent = verifyBroadcastLocked(intent);
15563
15564            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15565            final int callingPid = Binder.getCallingPid();
15566            final int callingUid = Binder.getCallingUid();
15567            final long origId = Binder.clearCallingIdentity();
15568            int res = broadcastIntentLocked(callerApp,
15569                    callerApp != null ? callerApp.info.packageName : null,
15570                    intent, resolvedType, resultTo,
15571                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15572                    callingPid, callingUid, userId);
15573            Binder.restoreCallingIdentity(origId);
15574            return res;
15575        }
15576    }
15577
15578    int broadcastIntentInPackage(String packageName, int uid,
15579            Intent intent, String resolvedType, IIntentReceiver resultTo,
15580            int resultCode, String resultData, Bundle map,
15581            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15582        synchronized(this) {
15583            intent = verifyBroadcastLocked(intent);
15584
15585            final long origId = Binder.clearCallingIdentity();
15586            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15587                    resultTo, resultCode, resultData, map, requiredPermission,
15588                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15589            Binder.restoreCallingIdentity(origId);
15590            return res;
15591        }
15592    }
15593
15594    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15595        // Refuse possible leaked file descriptors
15596        if (intent != null && intent.hasFileDescriptors() == true) {
15597            throw new IllegalArgumentException("File descriptors passed in Intent");
15598        }
15599
15600        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15601                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15602
15603        synchronized(this) {
15604            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15605                    != PackageManager.PERMISSION_GRANTED) {
15606                String msg = "Permission Denial: unbroadcastIntent() from pid="
15607                        + Binder.getCallingPid()
15608                        + ", uid=" + Binder.getCallingUid()
15609                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15610                Slog.w(TAG, msg);
15611                throw new SecurityException(msg);
15612            }
15613            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15614            if (stickies != null) {
15615                ArrayList<Intent> list = stickies.get(intent.getAction());
15616                if (list != null) {
15617                    int N = list.size();
15618                    int i;
15619                    for (i=0; i<N; i++) {
15620                        if (intent.filterEquals(list.get(i))) {
15621                            list.remove(i);
15622                            break;
15623                        }
15624                    }
15625                    if (list.size() <= 0) {
15626                        stickies.remove(intent.getAction());
15627                    }
15628                }
15629                if (stickies.size() <= 0) {
15630                    mStickyBroadcasts.remove(userId);
15631                }
15632            }
15633        }
15634    }
15635
15636    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15637            String resultData, Bundle resultExtras, boolean resultAbort) {
15638        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15639        if (r == null) {
15640            Slog.w(TAG, "finishReceiver called but not found on queue");
15641            return false;
15642        }
15643
15644        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15645    }
15646
15647    void backgroundServicesFinishedLocked(int userId) {
15648        for (BroadcastQueue queue : mBroadcastQueues) {
15649            queue.backgroundServicesFinishedLocked(userId);
15650        }
15651    }
15652
15653    public void finishReceiver(IBinder who, int resultCode, String resultData,
15654            Bundle resultExtras, boolean resultAbort) {
15655        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15656
15657        // Refuse possible leaked file descriptors
15658        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15659            throw new IllegalArgumentException("File descriptors passed in Bundle");
15660        }
15661
15662        final long origId = Binder.clearCallingIdentity();
15663        try {
15664            boolean doNext = false;
15665            BroadcastRecord r;
15666
15667            synchronized(this) {
15668                r = broadcastRecordForReceiverLocked(who);
15669                if (r != null) {
15670                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15671                        resultData, resultExtras, resultAbort, true);
15672                }
15673            }
15674
15675            if (doNext) {
15676                r.queue.processNextBroadcast(false);
15677            }
15678            trimApplications();
15679        } finally {
15680            Binder.restoreCallingIdentity(origId);
15681        }
15682    }
15683
15684    // =========================================================
15685    // INSTRUMENTATION
15686    // =========================================================
15687
15688    public boolean startInstrumentation(ComponentName className,
15689            String profileFile, int flags, Bundle arguments,
15690            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15691            int userId, String abiOverride) {
15692        enforceNotIsolatedCaller("startInstrumentation");
15693        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15694                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15695        // Refuse possible leaked file descriptors
15696        if (arguments != null && arguments.hasFileDescriptors()) {
15697            throw new IllegalArgumentException("File descriptors passed in Bundle");
15698        }
15699
15700        synchronized(this) {
15701            InstrumentationInfo ii = null;
15702            ApplicationInfo ai = null;
15703            try {
15704                ii = mContext.getPackageManager().getInstrumentationInfo(
15705                    className, STOCK_PM_FLAGS);
15706                ai = AppGlobals.getPackageManager().getApplicationInfo(
15707                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15708            } catch (PackageManager.NameNotFoundException e) {
15709            } catch (RemoteException e) {
15710            }
15711            if (ii == null) {
15712                reportStartInstrumentationFailure(watcher, className,
15713                        "Unable to find instrumentation info for: " + className);
15714                return false;
15715            }
15716            if (ai == null) {
15717                reportStartInstrumentationFailure(watcher, className,
15718                        "Unable to find instrumentation target package: " + ii.targetPackage);
15719                return false;
15720            }
15721
15722            int match = mContext.getPackageManager().checkSignatures(
15723                    ii.targetPackage, ii.packageName);
15724            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15725                String msg = "Permission Denial: starting instrumentation "
15726                        + className + " from pid="
15727                        + Binder.getCallingPid()
15728                        + ", uid=" + Binder.getCallingPid()
15729                        + " not allowed because package " + ii.packageName
15730                        + " does not have a signature matching the target "
15731                        + ii.targetPackage;
15732                reportStartInstrumentationFailure(watcher, className, msg);
15733                throw new SecurityException(msg);
15734            }
15735
15736            final long origId = Binder.clearCallingIdentity();
15737            // Instrumentation can kill and relaunch even persistent processes
15738            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15739                    "start instr");
15740            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15741            app.instrumentationClass = className;
15742            app.instrumentationInfo = ai;
15743            app.instrumentationProfileFile = profileFile;
15744            app.instrumentationArguments = arguments;
15745            app.instrumentationWatcher = watcher;
15746            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15747            app.instrumentationResultClass = className;
15748            Binder.restoreCallingIdentity(origId);
15749        }
15750
15751        return true;
15752    }
15753
15754    /**
15755     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15756     * error to the logs, but if somebody is watching, send the report there too.  This enables
15757     * the "am" command to report errors with more information.
15758     *
15759     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15760     * @param cn The component name of the instrumentation.
15761     * @param report The error report.
15762     */
15763    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15764            ComponentName cn, String report) {
15765        Slog.w(TAG, report);
15766        try {
15767            if (watcher != null) {
15768                Bundle results = new Bundle();
15769                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15770                results.putString("Error", report);
15771                watcher.instrumentationStatus(cn, -1, results);
15772            }
15773        } catch (RemoteException e) {
15774            Slog.w(TAG, e);
15775        }
15776    }
15777
15778    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15779        if (app.instrumentationWatcher != null) {
15780            try {
15781                // NOTE:  IInstrumentationWatcher *must* be oneway here
15782                app.instrumentationWatcher.instrumentationFinished(
15783                    app.instrumentationClass,
15784                    resultCode,
15785                    results);
15786            } catch (RemoteException e) {
15787            }
15788        }
15789        if (app.instrumentationUiAutomationConnection != null) {
15790            try {
15791                app.instrumentationUiAutomationConnection.shutdown();
15792            } catch (RemoteException re) {
15793                /* ignore */
15794            }
15795            // Only a UiAutomation can set this flag and now that
15796            // it is finished we make sure it is reset to its default.
15797            mUserIsMonkey = false;
15798        }
15799        app.instrumentationWatcher = null;
15800        app.instrumentationUiAutomationConnection = null;
15801        app.instrumentationClass = null;
15802        app.instrumentationInfo = null;
15803        app.instrumentationProfileFile = null;
15804        app.instrumentationArguments = null;
15805
15806        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15807                "finished inst");
15808    }
15809
15810    public void finishInstrumentation(IApplicationThread target,
15811            int resultCode, Bundle results) {
15812        int userId = UserHandle.getCallingUserId();
15813        // Refuse possible leaked file descriptors
15814        if (results != null && results.hasFileDescriptors()) {
15815            throw new IllegalArgumentException("File descriptors passed in Intent");
15816        }
15817
15818        synchronized(this) {
15819            ProcessRecord app = getRecordForAppLocked(target);
15820            if (app == null) {
15821                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15822                return;
15823            }
15824            final long origId = Binder.clearCallingIdentity();
15825            finishInstrumentationLocked(app, resultCode, results);
15826            Binder.restoreCallingIdentity(origId);
15827        }
15828    }
15829
15830    // =========================================================
15831    // CONFIGURATION
15832    // =========================================================
15833
15834    public ConfigurationInfo getDeviceConfigurationInfo() {
15835        ConfigurationInfo config = new ConfigurationInfo();
15836        synchronized (this) {
15837            config.reqTouchScreen = mConfiguration.touchscreen;
15838            config.reqKeyboardType = mConfiguration.keyboard;
15839            config.reqNavigation = mConfiguration.navigation;
15840            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15841                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15842                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15843            }
15844            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15845                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15846                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15847            }
15848            config.reqGlEsVersion = GL_ES_VERSION;
15849        }
15850        return config;
15851    }
15852
15853    ActivityStack getFocusedStack() {
15854        return mStackSupervisor.getFocusedStack();
15855    }
15856
15857    public Configuration getConfiguration() {
15858        Configuration ci;
15859        synchronized(this) {
15860            ci = new Configuration(mConfiguration);
15861        }
15862        return ci;
15863    }
15864
15865    public void updatePersistentConfiguration(Configuration values) {
15866        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15867                "updateConfiguration()");
15868        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15869                "updateConfiguration()");
15870        if (values == null) {
15871            throw new NullPointerException("Configuration must not be null");
15872        }
15873
15874        synchronized(this) {
15875            final long origId = Binder.clearCallingIdentity();
15876            updateConfigurationLocked(values, null, true, false);
15877            Binder.restoreCallingIdentity(origId);
15878        }
15879    }
15880
15881    public void updateConfiguration(Configuration values) {
15882        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15883                "updateConfiguration()");
15884
15885        synchronized(this) {
15886            if (values == null && mWindowManager != null) {
15887                // sentinel: fetch the current configuration from the window manager
15888                values = mWindowManager.computeNewConfiguration();
15889            }
15890
15891            if (mWindowManager != null) {
15892                mProcessList.applyDisplaySize(mWindowManager);
15893            }
15894
15895            final long origId = Binder.clearCallingIdentity();
15896            if (values != null) {
15897                Settings.System.clearConfiguration(values);
15898            }
15899            updateConfigurationLocked(values, null, false, false);
15900            Binder.restoreCallingIdentity(origId);
15901        }
15902    }
15903
15904    /**
15905     * Do either or both things: (1) change the current configuration, and (2)
15906     * make sure the given activity is running with the (now) current
15907     * configuration.  Returns true if the activity has been left running, or
15908     * false if <var>starting</var> is being destroyed to match the new
15909     * configuration.
15910     * @param persistent TODO
15911     */
15912    boolean updateConfigurationLocked(Configuration values,
15913            ActivityRecord starting, boolean persistent, boolean initLocale) {
15914        int changes = 0;
15915
15916        if (values != null) {
15917            Configuration newConfig = new Configuration(mConfiguration);
15918            changes = newConfig.updateFrom(values);
15919            if (changes != 0) {
15920                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15921                    Slog.i(TAG, "Updating configuration to: " + values);
15922                }
15923
15924                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15925
15926                if (values.locale != null && !initLocale) {
15927                    saveLocaleLocked(values.locale,
15928                                     !values.locale.equals(mConfiguration.locale),
15929                                     values.userSetLocale);
15930                }
15931
15932                mConfigurationSeq++;
15933                if (mConfigurationSeq <= 0) {
15934                    mConfigurationSeq = 1;
15935                }
15936                newConfig.seq = mConfigurationSeq;
15937                mConfiguration = newConfig;
15938                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15939                //mUsageStatsService.noteStartConfig(newConfig);
15940
15941                final Configuration configCopy = new Configuration(mConfiguration);
15942
15943                // TODO: If our config changes, should we auto dismiss any currently
15944                // showing dialogs?
15945                mShowDialogs = shouldShowDialogs(newConfig);
15946
15947                AttributeCache ac = AttributeCache.instance();
15948                if (ac != null) {
15949                    ac.updateConfiguration(configCopy);
15950                }
15951
15952                // Make sure all resources in our process are updated
15953                // right now, so that anyone who is going to retrieve
15954                // resource values after we return will be sure to get
15955                // the new ones.  This is especially important during
15956                // boot, where the first config change needs to guarantee
15957                // all resources have that config before following boot
15958                // code is executed.
15959                mSystemThread.applyConfigurationToResources(configCopy);
15960
15961                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15962                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15963                    msg.obj = new Configuration(configCopy);
15964                    mHandler.sendMessage(msg);
15965                }
15966
15967                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15968                    ProcessRecord app = mLruProcesses.get(i);
15969                    try {
15970                        if (app.thread != null) {
15971                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15972                                    + app.processName + " new config " + mConfiguration);
15973                            app.thread.scheduleConfigurationChanged(configCopy);
15974                        }
15975                    } catch (Exception e) {
15976                    }
15977                }
15978                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15979                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15980                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15981                        | Intent.FLAG_RECEIVER_FOREGROUND);
15982                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15983                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15984                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15985                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15986                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15987                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15988                    broadcastIntentLocked(null, null, intent,
15989                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15990                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15991                }
15992            }
15993        }
15994
15995        boolean kept = true;
15996        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15997        // mainStack is null during startup.
15998        if (mainStack != null) {
15999            if (changes != 0 && starting == null) {
16000                // If the configuration changed, and the caller is not already
16001                // in the process of starting an activity, then find the top
16002                // activity to check if its configuration needs to change.
16003                starting = mainStack.topRunningActivityLocked(null);
16004            }
16005
16006            if (starting != null) {
16007                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16008                // And we need to make sure at this point that all other activities
16009                // are made visible with the correct configuration.
16010                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16011            }
16012        }
16013
16014        if (values != null && mWindowManager != null) {
16015            mWindowManager.setNewConfiguration(mConfiguration);
16016        }
16017
16018        return kept;
16019    }
16020
16021    /**
16022     * Decide based on the configuration whether we should shouw the ANR,
16023     * crash, etc dialogs.  The idea is that if there is no affordnace to
16024     * press the on-screen buttons, we shouldn't show the dialog.
16025     *
16026     * A thought: SystemUI might also want to get told about this, the Power
16027     * dialog / global actions also might want different behaviors.
16028     */
16029    private static final boolean shouldShowDialogs(Configuration config) {
16030        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16031                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16032    }
16033
16034    /**
16035     * Save the locale.  You must be inside a synchronized (this) block.
16036     */
16037    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16038        if(isDiff) {
16039            SystemProperties.set("user.language", l.getLanguage());
16040            SystemProperties.set("user.region", l.getCountry());
16041        }
16042
16043        if(isPersist) {
16044            SystemProperties.set("persist.sys.language", l.getLanguage());
16045            SystemProperties.set("persist.sys.country", l.getCountry());
16046            SystemProperties.set("persist.sys.localevar", l.getVariant());
16047        }
16048    }
16049
16050    @Override
16051    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16052        synchronized (this) {
16053            ActivityRecord srec = ActivityRecord.forToken(token);
16054            if (srec.task != null && srec.task.stack != null) {
16055                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16056            }
16057        }
16058        return false;
16059    }
16060
16061    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16062            Intent resultData) {
16063
16064        synchronized (this) {
16065            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16066            if (stack != null) {
16067                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16068            }
16069            return false;
16070        }
16071    }
16072
16073    public int getLaunchedFromUid(IBinder activityToken) {
16074        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16075        if (srec == null) {
16076            return -1;
16077        }
16078        return srec.launchedFromUid;
16079    }
16080
16081    public String getLaunchedFromPackage(IBinder activityToken) {
16082        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16083        if (srec == null) {
16084            return null;
16085        }
16086        return srec.launchedFromPackage;
16087    }
16088
16089    // =========================================================
16090    // LIFETIME MANAGEMENT
16091    // =========================================================
16092
16093    // Returns which broadcast queue the app is the current [or imminent] receiver
16094    // on, or 'null' if the app is not an active broadcast recipient.
16095    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16096        BroadcastRecord r = app.curReceiver;
16097        if (r != null) {
16098            return r.queue;
16099        }
16100
16101        // It's not the current receiver, but it might be starting up to become one
16102        synchronized (this) {
16103            for (BroadcastQueue queue : mBroadcastQueues) {
16104                r = queue.mPendingBroadcast;
16105                if (r != null && r.curApp == app) {
16106                    // found it; report which queue it's in
16107                    return queue;
16108                }
16109            }
16110        }
16111
16112        return null;
16113    }
16114
16115    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16116            boolean doingAll, long now) {
16117        if (mAdjSeq == app.adjSeq) {
16118            // This adjustment has already been computed.
16119            return app.curRawAdj;
16120        }
16121
16122        if (app.thread == null) {
16123            app.adjSeq = mAdjSeq;
16124            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16125            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16126            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16127        }
16128
16129        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16130        app.adjSource = null;
16131        app.adjTarget = null;
16132        app.empty = false;
16133        app.cached = false;
16134
16135        final int activitiesSize = app.activities.size();
16136
16137        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16138            // The max adjustment doesn't allow this app to be anything
16139            // below foreground, so it is not worth doing work for it.
16140            app.adjType = "fixed";
16141            app.adjSeq = mAdjSeq;
16142            app.curRawAdj = app.maxAdj;
16143            app.foregroundActivities = false;
16144            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16145            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16146            // System processes can do UI, and when they do we want to have
16147            // them trim their memory after the user leaves the UI.  To
16148            // facilitate this, here we need to determine whether or not it
16149            // is currently showing UI.
16150            app.systemNoUi = true;
16151            if (app == TOP_APP) {
16152                app.systemNoUi = false;
16153            } else if (activitiesSize > 0) {
16154                for (int j = 0; j < activitiesSize; j++) {
16155                    final ActivityRecord r = app.activities.get(j);
16156                    if (r.visible) {
16157                        app.systemNoUi = false;
16158                    }
16159                }
16160            }
16161            if (!app.systemNoUi) {
16162                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16163            }
16164            return (app.curAdj=app.maxAdj);
16165        }
16166
16167        app.systemNoUi = false;
16168
16169        // Determine the importance of the process, starting with most
16170        // important to least, and assign an appropriate OOM adjustment.
16171        int adj;
16172        int schedGroup;
16173        int procState;
16174        boolean foregroundActivities = false;
16175        BroadcastQueue queue;
16176        if (app == TOP_APP) {
16177            // The last app on the list is the foreground app.
16178            adj = ProcessList.FOREGROUND_APP_ADJ;
16179            schedGroup = Process.THREAD_GROUP_DEFAULT;
16180            app.adjType = "top-activity";
16181            foregroundActivities = true;
16182            procState = ActivityManager.PROCESS_STATE_TOP;
16183        } else if (app.instrumentationClass != null) {
16184            // Don't want to kill running instrumentation.
16185            adj = ProcessList.FOREGROUND_APP_ADJ;
16186            schedGroup = Process.THREAD_GROUP_DEFAULT;
16187            app.adjType = "instrumentation";
16188            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16189        } else if ((queue = isReceivingBroadcast(app)) != null) {
16190            // An app that is currently receiving a broadcast also
16191            // counts as being in the foreground for OOM killer purposes.
16192            // It's placed in a sched group based on the nature of the
16193            // broadcast as reflected by which queue it's active in.
16194            adj = ProcessList.FOREGROUND_APP_ADJ;
16195            schedGroup = (queue == mFgBroadcastQueue)
16196                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16197            app.adjType = "broadcast";
16198            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16199        } else if (app.executingServices.size() > 0) {
16200            // An app that is currently executing a service callback also
16201            // counts as being in the foreground.
16202            adj = ProcessList.FOREGROUND_APP_ADJ;
16203            schedGroup = app.execServicesFg ?
16204                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16205            app.adjType = "exec-service";
16206            procState = ActivityManager.PROCESS_STATE_SERVICE;
16207            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16208        } else {
16209            // As far as we know the process is empty.  We may change our mind later.
16210            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16211            // At this point we don't actually know the adjustment.  Use the cached adj
16212            // value that the caller wants us to.
16213            adj = cachedAdj;
16214            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16215            app.cached = true;
16216            app.empty = true;
16217            app.adjType = "cch-empty";
16218        }
16219
16220        // Examine all activities if not already foreground.
16221        if (!foregroundActivities && activitiesSize > 0) {
16222            for (int j = 0; j < activitiesSize; j++) {
16223                final ActivityRecord r = app.activities.get(j);
16224                if (r.app != app) {
16225                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16226                            + app + "?!?");
16227                    continue;
16228                }
16229                if (r.visible) {
16230                    // App has a visible activity; only upgrade adjustment.
16231                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16232                        adj = ProcessList.VISIBLE_APP_ADJ;
16233                        app.adjType = "visible";
16234                    }
16235                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16236                        procState = ActivityManager.PROCESS_STATE_TOP;
16237                    }
16238                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16239                    app.cached = false;
16240                    app.empty = false;
16241                    foregroundActivities = true;
16242                    break;
16243                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16244                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16245                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16246                        app.adjType = "pausing";
16247                    }
16248                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16249                        procState = ActivityManager.PROCESS_STATE_TOP;
16250                    }
16251                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16252                    app.cached = false;
16253                    app.empty = false;
16254                    foregroundActivities = true;
16255                } else if (r.state == ActivityState.STOPPING) {
16256                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16257                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16258                        app.adjType = "stopping";
16259                    }
16260                    // For the process state, we will at this point consider the
16261                    // process to be cached.  It will be cached either as an activity
16262                    // or empty depending on whether the activity is finishing.  We do
16263                    // this so that we can treat the process as cached for purposes of
16264                    // memory trimming (determing current memory level, trim command to
16265                    // send to process) since there can be an arbitrary number of stopping
16266                    // processes and they should soon all go into the cached state.
16267                    if (!r.finishing) {
16268                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16269                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16270                        }
16271                    }
16272                    app.cached = false;
16273                    app.empty = false;
16274                    foregroundActivities = true;
16275                } else {
16276                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16277                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16278                        app.adjType = "cch-act";
16279                    }
16280                }
16281            }
16282        }
16283
16284        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16285            if (app.foregroundServices) {
16286                // The user is aware of this app, so make it visible.
16287                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16288                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16289                app.cached = false;
16290                app.adjType = "fg-service";
16291                schedGroup = Process.THREAD_GROUP_DEFAULT;
16292            } else if (app.forcingToForeground != null) {
16293                // The user is aware of this app, so make it visible.
16294                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16295                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16296                app.cached = false;
16297                app.adjType = "force-fg";
16298                app.adjSource = app.forcingToForeground;
16299                schedGroup = Process.THREAD_GROUP_DEFAULT;
16300            }
16301        }
16302
16303        if (app == mHeavyWeightProcess) {
16304            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16305                // We don't want to kill the current heavy-weight process.
16306                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16307                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16308                app.cached = false;
16309                app.adjType = "heavy";
16310            }
16311            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16312                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16313            }
16314        }
16315
16316        if (app == mHomeProcess) {
16317            if (adj > ProcessList.HOME_APP_ADJ) {
16318                // This process is hosting what we currently consider to be the
16319                // home app, so we don't want to let it go into the background.
16320                adj = ProcessList.HOME_APP_ADJ;
16321                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16322                app.cached = false;
16323                app.adjType = "home";
16324            }
16325            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16326                procState = ActivityManager.PROCESS_STATE_HOME;
16327            }
16328        }
16329
16330        if (app == mPreviousProcess && app.activities.size() > 0) {
16331            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16332                // This was the previous process that showed UI to the user.
16333                // We want to try to keep it around more aggressively, to give
16334                // a good experience around switching between two apps.
16335                adj = ProcessList.PREVIOUS_APP_ADJ;
16336                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16337                app.cached = false;
16338                app.adjType = "previous";
16339            }
16340            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16341                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16342            }
16343        }
16344
16345        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16346                + " reason=" + app.adjType);
16347
16348        // By default, we use the computed adjustment.  It may be changed if
16349        // there are applications dependent on our services or providers, but
16350        // this gives us a baseline and makes sure we don't get into an
16351        // infinite recursion.
16352        app.adjSeq = mAdjSeq;
16353        app.curRawAdj = adj;
16354        app.hasStartedServices = false;
16355
16356        if (mBackupTarget != null && app == mBackupTarget.app) {
16357            // If possible we want to avoid killing apps while they're being backed up
16358            if (adj > ProcessList.BACKUP_APP_ADJ) {
16359                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16360                adj = ProcessList.BACKUP_APP_ADJ;
16361                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16362                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16363                }
16364                app.adjType = "backup";
16365                app.cached = false;
16366            }
16367            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16368                procState = ActivityManager.PROCESS_STATE_BACKUP;
16369            }
16370        }
16371
16372        boolean mayBeTop = false;
16373
16374        for (int is = app.services.size()-1;
16375                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16376                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16377                        || procState > ActivityManager.PROCESS_STATE_TOP);
16378                is--) {
16379            ServiceRecord s = app.services.valueAt(is);
16380            if (s.startRequested) {
16381                app.hasStartedServices = true;
16382                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16383                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16384                }
16385                if (app.hasShownUi && app != mHomeProcess) {
16386                    // If this process has shown some UI, let it immediately
16387                    // go to the LRU list because it may be pretty heavy with
16388                    // UI stuff.  We'll tag it with a label just to help
16389                    // debug and understand what is going on.
16390                    if (adj > ProcessList.SERVICE_ADJ) {
16391                        app.adjType = "cch-started-ui-services";
16392                    }
16393                } else {
16394                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16395                        // This service has seen some activity within
16396                        // recent memory, so we will keep its process ahead
16397                        // of the background processes.
16398                        if (adj > ProcessList.SERVICE_ADJ) {
16399                            adj = ProcessList.SERVICE_ADJ;
16400                            app.adjType = "started-services";
16401                            app.cached = false;
16402                        }
16403                    }
16404                    // If we have let the service slide into the background
16405                    // state, still have some text describing what it is doing
16406                    // even though the service no longer has an impact.
16407                    if (adj > ProcessList.SERVICE_ADJ) {
16408                        app.adjType = "cch-started-services";
16409                    }
16410                }
16411            }
16412            for (int conni = s.connections.size()-1;
16413                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16414                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16415                            || procState > ActivityManager.PROCESS_STATE_TOP);
16416                    conni--) {
16417                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16418                for (int i = 0;
16419                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16420                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16421                                || procState > ActivityManager.PROCESS_STATE_TOP);
16422                        i++) {
16423                    // XXX should compute this based on the max of
16424                    // all connected clients.
16425                    ConnectionRecord cr = clist.get(i);
16426                    if (cr.binding.client == app) {
16427                        // Binding to ourself is not interesting.
16428                        continue;
16429                    }
16430                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16431                        ProcessRecord client = cr.binding.client;
16432                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16433                                TOP_APP, doingAll, now);
16434                        int clientProcState = client.curProcState;
16435                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16436                            // If the other app is cached for any reason, for purposes here
16437                            // we are going to consider it empty.  The specific cached state
16438                            // doesn't propagate except under certain conditions.
16439                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16440                        }
16441                        String adjType = null;
16442                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16443                            // Not doing bind OOM management, so treat
16444                            // this guy more like a started service.
16445                            if (app.hasShownUi && app != mHomeProcess) {
16446                                // If this process has shown some UI, let it immediately
16447                                // go to the LRU list because it may be pretty heavy with
16448                                // UI stuff.  We'll tag it with a label just to help
16449                                // debug and understand what is going on.
16450                                if (adj > clientAdj) {
16451                                    adjType = "cch-bound-ui-services";
16452                                }
16453                                app.cached = false;
16454                                clientAdj = adj;
16455                                clientProcState = procState;
16456                            } else {
16457                                if (now >= (s.lastActivity
16458                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16459                                    // This service has not seen activity within
16460                                    // recent memory, so allow it to drop to the
16461                                    // LRU list if there is no other reason to keep
16462                                    // it around.  We'll also tag it with a label just
16463                                    // to help debug and undertand what is going on.
16464                                    if (adj > clientAdj) {
16465                                        adjType = "cch-bound-services";
16466                                    }
16467                                    clientAdj = adj;
16468                                }
16469                            }
16470                        }
16471                        if (adj > clientAdj) {
16472                            // If this process has recently shown UI, and
16473                            // the process that is binding to it is less
16474                            // important than being visible, then we don't
16475                            // care about the binding as much as we care
16476                            // about letting this process get into the LRU
16477                            // list to be killed and restarted if needed for
16478                            // memory.
16479                            if (app.hasShownUi && app != mHomeProcess
16480                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16481                                adjType = "cch-bound-ui-services";
16482                            } else {
16483                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16484                                        |Context.BIND_IMPORTANT)) != 0) {
16485                                    adj = clientAdj;
16486                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16487                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16488                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16489                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16490                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16491                                    adj = clientAdj;
16492                                } else {
16493                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16494                                        adj = ProcessList.VISIBLE_APP_ADJ;
16495                                    }
16496                                }
16497                                if (!client.cached) {
16498                                    app.cached = false;
16499                                }
16500                                adjType = "service";
16501                            }
16502                        }
16503                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16504                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16505                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16506                            }
16507                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16508                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16509                                    // Special handling of clients who are in the top state.
16510                                    // We *may* want to consider this process to be in the
16511                                    // top state as well, but only if there is not another
16512                                    // reason for it to be running.  Being on the top is a
16513                                    // special state, meaning you are specifically running
16514                                    // for the current top app.  If the process is already
16515                                    // running in the background for some other reason, it
16516                                    // is more important to continue considering it to be
16517                                    // in the background state.
16518                                    mayBeTop = true;
16519                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16520                                } else {
16521                                    // Special handling for above-top states (persistent
16522                                    // processes).  These should not bring the current process
16523                                    // into the top state, since they are not on top.  Instead
16524                                    // give them the best state after that.
16525                                    clientProcState =
16526                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16527                                }
16528                            }
16529                        } else {
16530                            if (clientProcState <
16531                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16532                                clientProcState =
16533                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16534                            }
16535                        }
16536                        if (procState > clientProcState) {
16537                            procState = clientProcState;
16538                        }
16539                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16540                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16541                            app.pendingUiClean = true;
16542                        }
16543                        if (adjType != null) {
16544                            app.adjType = adjType;
16545                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16546                                    .REASON_SERVICE_IN_USE;
16547                            app.adjSource = cr.binding.client;
16548                            app.adjSourceProcState = clientProcState;
16549                            app.adjTarget = s.name;
16550                        }
16551                    }
16552                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16553                        app.treatLikeActivity = true;
16554                    }
16555                    final ActivityRecord a = cr.activity;
16556                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16557                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16558                                (a.visible || a.state == ActivityState.RESUMED
16559                                 || a.state == ActivityState.PAUSING)) {
16560                            adj = ProcessList.FOREGROUND_APP_ADJ;
16561                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16562                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16563                            }
16564                            app.cached = false;
16565                            app.adjType = "service";
16566                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16567                                    .REASON_SERVICE_IN_USE;
16568                            app.adjSource = a;
16569                            app.adjSourceProcState = procState;
16570                            app.adjTarget = s.name;
16571                        }
16572                    }
16573                }
16574            }
16575        }
16576
16577        for (int provi = app.pubProviders.size()-1;
16578                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16579                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16580                        || procState > ActivityManager.PROCESS_STATE_TOP);
16581                provi--) {
16582            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16583            for (int i = cpr.connections.size()-1;
16584                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16585                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16586                            || procState > ActivityManager.PROCESS_STATE_TOP);
16587                    i--) {
16588                ContentProviderConnection conn = cpr.connections.get(i);
16589                ProcessRecord client = conn.client;
16590                if (client == app) {
16591                    // Being our own client is not interesting.
16592                    continue;
16593                }
16594                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16595                int clientProcState = client.curProcState;
16596                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16597                    // If the other app is cached for any reason, for purposes here
16598                    // we are going to consider it empty.
16599                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16600                }
16601                if (adj > clientAdj) {
16602                    if (app.hasShownUi && app != mHomeProcess
16603                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16604                        app.adjType = "cch-ui-provider";
16605                    } else {
16606                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16607                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16608                        app.adjType = "provider";
16609                    }
16610                    app.cached &= client.cached;
16611                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16612                            .REASON_PROVIDER_IN_USE;
16613                    app.adjSource = client;
16614                    app.adjSourceProcState = clientProcState;
16615                    app.adjTarget = cpr.name;
16616                }
16617                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16618                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16619                        // Special handling of clients who are in the top state.
16620                        // We *may* want to consider this process to be in the
16621                        // top state as well, but only if there is not another
16622                        // reason for it to be running.  Being on the top is a
16623                        // special state, meaning you are specifically running
16624                        // for the current top app.  If the process is already
16625                        // running in the background for some other reason, it
16626                        // is more important to continue considering it to be
16627                        // in the background state.
16628                        mayBeTop = true;
16629                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16630                    } else {
16631                        // Special handling for above-top states (persistent
16632                        // processes).  These should not bring the current process
16633                        // into the top state, since they are not on top.  Instead
16634                        // give them the best state after that.
16635                        clientProcState =
16636                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16637                    }
16638                }
16639                if (procState > clientProcState) {
16640                    procState = clientProcState;
16641                }
16642                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16643                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16644                }
16645            }
16646            // If the provider has external (non-framework) process
16647            // dependencies, ensure that its adjustment is at least
16648            // FOREGROUND_APP_ADJ.
16649            if (cpr.hasExternalProcessHandles()) {
16650                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16651                    adj = ProcessList.FOREGROUND_APP_ADJ;
16652                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16653                    app.cached = false;
16654                    app.adjType = "provider";
16655                    app.adjTarget = cpr.name;
16656                }
16657                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16658                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16659                }
16660            }
16661        }
16662
16663        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16664            // A client of one of our services or providers is in the top state.  We
16665            // *may* want to be in the top state, but not if we are already running in
16666            // the background for some other reason.  For the decision here, we are going
16667            // to pick out a few specific states that we want to remain in when a client
16668            // is top (states that tend to be longer-term) and otherwise allow it to go
16669            // to the top state.
16670            switch (procState) {
16671                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16672                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16673                case ActivityManager.PROCESS_STATE_SERVICE:
16674                    // These all are longer-term states, so pull them up to the top
16675                    // of the background states, but not all the way to the top state.
16676                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16677                    break;
16678                default:
16679                    // Otherwise, top is a better choice, so take it.
16680                    procState = ActivityManager.PROCESS_STATE_TOP;
16681                    break;
16682            }
16683        }
16684
16685        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16686            if (app.hasClientActivities) {
16687                // This is a cached process, but with client activities.  Mark it so.
16688                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16689                app.adjType = "cch-client-act";
16690            } else if (app.treatLikeActivity) {
16691                // This is a cached process, but somebody wants us to treat it like it has
16692                // an activity, okay!
16693                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16694                app.adjType = "cch-as-act";
16695            }
16696        }
16697
16698        if (adj == ProcessList.SERVICE_ADJ) {
16699            if (doingAll) {
16700                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16701                mNewNumServiceProcs++;
16702                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16703                if (!app.serviceb) {
16704                    // This service isn't far enough down on the LRU list to
16705                    // normally be a B service, but if we are low on RAM and it
16706                    // is large we want to force it down since we would prefer to
16707                    // keep launcher over it.
16708                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16709                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16710                        app.serviceHighRam = true;
16711                        app.serviceb = true;
16712                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16713                    } else {
16714                        mNewNumAServiceProcs++;
16715                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16716                    }
16717                } else {
16718                    app.serviceHighRam = false;
16719                }
16720            }
16721            if (app.serviceb) {
16722                adj = ProcessList.SERVICE_B_ADJ;
16723            }
16724        }
16725
16726        app.curRawAdj = adj;
16727
16728        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16729        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16730        if (adj > app.maxAdj) {
16731            adj = app.maxAdj;
16732            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16733                schedGroup = Process.THREAD_GROUP_DEFAULT;
16734            }
16735        }
16736
16737        // Do final modification to adj.  Everything we do between here and applying
16738        // the final setAdj must be done in this function, because we will also use
16739        // it when computing the final cached adj later.  Note that we don't need to
16740        // worry about this for max adj above, since max adj will always be used to
16741        // keep it out of the cached vaues.
16742        app.curAdj = app.modifyRawOomAdj(adj);
16743        app.curSchedGroup = schedGroup;
16744        app.curProcState = procState;
16745        app.foregroundActivities = foregroundActivities;
16746
16747        return app.curRawAdj;
16748    }
16749
16750    /**
16751     * Schedule PSS collection of a process.
16752     */
16753    void requestPssLocked(ProcessRecord proc, int procState) {
16754        if (mPendingPssProcesses.contains(proc)) {
16755            return;
16756        }
16757        if (mPendingPssProcesses.size() == 0) {
16758            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16759        }
16760        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16761        proc.pssProcState = procState;
16762        mPendingPssProcesses.add(proc);
16763    }
16764
16765    /**
16766     * Schedule PSS collection of all processes.
16767     */
16768    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16769        if (!always) {
16770            if (now < (mLastFullPssTime +
16771                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16772                return;
16773            }
16774        }
16775        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16776        mLastFullPssTime = now;
16777        mFullPssPending = true;
16778        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16779        mPendingPssProcesses.clear();
16780        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16781            ProcessRecord app = mLruProcesses.get(i);
16782            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16783                app.pssProcState = app.setProcState;
16784                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16785                        isSleeping(), now);
16786                mPendingPssProcesses.add(app);
16787            }
16788        }
16789        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16790    }
16791
16792    /**
16793     * Ask a given process to GC right now.
16794     */
16795    final void performAppGcLocked(ProcessRecord app) {
16796        try {
16797            app.lastRequestedGc = SystemClock.uptimeMillis();
16798            if (app.thread != null) {
16799                if (app.reportLowMemory) {
16800                    app.reportLowMemory = false;
16801                    app.thread.scheduleLowMemory();
16802                } else {
16803                    app.thread.processInBackground();
16804                }
16805            }
16806        } catch (Exception e) {
16807            // whatever.
16808        }
16809    }
16810
16811    /**
16812     * Returns true if things are idle enough to perform GCs.
16813     */
16814    private final boolean canGcNowLocked() {
16815        boolean processingBroadcasts = false;
16816        for (BroadcastQueue q : mBroadcastQueues) {
16817            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16818                processingBroadcasts = true;
16819            }
16820        }
16821        return !processingBroadcasts
16822                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16823    }
16824
16825    /**
16826     * Perform GCs on all processes that are waiting for it, but only
16827     * if things are idle.
16828     */
16829    final void performAppGcsLocked() {
16830        final int N = mProcessesToGc.size();
16831        if (N <= 0) {
16832            return;
16833        }
16834        if (canGcNowLocked()) {
16835            while (mProcessesToGc.size() > 0) {
16836                ProcessRecord proc = mProcessesToGc.remove(0);
16837                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16838                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16839                            <= SystemClock.uptimeMillis()) {
16840                        // To avoid spamming the system, we will GC processes one
16841                        // at a time, waiting a few seconds between each.
16842                        performAppGcLocked(proc);
16843                        scheduleAppGcsLocked();
16844                        return;
16845                    } else {
16846                        // It hasn't been long enough since we last GCed this
16847                        // process...  put it in the list to wait for its time.
16848                        addProcessToGcListLocked(proc);
16849                        break;
16850                    }
16851                }
16852            }
16853
16854            scheduleAppGcsLocked();
16855        }
16856    }
16857
16858    /**
16859     * If all looks good, perform GCs on all processes waiting for them.
16860     */
16861    final void performAppGcsIfAppropriateLocked() {
16862        if (canGcNowLocked()) {
16863            performAppGcsLocked();
16864            return;
16865        }
16866        // Still not idle, wait some more.
16867        scheduleAppGcsLocked();
16868    }
16869
16870    /**
16871     * Schedule the execution of all pending app GCs.
16872     */
16873    final void scheduleAppGcsLocked() {
16874        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16875
16876        if (mProcessesToGc.size() > 0) {
16877            // Schedule a GC for the time to the next process.
16878            ProcessRecord proc = mProcessesToGc.get(0);
16879            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16880
16881            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16882            long now = SystemClock.uptimeMillis();
16883            if (when < (now+GC_TIMEOUT)) {
16884                when = now + GC_TIMEOUT;
16885            }
16886            mHandler.sendMessageAtTime(msg, when);
16887        }
16888    }
16889
16890    /**
16891     * Add a process to the array of processes waiting to be GCed.  Keeps the
16892     * list in sorted order by the last GC time.  The process can't already be
16893     * on the list.
16894     */
16895    final void addProcessToGcListLocked(ProcessRecord proc) {
16896        boolean added = false;
16897        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16898            if (mProcessesToGc.get(i).lastRequestedGc <
16899                    proc.lastRequestedGc) {
16900                added = true;
16901                mProcessesToGc.add(i+1, proc);
16902                break;
16903            }
16904        }
16905        if (!added) {
16906            mProcessesToGc.add(0, proc);
16907        }
16908    }
16909
16910    /**
16911     * Set up to ask a process to GC itself.  This will either do it
16912     * immediately, or put it on the list of processes to gc the next
16913     * time things are idle.
16914     */
16915    final void scheduleAppGcLocked(ProcessRecord app) {
16916        long now = SystemClock.uptimeMillis();
16917        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16918            return;
16919        }
16920        if (!mProcessesToGc.contains(app)) {
16921            addProcessToGcListLocked(app);
16922            scheduleAppGcsLocked();
16923        }
16924    }
16925
16926    final void checkExcessivePowerUsageLocked(boolean doKills) {
16927        updateCpuStatsNow();
16928
16929        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16930        boolean doWakeKills = doKills;
16931        boolean doCpuKills = doKills;
16932        if (mLastPowerCheckRealtime == 0) {
16933            doWakeKills = false;
16934        }
16935        if (mLastPowerCheckUptime == 0) {
16936            doCpuKills = false;
16937        }
16938        if (stats.isScreenOn()) {
16939            doWakeKills = false;
16940        }
16941        final long curRealtime = SystemClock.elapsedRealtime();
16942        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16943        final long curUptime = SystemClock.uptimeMillis();
16944        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16945        mLastPowerCheckRealtime = curRealtime;
16946        mLastPowerCheckUptime = curUptime;
16947        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16948            doWakeKills = false;
16949        }
16950        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16951            doCpuKills = false;
16952        }
16953        int i = mLruProcesses.size();
16954        while (i > 0) {
16955            i--;
16956            ProcessRecord app = mLruProcesses.get(i);
16957            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16958                long wtime;
16959                synchronized (stats) {
16960                    wtime = stats.getProcessWakeTime(app.info.uid,
16961                            app.pid, curRealtime);
16962                }
16963                long wtimeUsed = wtime - app.lastWakeTime;
16964                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16965                if (DEBUG_POWER) {
16966                    StringBuilder sb = new StringBuilder(128);
16967                    sb.append("Wake for ");
16968                    app.toShortString(sb);
16969                    sb.append(": over ");
16970                    TimeUtils.formatDuration(realtimeSince, sb);
16971                    sb.append(" used ");
16972                    TimeUtils.formatDuration(wtimeUsed, sb);
16973                    sb.append(" (");
16974                    sb.append((wtimeUsed*100)/realtimeSince);
16975                    sb.append("%)");
16976                    Slog.i(TAG, sb.toString());
16977                    sb.setLength(0);
16978                    sb.append("CPU for ");
16979                    app.toShortString(sb);
16980                    sb.append(": over ");
16981                    TimeUtils.formatDuration(uptimeSince, sb);
16982                    sb.append(" used ");
16983                    TimeUtils.formatDuration(cputimeUsed, sb);
16984                    sb.append(" (");
16985                    sb.append((cputimeUsed*100)/uptimeSince);
16986                    sb.append("%)");
16987                    Slog.i(TAG, sb.toString());
16988                }
16989                // If a process has held a wake lock for more
16990                // than 50% of the time during this period,
16991                // that sounds bad.  Kill!
16992                if (doWakeKills && realtimeSince > 0
16993                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16994                    synchronized (stats) {
16995                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16996                                realtimeSince, wtimeUsed);
16997                    }
16998                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16999                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17000                } else if (doCpuKills && uptimeSince > 0
17001                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17002                    synchronized (stats) {
17003                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17004                                uptimeSince, cputimeUsed);
17005                    }
17006                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17007                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17008                } else {
17009                    app.lastWakeTime = wtime;
17010                    app.lastCpuTime = app.curCpuTime;
17011                }
17012            }
17013        }
17014    }
17015
17016    private final boolean applyOomAdjLocked(ProcessRecord app,
17017            ProcessRecord TOP_APP, boolean doingAll, long now) {
17018        boolean success = true;
17019
17020        if (app.curRawAdj != app.setRawAdj) {
17021            app.setRawAdj = app.curRawAdj;
17022        }
17023
17024        int changes = 0;
17025
17026        if (app.curAdj != app.setAdj) {
17027            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17028            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17029                TAG, "Set " + app.pid + " " + app.processName +
17030                " adj " + app.curAdj + ": " + app.adjType);
17031            app.setAdj = app.curAdj;
17032        }
17033
17034        if (app.setSchedGroup != app.curSchedGroup) {
17035            app.setSchedGroup = app.curSchedGroup;
17036            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17037                    "Setting process group of " + app.processName
17038                    + " to " + app.curSchedGroup);
17039            if (app.waitingToKill != null &&
17040                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17041                app.kill(app.waitingToKill, true);
17042                success = false;
17043            } else {
17044                if (true) {
17045                    long oldId = Binder.clearCallingIdentity();
17046                    try {
17047                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17048                    } catch (Exception e) {
17049                        Slog.w(TAG, "Failed setting process group of " + app.pid
17050                                + " to " + app.curSchedGroup);
17051                        e.printStackTrace();
17052                    } finally {
17053                        Binder.restoreCallingIdentity(oldId);
17054                    }
17055                } else {
17056                    if (app.thread != null) {
17057                        try {
17058                            app.thread.setSchedulingGroup(app.curSchedGroup);
17059                        } catch (RemoteException e) {
17060                        }
17061                    }
17062                }
17063                Process.setSwappiness(app.pid,
17064                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17065            }
17066        }
17067        if (app.repForegroundActivities != app.foregroundActivities) {
17068            app.repForegroundActivities = app.foregroundActivities;
17069            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17070        }
17071        if (app.repProcState != app.curProcState) {
17072            app.repProcState = app.curProcState;
17073            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17074            if (app.thread != null) {
17075                try {
17076                    if (false) {
17077                        //RuntimeException h = new RuntimeException("here");
17078                        Slog.i(TAG, "Sending new process state " + app.repProcState
17079                                + " to " + app /*, h*/);
17080                    }
17081                    app.thread.setProcessState(app.repProcState);
17082                } catch (RemoteException e) {
17083                }
17084            }
17085        }
17086        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17087                app.setProcState)) {
17088            app.lastStateTime = now;
17089            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17090                    isSleeping(), now);
17091            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17092                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17093                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17094                    + (app.nextPssTime-now) + ": " + app);
17095        } else {
17096            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17097                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17098                requestPssLocked(app, app.setProcState);
17099                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17100                        isSleeping(), now);
17101            } else if (false && DEBUG_PSS) {
17102                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17103            }
17104        }
17105        if (app.setProcState != app.curProcState) {
17106            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17107                    "Proc state change of " + app.processName
17108                    + " to " + app.curProcState);
17109            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17110            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17111            if (setImportant && !curImportant) {
17112                // This app is no longer something we consider important enough to allow to
17113                // use arbitrary amounts of battery power.  Note
17114                // its current wake lock time to later know to kill it if
17115                // it is not behaving well.
17116                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17117                synchronized (stats) {
17118                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17119                            app.pid, SystemClock.elapsedRealtime());
17120                }
17121                app.lastCpuTime = app.curCpuTime;
17122
17123            }
17124            app.setProcState = app.curProcState;
17125            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17126                app.notCachedSinceIdle = false;
17127            }
17128            if (!doingAll) {
17129                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17130            } else {
17131                app.procStateChanged = true;
17132            }
17133        }
17134
17135        if (changes != 0) {
17136            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17137            int i = mPendingProcessChanges.size()-1;
17138            ProcessChangeItem item = null;
17139            while (i >= 0) {
17140                item = mPendingProcessChanges.get(i);
17141                if (item.pid == app.pid) {
17142                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17143                    break;
17144                }
17145                i--;
17146            }
17147            if (i < 0) {
17148                // No existing item in pending changes; need a new one.
17149                final int NA = mAvailProcessChanges.size();
17150                if (NA > 0) {
17151                    item = mAvailProcessChanges.remove(NA-1);
17152                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17153                } else {
17154                    item = new ProcessChangeItem();
17155                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17156                }
17157                item.changes = 0;
17158                item.pid = app.pid;
17159                item.uid = app.info.uid;
17160                if (mPendingProcessChanges.size() == 0) {
17161                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17162                            "*** Enqueueing dispatch processes changed!");
17163                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17164                }
17165                mPendingProcessChanges.add(item);
17166            }
17167            item.changes |= changes;
17168            item.processState = app.repProcState;
17169            item.foregroundActivities = app.repForegroundActivities;
17170            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17171                    + Integer.toHexString(System.identityHashCode(item))
17172                    + " " + app.toShortString() + ": changes=" + item.changes
17173                    + " procState=" + item.processState
17174                    + " foreground=" + item.foregroundActivities
17175                    + " type=" + app.adjType + " source=" + app.adjSource
17176                    + " target=" + app.adjTarget);
17177        }
17178
17179        return success;
17180    }
17181
17182    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17183        if (proc.thread != null) {
17184            if (proc.baseProcessTracker != null) {
17185                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17186            }
17187            if (proc.repProcState >= 0) {
17188                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17189                        proc.repProcState);
17190            }
17191        }
17192    }
17193
17194    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17195            ProcessRecord TOP_APP, boolean doingAll, long now) {
17196        if (app.thread == null) {
17197            return false;
17198        }
17199
17200        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17201
17202        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17203    }
17204
17205    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17206            boolean oomAdj) {
17207        if (isForeground != proc.foregroundServices) {
17208            proc.foregroundServices = isForeground;
17209            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17210                    proc.info.uid);
17211            if (isForeground) {
17212                if (curProcs == null) {
17213                    curProcs = new ArrayList<ProcessRecord>();
17214                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17215                }
17216                if (!curProcs.contains(proc)) {
17217                    curProcs.add(proc);
17218                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17219                            proc.info.packageName, proc.info.uid);
17220                }
17221            } else {
17222                if (curProcs != null) {
17223                    if (curProcs.remove(proc)) {
17224                        mBatteryStatsService.noteEvent(
17225                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17226                                proc.info.packageName, proc.info.uid);
17227                        if (curProcs.size() <= 0) {
17228                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17229                        }
17230                    }
17231                }
17232            }
17233            if (oomAdj) {
17234                updateOomAdjLocked();
17235            }
17236        }
17237    }
17238
17239    private final ActivityRecord resumedAppLocked() {
17240        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17241        String pkg;
17242        int uid;
17243        if (act != null) {
17244            pkg = act.packageName;
17245            uid = act.info.applicationInfo.uid;
17246        } else {
17247            pkg = null;
17248            uid = -1;
17249        }
17250        // Has the UID or resumed package name changed?
17251        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17252                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17253            if (mCurResumedPackage != null) {
17254                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17255                        mCurResumedPackage, mCurResumedUid);
17256            }
17257            mCurResumedPackage = pkg;
17258            mCurResumedUid = uid;
17259            if (mCurResumedPackage != null) {
17260                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17261                        mCurResumedPackage, mCurResumedUid);
17262            }
17263        }
17264        return act;
17265    }
17266
17267    final boolean updateOomAdjLocked(ProcessRecord app) {
17268        final ActivityRecord TOP_ACT = resumedAppLocked();
17269        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17270        final boolean wasCached = app.cached;
17271
17272        mAdjSeq++;
17273
17274        // This is the desired cached adjusment we want to tell it to use.
17275        // If our app is currently cached, we know it, and that is it.  Otherwise,
17276        // we don't know it yet, and it needs to now be cached we will then
17277        // need to do a complete oom adj.
17278        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17279                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17280        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17281                SystemClock.uptimeMillis());
17282        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17283            // Changed to/from cached state, so apps after it in the LRU
17284            // list may also be changed.
17285            updateOomAdjLocked();
17286        }
17287        return success;
17288    }
17289
17290    final void updateOomAdjLocked() {
17291        final ActivityRecord TOP_ACT = resumedAppLocked();
17292        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17293        final long now = SystemClock.uptimeMillis();
17294        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17295        final int N = mLruProcesses.size();
17296
17297        if (false) {
17298            RuntimeException e = new RuntimeException();
17299            e.fillInStackTrace();
17300            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17301        }
17302
17303        mAdjSeq++;
17304        mNewNumServiceProcs = 0;
17305        mNewNumAServiceProcs = 0;
17306
17307        final int emptyProcessLimit;
17308        final int cachedProcessLimit;
17309        if (mProcessLimit <= 0) {
17310            emptyProcessLimit = cachedProcessLimit = 0;
17311        } else if (mProcessLimit == 1) {
17312            emptyProcessLimit = 1;
17313            cachedProcessLimit = 0;
17314        } else {
17315            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17316            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17317        }
17318
17319        // Let's determine how many processes we have running vs.
17320        // how many slots we have for background processes; we may want
17321        // to put multiple processes in a slot of there are enough of
17322        // them.
17323        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17324                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17325        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17326        if (numEmptyProcs > cachedProcessLimit) {
17327            // If there are more empty processes than our limit on cached
17328            // processes, then use the cached process limit for the factor.
17329            // This ensures that the really old empty processes get pushed
17330            // down to the bottom, so if we are running low on memory we will
17331            // have a better chance at keeping around more cached processes
17332            // instead of a gazillion empty processes.
17333            numEmptyProcs = cachedProcessLimit;
17334        }
17335        int emptyFactor = numEmptyProcs/numSlots;
17336        if (emptyFactor < 1) emptyFactor = 1;
17337        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17338        if (cachedFactor < 1) cachedFactor = 1;
17339        int stepCached = 0;
17340        int stepEmpty = 0;
17341        int numCached = 0;
17342        int numEmpty = 0;
17343        int numTrimming = 0;
17344
17345        mNumNonCachedProcs = 0;
17346        mNumCachedHiddenProcs = 0;
17347
17348        // First update the OOM adjustment for each of the
17349        // application processes based on their current state.
17350        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17351        int nextCachedAdj = curCachedAdj+1;
17352        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17353        int nextEmptyAdj = curEmptyAdj+2;
17354        for (int i=N-1; i>=0; i--) {
17355            ProcessRecord app = mLruProcesses.get(i);
17356            if (!app.killedByAm && app.thread != null) {
17357                app.procStateChanged = false;
17358                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17359
17360                // If we haven't yet assigned the final cached adj
17361                // to the process, do that now.
17362                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17363                    switch (app.curProcState) {
17364                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17365                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17366                            // This process is a cached process holding activities...
17367                            // assign it the next cached value for that type, and then
17368                            // step that cached level.
17369                            app.curRawAdj = curCachedAdj;
17370                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17371                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17372                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17373                                    + ")");
17374                            if (curCachedAdj != nextCachedAdj) {
17375                                stepCached++;
17376                                if (stepCached >= cachedFactor) {
17377                                    stepCached = 0;
17378                                    curCachedAdj = nextCachedAdj;
17379                                    nextCachedAdj += 2;
17380                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17381                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17382                                    }
17383                                }
17384                            }
17385                            break;
17386                        default:
17387                            // For everything else, assign next empty cached process
17388                            // level and bump that up.  Note that this means that
17389                            // long-running services that have dropped down to the
17390                            // cached level will be treated as empty (since their process
17391                            // state is still as a service), which is what we want.
17392                            app.curRawAdj = curEmptyAdj;
17393                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17394                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17395                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17396                                    + ")");
17397                            if (curEmptyAdj != nextEmptyAdj) {
17398                                stepEmpty++;
17399                                if (stepEmpty >= emptyFactor) {
17400                                    stepEmpty = 0;
17401                                    curEmptyAdj = nextEmptyAdj;
17402                                    nextEmptyAdj += 2;
17403                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17404                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17405                                    }
17406                                }
17407                            }
17408                            break;
17409                    }
17410                }
17411
17412                applyOomAdjLocked(app, TOP_APP, true, now);
17413
17414                // Count the number of process types.
17415                switch (app.curProcState) {
17416                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17417                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17418                        mNumCachedHiddenProcs++;
17419                        numCached++;
17420                        if (numCached > cachedProcessLimit) {
17421                            app.kill("cached #" + numCached, true);
17422                        }
17423                        break;
17424                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17425                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17426                                && app.lastActivityTime < oldTime) {
17427                            app.kill("empty for "
17428                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17429                                    / 1000) + "s", true);
17430                        } else {
17431                            numEmpty++;
17432                            if (numEmpty > emptyProcessLimit) {
17433                                app.kill("empty #" + numEmpty, true);
17434                            }
17435                        }
17436                        break;
17437                    default:
17438                        mNumNonCachedProcs++;
17439                        break;
17440                }
17441
17442                if (app.isolated && app.services.size() <= 0) {
17443                    // If this is an isolated process, and there are no
17444                    // services running in it, then the process is no longer
17445                    // needed.  We agressively kill these because we can by
17446                    // definition not re-use the same process again, and it is
17447                    // good to avoid having whatever code was running in them
17448                    // left sitting around after no longer needed.
17449                    app.kill("isolated not needed", true);
17450                }
17451
17452                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17453                        && !app.killedByAm) {
17454                    numTrimming++;
17455                }
17456            }
17457        }
17458
17459        mNumServiceProcs = mNewNumServiceProcs;
17460
17461        // Now determine the memory trimming level of background processes.
17462        // Unfortunately we need to start at the back of the list to do this
17463        // properly.  We only do this if the number of background apps we
17464        // are managing to keep around is less than half the maximum we desire;
17465        // if we are keeping a good number around, we'll let them use whatever
17466        // memory they want.
17467        final int numCachedAndEmpty = numCached + numEmpty;
17468        int memFactor;
17469        if (numCached <= ProcessList.TRIM_CACHED_APPS
17470                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17471            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17472                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17473            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17474                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17475            } else {
17476                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17477            }
17478        } else {
17479            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17480        }
17481        // We always allow the memory level to go up (better).  We only allow it to go
17482        // down if we are in a state where that is allowed, *and* the total number of processes
17483        // has gone down since last time.
17484        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17485                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17486                + " last=" + mLastNumProcesses);
17487        if (memFactor > mLastMemoryLevel) {
17488            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17489                memFactor = mLastMemoryLevel;
17490                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17491            }
17492        }
17493        mLastMemoryLevel = memFactor;
17494        mLastNumProcesses = mLruProcesses.size();
17495        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17496        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17497        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17498            if (mLowRamStartTime == 0) {
17499                mLowRamStartTime = now;
17500            }
17501            int step = 0;
17502            int fgTrimLevel;
17503            switch (memFactor) {
17504                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17505                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17506                    break;
17507                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17508                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17509                    break;
17510                default:
17511                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17512                    break;
17513            }
17514            int factor = numTrimming/3;
17515            int minFactor = 2;
17516            if (mHomeProcess != null) minFactor++;
17517            if (mPreviousProcess != null) minFactor++;
17518            if (factor < minFactor) factor = minFactor;
17519            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17520            for (int i=N-1; i>=0; i--) {
17521                ProcessRecord app = mLruProcesses.get(i);
17522                if (allChanged || app.procStateChanged) {
17523                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17524                    app.procStateChanged = false;
17525                }
17526                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17527                        && !app.killedByAm) {
17528                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17529                        try {
17530                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17531                                    "Trimming memory of " + app.processName
17532                                    + " to " + curLevel);
17533                            app.thread.scheduleTrimMemory(curLevel);
17534                        } catch (RemoteException e) {
17535                        }
17536                        if (false) {
17537                            // For now we won't do this; our memory trimming seems
17538                            // to be good enough at this point that destroying
17539                            // activities causes more harm than good.
17540                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17541                                    && app != mHomeProcess && app != mPreviousProcess) {
17542                                // Need to do this on its own message because the stack may not
17543                                // be in a consistent state at this point.
17544                                // For these apps we will also finish their activities
17545                                // to help them free memory.
17546                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17547                            }
17548                        }
17549                    }
17550                    app.trimMemoryLevel = curLevel;
17551                    step++;
17552                    if (step >= factor) {
17553                        step = 0;
17554                        switch (curLevel) {
17555                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17556                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17557                                break;
17558                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17559                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17560                                break;
17561                        }
17562                    }
17563                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17564                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17565                            && app.thread != null) {
17566                        try {
17567                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17568                                    "Trimming memory of heavy-weight " + app.processName
17569                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17570                            app.thread.scheduleTrimMemory(
17571                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17572                        } catch (RemoteException e) {
17573                        }
17574                    }
17575                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17576                } else {
17577                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17578                            || app.systemNoUi) && app.pendingUiClean) {
17579                        // If this application is now in the background and it
17580                        // had done UI, then give it the special trim level to
17581                        // have it free UI resources.
17582                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17583                        if (app.trimMemoryLevel < level && app.thread != null) {
17584                            try {
17585                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17586                                        "Trimming memory of bg-ui " + app.processName
17587                                        + " to " + level);
17588                                app.thread.scheduleTrimMemory(level);
17589                            } catch (RemoteException e) {
17590                            }
17591                        }
17592                        app.pendingUiClean = false;
17593                    }
17594                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17595                        try {
17596                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17597                                    "Trimming memory of fg " + app.processName
17598                                    + " to " + fgTrimLevel);
17599                            app.thread.scheduleTrimMemory(fgTrimLevel);
17600                        } catch (RemoteException e) {
17601                        }
17602                    }
17603                    app.trimMemoryLevel = fgTrimLevel;
17604                }
17605            }
17606        } else {
17607            if (mLowRamStartTime != 0) {
17608                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17609                mLowRamStartTime = 0;
17610            }
17611            for (int i=N-1; i>=0; i--) {
17612                ProcessRecord app = mLruProcesses.get(i);
17613                if (allChanged || app.procStateChanged) {
17614                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17615                    app.procStateChanged = false;
17616                }
17617                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17618                        || app.systemNoUi) && app.pendingUiClean) {
17619                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17620                            && app.thread != null) {
17621                        try {
17622                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17623                                    "Trimming memory of ui hidden " + app.processName
17624                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17625                            app.thread.scheduleTrimMemory(
17626                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17627                        } catch (RemoteException e) {
17628                        }
17629                    }
17630                    app.pendingUiClean = false;
17631                }
17632                app.trimMemoryLevel = 0;
17633            }
17634        }
17635
17636        if (mAlwaysFinishActivities) {
17637            // Need to do this on its own message because the stack may not
17638            // be in a consistent state at this point.
17639            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17640        }
17641
17642        if (allChanged) {
17643            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17644        }
17645
17646        if (mProcessStats.shouldWriteNowLocked(now)) {
17647            mHandler.post(new Runnable() {
17648                @Override public void run() {
17649                    synchronized (ActivityManagerService.this) {
17650                        mProcessStats.writeStateAsyncLocked();
17651                    }
17652                }
17653            });
17654        }
17655
17656        if (DEBUG_OOM_ADJ) {
17657            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17658        }
17659    }
17660
17661    final void trimApplications() {
17662        synchronized (this) {
17663            int i;
17664
17665            // First remove any unused application processes whose package
17666            // has been removed.
17667            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17668                final ProcessRecord app = mRemovedProcesses.get(i);
17669                if (app.activities.size() == 0
17670                        && app.curReceiver == null && app.services.size() == 0) {
17671                    Slog.i(
17672                        TAG, "Exiting empty application process "
17673                        + app.processName + " ("
17674                        + (app.thread != null ? app.thread.asBinder() : null)
17675                        + ")\n");
17676                    if (app.pid > 0 && app.pid != MY_PID) {
17677                        app.kill("empty", false);
17678                    } else {
17679                        try {
17680                            app.thread.scheduleExit();
17681                        } catch (Exception e) {
17682                            // Ignore exceptions.
17683                        }
17684                    }
17685                    cleanUpApplicationRecordLocked(app, false, true, -1);
17686                    mRemovedProcesses.remove(i);
17687
17688                    if (app.persistent) {
17689                        addAppLocked(app.info, false, null /* ABI override */);
17690                    }
17691                }
17692            }
17693
17694            // Now update the oom adj for all processes.
17695            updateOomAdjLocked();
17696        }
17697    }
17698
17699    /** This method sends the specified signal to each of the persistent apps */
17700    public void signalPersistentProcesses(int sig) throws RemoteException {
17701        if (sig != Process.SIGNAL_USR1) {
17702            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17703        }
17704
17705        synchronized (this) {
17706            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17707                    != PackageManager.PERMISSION_GRANTED) {
17708                throw new SecurityException("Requires permission "
17709                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17710            }
17711
17712            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17713                ProcessRecord r = mLruProcesses.get(i);
17714                if (r.thread != null && r.persistent) {
17715                    Process.sendSignal(r.pid, sig);
17716                }
17717            }
17718        }
17719    }
17720
17721    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17722        if (proc == null || proc == mProfileProc) {
17723            proc = mProfileProc;
17724            profileType = mProfileType;
17725            clearProfilerLocked();
17726        }
17727        if (proc == null) {
17728            return;
17729        }
17730        try {
17731            proc.thread.profilerControl(false, null, profileType);
17732        } catch (RemoteException e) {
17733            throw new IllegalStateException("Process disappeared");
17734        }
17735    }
17736
17737    private void clearProfilerLocked() {
17738        if (mProfileFd != null) {
17739            try {
17740                mProfileFd.close();
17741            } catch (IOException e) {
17742            }
17743        }
17744        mProfileApp = null;
17745        mProfileProc = null;
17746        mProfileFile = null;
17747        mProfileType = 0;
17748        mAutoStopProfiler = false;
17749        mSamplingInterval = 0;
17750    }
17751
17752    public boolean profileControl(String process, int userId, boolean start,
17753            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17754
17755        try {
17756            synchronized (this) {
17757                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17758                // its own permission.
17759                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17760                        != PackageManager.PERMISSION_GRANTED) {
17761                    throw new SecurityException("Requires permission "
17762                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17763                }
17764
17765                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17766                    throw new IllegalArgumentException("null profile info or fd");
17767                }
17768
17769                ProcessRecord proc = null;
17770                if (process != null) {
17771                    proc = findProcessLocked(process, userId, "profileControl");
17772                }
17773
17774                if (start && (proc == null || proc.thread == null)) {
17775                    throw new IllegalArgumentException("Unknown process: " + process);
17776                }
17777
17778                if (start) {
17779                    stopProfilerLocked(null, 0);
17780                    setProfileApp(proc.info, proc.processName, profilerInfo);
17781                    mProfileProc = proc;
17782                    mProfileType = profileType;
17783                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17784                    try {
17785                        fd = fd.dup();
17786                    } catch (IOException e) {
17787                        fd = null;
17788                    }
17789                    profilerInfo.profileFd = fd;
17790                    proc.thread.profilerControl(start, profilerInfo, profileType);
17791                    fd = null;
17792                    mProfileFd = null;
17793                } else {
17794                    stopProfilerLocked(proc, profileType);
17795                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17796                        try {
17797                            profilerInfo.profileFd.close();
17798                        } catch (IOException e) {
17799                        }
17800                    }
17801                }
17802
17803                return true;
17804            }
17805        } catch (RemoteException e) {
17806            throw new IllegalStateException("Process disappeared");
17807        } finally {
17808            if (profilerInfo != null && profilerInfo.profileFd != null) {
17809                try {
17810                    profilerInfo.profileFd.close();
17811                } catch (IOException e) {
17812                }
17813            }
17814        }
17815    }
17816
17817    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17818        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17819                userId, true, ALLOW_FULL_ONLY, callName, null);
17820        ProcessRecord proc = null;
17821        try {
17822            int pid = Integer.parseInt(process);
17823            synchronized (mPidsSelfLocked) {
17824                proc = mPidsSelfLocked.get(pid);
17825            }
17826        } catch (NumberFormatException e) {
17827        }
17828
17829        if (proc == null) {
17830            ArrayMap<String, SparseArray<ProcessRecord>> all
17831                    = mProcessNames.getMap();
17832            SparseArray<ProcessRecord> procs = all.get(process);
17833            if (procs != null && procs.size() > 0) {
17834                proc = procs.valueAt(0);
17835                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17836                    for (int i=1; i<procs.size(); i++) {
17837                        ProcessRecord thisProc = procs.valueAt(i);
17838                        if (thisProc.userId == userId) {
17839                            proc = thisProc;
17840                            break;
17841                        }
17842                    }
17843                }
17844            }
17845        }
17846
17847        return proc;
17848    }
17849
17850    public boolean dumpHeap(String process, int userId, boolean managed,
17851            String path, ParcelFileDescriptor fd) throws RemoteException {
17852
17853        try {
17854            synchronized (this) {
17855                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17856                // its own permission (same as profileControl).
17857                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17858                        != PackageManager.PERMISSION_GRANTED) {
17859                    throw new SecurityException("Requires permission "
17860                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17861                }
17862
17863                if (fd == null) {
17864                    throw new IllegalArgumentException("null fd");
17865                }
17866
17867                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17868                if (proc == null || proc.thread == null) {
17869                    throw new IllegalArgumentException("Unknown process: " + process);
17870                }
17871
17872                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17873                if (!isDebuggable) {
17874                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17875                        throw new SecurityException("Process not debuggable: " + proc);
17876                    }
17877                }
17878
17879                proc.thread.dumpHeap(managed, path, fd);
17880                fd = null;
17881                return true;
17882            }
17883        } catch (RemoteException e) {
17884            throw new IllegalStateException("Process disappeared");
17885        } finally {
17886            if (fd != null) {
17887                try {
17888                    fd.close();
17889                } catch (IOException e) {
17890                }
17891            }
17892        }
17893    }
17894
17895    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17896    public void monitor() {
17897        synchronized (this) { }
17898    }
17899
17900    void onCoreSettingsChange(Bundle settings) {
17901        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17902            ProcessRecord processRecord = mLruProcesses.get(i);
17903            try {
17904                if (processRecord.thread != null) {
17905                    processRecord.thread.setCoreSettings(settings);
17906                }
17907            } catch (RemoteException re) {
17908                /* ignore */
17909            }
17910        }
17911    }
17912
17913    // Multi-user methods
17914
17915    /**
17916     * Start user, if its not already running, but don't bring it to foreground.
17917     */
17918    @Override
17919    public boolean startUserInBackground(final int userId) {
17920        return startUser(userId, /* foreground */ false);
17921    }
17922
17923    /**
17924     * Start user, if its not already running, and bring it to foreground.
17925     */
17926    boolean startUserInForeground(final int userId, Dialog dlg) {
17927        boolean result = startUser(userId, /* foreground */ true);
17928        dlg.dismiss();
17929        return result;
17930    }
17931
17932    /**
17933     * Refreshes the list of users related to the current user when either a
17934     * user switch happens or when a new related user is started in the
17935     * background.
17936     */
17937    private void updateCurrentProfileIdsLocked() {
17938        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17939                mCurrentUserId, false /* enabledOnly */);
17940        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17941        for (int i = 0; i < currentProfileIds.length; i++) {
17942            currentProfileIds[i] = profiles.get(i).id;
17943        }
17944        mCurrentProfileIds = currentProfileIds;
17945
17946        synchronized (mUserProfileGroupIdsSelfLocked) {
17947            mUserProfileGroupIdsSelfLocked.clear();
17948            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17949            for (int i = 0; i < users.size(); i++) {
17950                UserInfo user = users.get(i);
17951                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17952                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17953                }
17954            }
17955        }
17956    }
17957
17958    private Set getProfileIdsLocked(int userId) {
17959        Set userIds = new HashSet<Integer>();
17960        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17961                userId, false /* enabledOnly */);
17962        for (UserInfo user : profiles) {
17963            userIds.add(Integer.valueOf(user.id));
17964        }
17965        return userIds;
17966    }
17967
17968    @Override
17969    public boolean switchUser(final int userId) {
17970        String userName;
17971        synchronized (this) {
17972            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17973            if (userInfo == null) {
17974                Slog.w(TAG, "No user info for user #" + userId);
17975                return false;
17976            }
17977            if (userInfo.isManagedProfile()) {
17978                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17979                return false;
17980            }
17981            userName = userInfo.name;
17982            mTargetUserId = userId;
17983        }
17984        mHandler.removeMessages(START_USER_SWITCH_MSG);
17985        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17986        return true;
17987    }
17988
17989    private void showUserSwitchDialog(int userId, String userName) {
17990        // The dialog will show and then initiate the user switch by calling startUserInForeground
17991        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17992                true /* above system */);
17993        d.show();
17994    }
17995
17996    private boolean startUser(final int userId, final boolean foreground) {
17997        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17998                != PackageManager.PERMISSION_GRANTED) {
17999            String msg = "Permission Denial: switchUser() from pid="
18000                    + Binder.getCallingPid()
18001                    + ", uid=" + Binder.getCallingUid()
18002                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18003            Slog.w(TAG, msg);
18004            throw new SecurityException(msg);
18005        }
18006
18007        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18008
18009        final long ident = Binder.clearCallingIdentity();
18010        try {
18011            synchronized (this) {
18012                final int oldUserId = mCurrentUserId;
18013                if (oldUserId == userId) {
18014                    return true;
18015                }
18016
18017                mStackSupervisor.setLockTaskModeLocked(null, false);
18018
18019                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18020                if (userInfo == null) {
18021                    Slog.w(TAG, "No user info for user #" + userId);
18022                    return false;
18023                }
18024                if (foreground && userInfo.isManagedProfile()) {
18025                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18026                    return false;
18027                }
18028
18029                if (foreground) {
18030                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18031                            R.anim.screen_user_enter);
18032                }
18033
18034                boolean needStart = false;
18035
18036                // If the user we are switching to is not currently started, then
18037                // we need to start it now.
18038                if (mStartedUsers.get(userId) == null) {
18039                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18040                    updateStartedUserArrayLocked();
18041                    needStart = true;
18042                }
18043
18044                final Integer userIdInt = Integer.valueOf(userId);
18045                mUserLru.remove(userIdInt);
18046                mUserLru.add(userIdInt);
18047
18048                if (foreground) {
18049                    mCurrentUserId = userId;
18050                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18051                    updateCurrentProfileIdsLocked();
18052                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18053                    // Once the internal notion of the active user has switched, we lock the device
18054                    // with the option to show the user switcher on the keyguard.
18055                    mWindowManager.lockNow(null);
18056                } else {
18057                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18058                    updateCurrentProfileIdsLocked();
18059                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18060                    mUserLru.remove(currentUserIdInt);
18061                    mUserLru.add(currentUserIdInt);
18062                }
18063
18064                final UserStartedState uss = mStartedUsers.get(userId);
18065
18066                // Make sure user is in the started state.  If it is currently
18067                // stopping, we need to knock that off.
18068                if (uss.mState == UserStartedState.STATE_STOPPING) {
18069                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18070                    // so we can just fairly silently bring the user back from
18071                    // the almost-dead.
18072                    uss.mState = UserStartedState.STATE_RUNNING;
18073                    updateStartedUserArrayLocked();
18074                    needStart = true;
18075                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18076                    // This means ACTION_SHUTDOWN has been sent, so we will
18077                    // need to treat this as a new boot of the user.
18078                    uss.mState = UserStartedState.STATE_BOOTING;
18079                    updateStartedUserArrayLocked();
18080                    needStart = true;
18081                }
18082
18083                if (uss.mState == UserStartedState.STATE_BOOTING) {
18084                    // Booting up a new user, need to tell system services about it.
18085                    // Note that this is on the same handler as scheduling of broadcasts,
18086                    // which is important because it needs to go first.
18087                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18088                }
18089
18090                if (foreground) {
18091                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18092                            oldUserId));
18093                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18094                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18095                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18096                            oldUserId, userId, uss));
18097                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18098                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18099                }
18100
18101                if (needStart) {
18102                    // Send USER_STARTED broadcast
18103                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18104                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18105                            | Intent.FLAG_RECEIVER_FOREGROUND);
18106                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18107                    broadcastIntentLocked(null, null, intent,
18108                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18109                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18110                }
18111
18112                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18113                    if (userId != UserHandle.USER_OWNER) {
18114                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18115                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18116                        broadcastIntentLocked(null, null, intent, null,
18117                                new IIntentReceiver.Stub() {
18118                                    public void performReceive(Intent intent, int resultCode,
18119                                            String data, Bundle extras, boolean ordered,
18120                                            boolean sticky, int sendingUser) {
18121                                        onUserInitialized(uss, foreground, oldUserId, userId);
18122                                    }
18123                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18124                                true, false, MY_PID, Process.SYSTEM_UID,
18125                                userId);
18126                        uss.initializing = true;
18127                    } else {
18128                        getUserManagerLocked().makeInitialized(userInfo.id);
18129                    }
18130                }
18131
18132                if (foreground) {
18133                    if (!uss.initializing) {
18134                        moveUserToForeground(uss, oldUserId, userId);
18135                    }
18136                } else {
18137                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18138                }
18139
18140                if (needStart) {
18141                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18142                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18143                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18144                    broadcastIntentLocked(null, null, intent,
18145                            null, new IIntentReceiver.Stub() {
18146                                @Override
18147                                public void performReceive(Intent intent, int resultCode, String data,
18148                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18149                                        throws RemoteException {
18150                                }
18151                            }, 0, null, null,
18152                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18153                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18154                }
18155            }
18156        } finally {
18157            Binder.restoreCallingIdentity(ident);
18158        }
18159
18160        return true;
18161    }
18162
18163    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18164        long ident = Binder.clearCallingIdentity();
18165        try {
18166            Intent intent;
18167            if (oldUserId >= 0) {
18168                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18169                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18170                int count = profiles.size();
18171                for (int i = 0; i < count; i++) {
18172                    int profileUserId = profiles.get(i).id;
18173                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18174                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18175                            | Intent.FLAG_RECEIVER_FOREGROUND);
18176                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18177                    broadcastIntentLocked(null, null, intent,
18178                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18179                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18180                }
18181            }
18182            if (newUserId >= 0) {
18183                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18184                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18185                int count = profiles.size();
18186                for (int i = 0; i < count; i++) {
18187                    int profileUserId = profiles.get(i).id;
18188                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18189                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18190                            | Intent.FLAG_RECEIVER_FOREGROUND);
18191                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18192                    broadcastIntentLocked(null, null, intent,
18193                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18194                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18195                }
18196                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18197                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18198                        | Intent.FLAG_RECEIVER_FOREGROUND);
18199                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18200                broadcastIntentLocked(null, null, intent,
18201                        null, null, 0, null, null,
18202                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18203                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18204            }
18205        } finally {
18206            Binder.restoreCallingIdentity(ident);
18207        }
18208    }
18209
18210    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18211            final int newUserId) {
18212        final int N = mUserSwitchObservers.beginBroadcast();
18213        if (N > 0) {
18214            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18215                int mCount = 0;
18216                @Override
18217                public void sendResult(Bundle data) throws RemoteException {
18218                    synchronized (ActivityManagerService.this) {
18219                        if (mCurUserSwitchCallback == this) {
18220                            mCount++;
18221                            if (mCount == N) {
18222                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18223                            }
18224                        }
18225                    }
18226                }
18227            };
18228            synchronized (this) {
18229                uss.switching = true;
18230                mCurUserSwitchCallback = callback;
18231            }
18232            for (int i=0; i<N; i++) {
18233                try {
18234                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18235                            newUserId, callback);
18236                } catch (RemoteException e) {
18237                }
18238            }
18239        } else {
18240            synchronized (this) {
18241                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18242            }
18243        }
18244        mUserSwitchObservers.finishBroadcast();
18245    }
18246
18247    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18248        synchronized (this) {
18249            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18250            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18251        }
18252    }
18253
18254    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18255        mCurUserSwitchCallback = null;
18256        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18257        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18258                oldUserId, newUserId, uss));
18259    }
18260
18261    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18262        synchronized (this) {
18263            if (foreground) {
18264                moveUserToForeground(uss, oldUserId, newUserId);
18265            }
18266        }
18267
18268        completeSwitchAndInitalize(uss, newUserId, true, false);
18269    }
18270
18271    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18272        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18273        if (homeInFront) {
18274            startHomeActivityLocked(newUserId);
18275        } else {
18276            mStackSupervisor.resumeTopActivitiesLocked();
18277        }
18278        EventLogTags.writeAmSwitchUser(newUserId);
18279        getUserManagerLocked().userForeground(newUserId);
18280        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18281    }
18282
18283    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18284        completeSwitchAndInitalize(uss, newUserId, false, true);
18285    }
18286
18287    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18288            boolean clearInitializing, boolean clearSwitching) {
18289        boolean unfrozen = false;
18290        synchronized (this) {
18291            if (clearInitializing) {
18292                uss.initializing = false;
18293                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18294            }
18295            if (clearSwitching) {
18296                uss.switching = false;
18297            }
18298            if (!uss.switching && !uss.initializing) {
18299                mWindowManager.stopFreezingScreen();
18300                unfrozen = true;
18301            }
18302        }
18303        if (unfrozen) {
18304            final int N = mUserSwitchObservers.beginBroadcast();
18305            for (int i=0; i<N; i++) {
18306                try {
18307                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18308                } catch (RemoteException e) {
18309                }
18310            }
18311            mUserSwitchObservers.finishBroadcast();
18312        }
18313    }
18314
18315    void scheduleStartProfilesLocked() {
18316        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18317            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18318                    DateUtils.SECOND_IN_MILLIS);
18319        }
18320    }
18321
18322    void startProfilesLocked() {
18323        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18324        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18325                mCurrentUserId, false /* enabledOnly */);
18326        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18327        for (UserInfo user : profiles) {
18328            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18329                    && user.id != mCurrentUserId) {
18330                toStart.add(user);
18331            }
18332        }
18333        final int n = toStart.size();
18334        int i = 0;
18335        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18336            startUserInBackground(toStart.get(i).id);
18337        }
18338        if (i < n) {
18339            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18340        }
18341    }
18342
18343    void finishUserBoot(UserStartedState uss) {
18344        synchronized (this) {
18345            if (uss.mState == UserStartedState.STATE_BOOTING
18346                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18347                uss.mState = UserStartedState.STATE_RUNNING;
18348                final int userId = uss.mHandle.getIdentifier();
18349                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18350                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18351                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18352                broadcastIntentLocked(null, null, intent,
18353                        null, null, 0, null, null,
18354                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18355                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18356            }
18357        }
18358    }
18359
18360    void finishUserSwitch(UserStartedState uss) {
18361        synchronized (this) {
18362            finishUserBoot(uss);
18363
18364            startProfilesLocked();
18365
18366            int num = mUserLru.size();
18367            int i = 0;
18368            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18369                Integer oldUserId = mUserLru.get(i);
18370                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18371                if (oldUss == null) {
18372                    // Shouldn't happen, but be sane if it does.
18373                    mUserLru.remove(i);
18374                    num--;
18375                    continue;
18376                }
18377                if (oldUss.mState == UserStartedState.STATE_STOPPING
18378                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18379                    // This user is already stopping, doesn't count.
18380                    num--;
18381                    i++;
18382                    continue;
18383                }
18384                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18385                    // Owner and current can't be stopped, but count as running.
18386                    i++;
18387                    continue;
18388                }
18389                // This is a user to be stopped.
18390                stopUserLocked(oldUserId, null);
18391                num--;
18392                i++;
18393            }
18394        }
18395    }
18396
18397    @Override
18398    public int stopUser(final int userId, final IStopUserCallback callback) {
18399        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18400                != PackageManager.PERMISSION_GRANTED) {
18401            String msg = "Permission Denial: switchUser() from pid="
18402                    + Binder.getCallingPid()
18403                    + ", uid=" + Binder.getCallingUid()
18404                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18405            Slog.w(TAG, msg);
18406            throw new SecurityException(msg);
18407        }
18408        if (userId <= 0) {
18409            throw new IllegalArgumentException("Can't stop primary user " + userId);
18410        }
18411        synchronized (this) {
18412            return stopUserLocked(userId, callback);
18413        }
18414    }
18415
18416    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18417        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18418        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18419            return ActivityManager.USER_OP_IS_CURRENT;
18420        }
18421
18422        final UserStartedState uss = mStartedUsers.get(userId);
18423        if (uss == null) {
18424            // User is not started, nothing to do...  but we do need to
18425            // callback if requested.
18426            if (callback != null) {
18427                mHandler.post(new Runnable() {
18428                    @Override
18429                    public void run() {
18430                        try {
18431                            callback.userStopped(userId);
18432                        } catch (RemoteException e) {
18433                        }
18434                    }
18435                });
18436            }
18437            return ActivityManager.USER_OP_SUCCESS;
18438        }
18439
18440        if (callback != null) {
18441            uss.mStopCallbacks.add(callback);
18442        }
18443
18444        if (uss.mState != UserStartedState.STATE_STOPPING
18445                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18446            uss.mState = UserStartedState.STATE_STOPPING;
18447            updateStartedUserArrayLocked();
18448
18449            long ident = Binder.clearCallingIdentity();
18450            try {
18451                // We are going to broadcast ACTION_USER_STOPPING and then
18452                // once that is done send a final ACTION_SHUTDOWN and then
18453                // stop the user.
18454                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18455                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18456                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18457                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18458                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18459                // This is the result receiver for the final shutdown broadcast.
18460                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18461                    @Override
18462                    public void performReceive(Intent intent, int resultCode, String data,
18463                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18464                        finishUserStop(uss);
18465                    }
18466                };
18467                // This is the result receiver for the initial stopping broadcast.
18468                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18469                    @Override
18470                    public void performReceive(Intent intent, int resultCode, String data,
18471                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18472                        // On to the next.
18473                        synchronized (ActivityManagerService.this) {
18474                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18475                                // Whoops, we are being started back up.  Abort, abort!
18476                                return;
18477                            }
18478                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18479                        }
18480                        mBatteryStatsService.noteEvent(
18481                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18482                                Integer.toString(userId), userId);
18483                        mSystemServiceManager.stopUser(userId);
18484                        broadcastIntentLocked(null, null, shutdownIntent,
18485                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18486                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18487                    }
18488                };
18489                // Kick things off.
18490                broadcastIntentLocked(null, null, stoppingIntent,
18491                        null, stoppingReceiver, 0, null, null,
18492                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18493                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18494            } finally {
18495                Binder.restoreCallingIdentity(ident);
18496            }
18497        }
18498
18499        return ActivityManager.USER_OP_SUCCESS;
18500    }
18501
18502    void finishUserStop(UserStartedState uss) {
18503        final int userId = uss.mHandle.getIdentifier();
18504        boolean stopped;
18505        ArrayList<IStopUserCallback> callbacks;
18506        synchronized (this) {
18507            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18508            if (mStartedUsers.get(userId) != uss) {
18509                stopped = false;
18510            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18511                stopped = false;
18512            } else {
18513                stopped = true;
18514                // User can no longer run.
18515                mStartedUsers.remove(userId);
18516                mUserLru.remove(Integer.valueOf(userId));
18517                updateStartedUserArrayLocked();
18518
18519                // Clean up all state and processes associated with the user.
18520                // Kill all the processes for the user.
18521                forceStopUserLocked(userId, "finish user");
18522            }
18523
18524            // Explicitly remove the old information in mRecentTasks.
18525            removeRecentTasksForUserLocked(userId);
18526        }
18527
18528        for (int i=0; i<callbacks.size(); i++) {
18529            try {
18530                if (stopped) callbacks.get(i).userStopped(userId);
18531                else callbacks.get(i).userStopAborted(userId);
18532            } catch (RemoteException e) {
18533            }
18534        }
18535
18536        if (stopped) {
18537            mSystemServiceManager.cleanupUser(userId);
18538            synchronized (this) {
18539                mStackSupervisor.removeUserLocked(userId);
18540            }
18541        }
18542    }
18543
18544    @Override
18545    public UserInfo getCurrentUser() {
18546        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18547                != PackageManager.PERMISSION_GRANTED) && (
18548                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18549                != PackageManager.PERMISSION_GRANTED)) {
18550            String msg = "Permission Denial: getCurrentUser() from pid="
18551                    + Binder.getCallingPid()
18552                    + ", uid=" + Binder.getCallingUid()
18553                    + " requires " + INTERACT_ACROSS_USERS;
18554            Slog.w(TAG, msg);
18555            throw new SecurityException(msg);
18556        }
18557        synchronized (this) {
18558            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18559            return getUserManagerLocked().getUserInfo(userId);
18560        }
18561    }
18562
18563    int getCurrentUserIdLocked() {
18564        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18565    }
18566
18567    @Override
18568    public boolean isUserRunning(int userId, boolean orStopped) {
18569        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18570                != PackageManager.PERMISSION_GRANTED) {
18571            String msg = "Permission Denial: isUserRunning() from pid="
18572                    + Binder.getCallingPid()
18573                    + ", uid=" + Binder.getCallingUid()
18574                    + " requires " + INTERACT_ACROSS_USERS;
18575            Slog.w(TAG, msg);
18576            throw new SecurityException(msg);
18577        }
18578        synchronized (this) {
18579            return isUserRunningLocked(userId, orStopped);
18580        }
18581    }
18582
18583    boolean isUserRunningLocked(int userId, boolean orStopped) {
18584        UserStartedState state = mStartedUsers.get(userId);
18585        if (state == null) {
18586            return false;
18587        }
18588        if (orStopped) {
18589            return true;
18590        }
18591        return state.mState != UserStartedState.STATE_STOPPING
18592                && state.mState != UserStartedState.STATE_SHUTDOWN;
18593    }
18594
18595    @Override
18596    public int[] getRunningUserIds() {
18597        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18598                != PackageManager.PERMISSION_GRANTED) {
18599            String msg = "Permission Denial: isUserRunning() from pid="
18600                    + Binder.getCallingPid()
18601                    + ", uid=" + Binder.getCallingUid()
18602                    + " requires " + INTERACT_ACROSS_USERS;
18603            Slog.w(TAG, msg);
18604            throw new SecurityException(msg);
18605        }
18606        synchronized (this) {
18607            return mStartedUserArray;
18608        }
18609    }
18610
18611    private void updateStartedUserArrayLocked() {
18612        int num = 0;
18613        for (int i=0; i<mStartedUsers.size();  i++) {
18614            UserStartedState uss = mStartedUsers.valueAt(i);
18615            // This list does not include stopping users.
18616            if (uss.mState != UserStartedState.STATE_STOPPING
18617                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18618                num++;
18619            }
18620        }
18621        mStartedUserArray = new int[num];
18622        num = 0;
18623        for (int i=0; i<mStartedUsers.size();  i++) {
18624            UserStartedState uss = mStartedUsers.valueAt(i);
18625            if (uss.mState != UserStartedState.STATE_STOPPING
18626                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18627                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18628                num++;
18629            }
18630        }
18631    }
18632
18633    @Override
18634    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18635        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18636                != PackageManager.PERMISSION_GRANTED) {
18637            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18638                    + Binder.getCallingPid()
18639                    + ", uid=" + Binder.getCallingUid()
18640                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18641            Slog.w(TAG, msg);
18642            throw new SecurityException(msg);
18643        }
18644
18645        mUserSwitchObservers.register(observer);
18646    }
18647
18648    @Override
18649    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18650        mUserSwitchObservers.unregister(observer);
18651    }
18652
18653    private boolean userExists(int userId) {
18654        if (userId == 0) {
18655            return true;
18656        }
18657        UserManagerService ums = getUserManagerLocked();
18658        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18659    }
18660
18661    int[] getUsersLocked() {
18662        UserManagerService ums = getUserManagerLocked();
18663        return ums != null ? ums.getUserIds() : new int[] { 0 };
18664    }
18665
18666    UserManagerService getUserManagerLocked() {
18667        if (mUserManager == null) {
18668            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18669            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18670        }
18671        return mUserManager;
18672    }
18673
18674    private int applyUserId(int uid, int userId) {
18675        return UserHandle.getUid(userId, uid);
18676    }
18677
18678    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18679        if (info == null) return null;
18680        ApplicationInfo newInfo = new ApplicationInfo(info);
18681        newInfo.uid = applyUserId(info.uid, userId);
18682        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18683                + info.packageName;
18684        return newInfo;
18685    }
18686
18687    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18688        if (aInfo == null
18689                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18690            return aInfo;
18691        }
18692
18693        ActivityInfo info = new ActivityInfo(aInfo);
18694        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18695        return info;
18696    }
18697
18698    private final class LocalService extends ActivityManagerInternal {
18699        @Override
18700        public void goingToSleep() {
18701            ActivityManagerService.this.goingToSleep();
18702        }
18703
18704        @Override
18705        public void wakingUp() {
18706            ActivityManagerService.this.wakingUp();
18707        }
18708
18709        @Override
18710        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18711                String processName, String abiOverride, int uid, Runnable crashHandler) {
18712            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18713                    processName, abiOverride, uid, crashHandler);
18714        }
18715    }
18716
18717    /**
18718     * An implementation of IAppTask, that allows an app to manage its own tasks via
18719     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18720     * only the process that calls getAppTasks() can call the AppTask methods.
18721     */
18722    class AppTaskImpl extends IAppTask.Stub {
18723        private int mTaskId;
18724        private int mCallingUid;
18725
18726        public AppTaskImpl(int taskId, int callingUid) {
18727            mTaskId = taskId;
18728            mCallingUid = callingUid;
18729        }
18730
18731        private void checkCaller() {
18732            if (mCallingUid != Binder.getCallingUid()) {
18733                throw new SecurityException("Caller " + mCallingUid
18734                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18735            }
18736        }
18737
18738        @Override
18739        public void finishAndRemoveTask() {
18740            checkCaller();
18741
18742            synchronized (ActivityManagerService.this) {
18743                long origId = Binder.clearCallingIdentity();
18744                try {
18745                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18746                    if (tr == null) {
18747                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18748                    }
18749                    // Only kill the process if we are not a new document
18750                    int flags = tr.getBaseIntent().getFlags();
18751                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18752                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18753                    removeTaskByIdLocked(mTaskId,
18754                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18755                } finally {
18756                    Binder.restoreCallingIdentity(origId);
18757                }
18758            }
18759        }
18760
18761        @Override
18762        public ActivityManager.RecentTaskInfo getTaskInfo() {
18763            checkCaller();
18764
18765            synchronized (ActivityManagerService.this) {
18766                long origId = Binder.clearCallingIdentity();
18767                try {
18768                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18769                    if (tr == null) {
18770                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18771                    }
18772                    return createRecentTaskInfoFromTaskRecord(tr);
18773                } finally {
18774                    Binder.restoreCallingIdentity(origId);
18775                }
18776            }
18777        }
18778
18779        @Override
18780        public void moveToFront() {
18781            checkCaller();
18782
18783            final TaskRecord tr;
18784            synchronized (ActivityManagerService.this) {
18785                tr = recentTaskForIdLocked(mTaskId);
18786                if (tr == null) {
18787                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18788                }
18789                if (tr.getRootActivity() != null) {
18790                    long origId = Binder.clearCallingIdentity();
18791                    try {
18792                        moveTaskToFrontLocked(tr.taskId, 0, null);
18793                        return;
18794                    } finally {
18795                        Binder.restoreCallingIdentity(origId);
18796                    }
18797                }
18798            }
18799
18800            startActivityFromRecentsInner(tr.taskId, null);
18801        }
18802
18803        @Override
18804        public int startActivity(IBinder whoThread, String callingPackage,
18805                Intent intent, String resolvedType, Bundle options) {
18806            checkCaller();
18807
18808            int callingUser = UserHandle.getCallingUserId();
18809            TaskRecord tr;
18810            IApplicationThread appThread;
18811            synchronized (ActivityManagerService.this) {
18812                tr = recentTaskForIdLocked(mTaskId);
18813                if (tr == null) {
18814                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18815                }
18816                appThread = ApplicationThreadNative.asInterface(whoThread);
18817                if (appThread == null) {
18818                    throw new IllegalArgumentException("Bad app thread " + appThread);
18819                }
18820            }
18821            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18822                    resolvedType, null, null, null, null, 0, 0, null, null,
18823                    null, options, callingUser, null, tr);
18824        }
18825
18826        @Override
18827        public void setExcludeFromRecents(boolean exclude) {
18828            checkCaller();
18829
18830            synchronized (ActivityManagerService.this) {
18831                long origId = Binder.clearCallingIdentity();
18832                try {
18833                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18834                    if (tr == null) {
18835                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18836                    }
18837                    Intent intent = tr.getBaseIntent();
18838                    if (exclude) {
18839                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18840                    } else {
18841                        intent.setFlags(intent.getFlags()
18842                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18843                    }
18844                } finally {
18845                    Binder.restoreCallingIdentity(origId);
18846                }
18847            }
18848        }
18849    }
18850}
18851