ActivityManagerService.java revision 7805a10c86a2de9fb5ddf41d63075eef342a59ea
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.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageEvents;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.content.res.Resources;
44import android.graphics.Bitmap;
45import android.graphics.Point;
46import android.graphics.Rect;
47import android.os.BatteryStats;
48import android.os.PersistableBundle;
49import android.service.voice.IVoiceInteractionSession;
50import android.util.ArrayMap;
51import android.util.ArraySet;
52import android.util.SparseIntArray;
53
54import com.android.internal.R;
55import com.android.internal.annotations.GuardedBy;
56import com.android.internal.app.IAppOpsService;
57import com.android.internal.app.IVoiceInteractor;
58import com.android.internal.app.ProcessMap;
59import com.android.internal.app.ProcessStats;
60import com.android.internal.content.PackageMonitor;
61import com.android.internal.os.BackgroundThread;
62import com.android.internal.os.BatteryStatsImpl;
63import com.android.internal.os.ProcessCpuTracker;
64import com.android.internal.os.TransferPipe;
65import com.android.internal.os.Zygote;
66import com.android.internal.util.FastPrintWriter;
67import com.android.internal.util.FastXmlSerializer;
68import com.android.internal.util.MemInfoReader;
69import com.android.internal.util.Preconditions;
70import com.android.server.AppOpsService;
71import com.android.server.AttributeCache;
72import com.android.server.IntentResolver;
73import com.android.server.LocalServices;
74import com.android.server.ServiceThread;
75import com.android.server.SystemService;
76import com.android.server.SystemServiceManager;
77import com.android.server.Watchdog;
78import com.android.server.am.ActivityStack.ActivityState;
79import com.android.server.firewall.IntentFirewall;
80import com.android.server.pm.UserManagerService;
81import com.android.server.wm.AppTransition;
82import com.android.server.wm.WindowManagerService;
83import com.google.android.collect.Lists;
84import com.google.android.collect.Maps;
85
86import libcore.io.IoUtils;
87
88import org.xmlpull.v1.XmlPullParser;
89import org.xmlpull.v1.XmlPullParserException;
90import org.xmlpull.v1.XmlSerializer;
91
92import android.app.Activity;
93import android.app.ActivityManager;
94import android.app.ActivityManager.RunningTaskInfo;
95import android.app.ActivityManager.StackInfo;
96import android.app.ActivityManagerInternal;
97import android.app.ActivityManagerNative;
98import android.app.ActivityOptions;
99import android.app.ActivityThread;
100import android.app.AlertDialog;
101import android.app.AppGlobals;
102import android.app.ApplicationErrorReport;
103import android.app.Dialog;
104import android.app.IActivityController;
105import android.app.IApplicationThread;
106import android.app.IInstrumentationWatcher;
107import android.app.INotificationManager;
108import android.app.IProcessObserver;
109import android.app.IServiceConnection;
110import android.app.IStopUserCallback;
111import android.app.IUiAutomationConnection;
112import android.app.IUserSwitchObserver;
113import android.app.Instrumentation;
114import android.app.Notification;
115import android.app.NotificationManager;
116import android.app.PendingIntent;
117import android.app.backup.IBackupManager;
118import android.content.ActivityNotFoundException;
119import android.content.BroadcastReceiver;
120import android.content.ClipData;
121import android.content.ComponentCallbacks2;
122import android.content.ComponentName;
123import android.content.ContentProvider;
124import android.content.ContentResolver;
125import android.content.Context;
126import android.content.DialogInterface;
127import android.content.IContentProvider;
128import android.content.IIntentReceiver;
129import android.content.IIntentSender;
130import android.content.Intent;
131import android.content.IntentFilter;
132import android.content.IntentSender;
133import android.content.pm.ActivityInfo;
134import android.content.pm.ApplicationInfo;
135import android.content.pm.ConfigurationInfo;
136import android.content.pm.IPackageDataObserver;
137import android.content.pm.IPackageManager;
138import android.content.pm.InstrumentationInfo;
139import android.content.pm.PackageInfo;
140import android.content.pm.PackageManager;
141import android.content.pm.ParceledListSlice;
142import android.content.pm.UserInfo;
143import android.content.pm.PackageManager.NameNotFoundException;
144import android.content.pm.PathPermission;
145import android.content.pm.ProviderInfo;
146import android.content.pm.ResolveInfo;
147import android.content.pm.ServiceInfo;
148import android.content.res.CompatibilityInfo;
149import android.content.res.Configuration;
150import android.net.Proxy;
151import android.net.ProxyInfo;
152import android.net.Uri;
153import android.os.Binder;
154import android.os.Build;
155import android.os.Bundle;
156import android.os.Debug;
157import android.os.DropBoxManager;
158import android.os.Environment;
159import android.os.FactoryTest;
160import android.os.FileObserver;
161import android.os.FileUtils;
162import android.os.Handler;
163import android.os.IBinder;
164import android.os.IPermissionController;
165import android.os.IRemoteCallback;
166import android.os.IUserManager;
167import android.os.Looper;
168import android.os.Message;
169import android.os.Parcel;
170import android.os.ParcelFileDescriptor;
171import android.os.Process;
172import android.os.RemoteCallbackList;
173import android.os.RemoteException;
174import android.os.SELinux;
175import android.os.ServiceManager;
176import android.os.StrictMode;
177import android.os.SystemClock;
178import android.os.SystemProperties;
179import android.os.UpdateLock;
180import android.os.UserHandle;
181import android.provider.Settings;
182import android.text.format.DateUtils;
183import android.text.format.Time;
184import android.util.AtomicFile;
185import android.util.EventLog;
186import android.util.Log;
187import android.util.Pair;
188import android.util.PrintWriterPrinter;
189import android.util.Slog;
190import android.util.SparseArray;
191import android.util.TimeUtils;
192import android.util.Xml;
193import android.view.Gravity;
194import android.view.LayoutInflater;
195import android.view.View;
196import android.view.WindowManager;
197
198import java.io.BufferedInputStream;
199import java.io.BufferedOutputStream;
200import java.io.DataInputStream;
201import java.io.DataOutputStream;
202import java.io.File;
203import java.io.FileDescriptor;
204import java.io.FileInputStream;
205import java.io.FileNotFoundException;
206import java.io.FileOutputStream;
207import java.io.IOException;
208import java.io.InputStreamReader;
209import java.io.PrintWriter;
210import java.io.StringWriter;
211import java.lang.ref.WeakReference;
212import java.util.ArrayList;
213import java.util.Arrays;
214import java.util.Collections;
215import java.util.Comparator;
216import java.util.HashMap;
217import java.util.HashSet;
218import java.util.Iterator;
219import java.util.List;
220import java.util.Locale;
221import java.util.Map;
222import java.util.Set;
223import java.util.concurrent.atomic.AtomicBoolean;
224import java.util.concurrent.atomic.AtomicLong;
225
226public final class ActivityManagerService extends ActivityManagerNative
227        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
228
229    private static final String USER_DATA_DIR = "/data/user/";
230    // File that stores last updated system version and called preboot receivers
231    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
232
233    static final String TAG = "ActivityManager";
234    static final String TAG_MU = "ActivityManagerServiceMU";
235    static final boolean DEBUG = false;
236    static final boolean localLOGV = DEBUG;
237    static final boolean DEBUG_BACKUP = localLOGV || false;
238    static final boolean DEBUG_BROADCAST = localLOGV || false;
239    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
240    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
241    static final boolean DEBUG_CLEANUP = localLOGV || false;
242    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
243    static final boolean DEBUG_FOCUS = false;
244    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
245    static final boolean DEBUG_MU = localLOGV || false;
246    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
247    static final boolean DEBUG_LRU = localLOGV || false;
248    static final boolean DEBUG_PAUSE = localLOGV || false;
249    static final boolean DEBUG_POWER = localLOGV || false;
250    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
251    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
252    static final boolean DEBUG_PROCESSES = localLOGV || false;
253    static final boolean DEBUG_PROVIDER = localLOGV || false;
254    static final boolean DEBUG_RESULTS = localLOGV || false;
255    static final boolean DEBUG_SERVICE = localLOGV || false;
256    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
257    static final boolean DEBUG_STACK = localLOGV || false;
258    static final boolean DEBUG_SWITCH = localLOGV || false;
259    static final boolean DEBUG_TASKS = localLOGV || false;
260    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
261    static final boolean DEBUG_TRANSITION = localLOGV || false;
262    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
263    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
264    static final boolean DEBUG_VISBILITY = localLOGV || false;
265    static final boolean DEBUG_PSS = localLOGV || false;
266    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
267    static final boolean DEBUG_RECENTS = localLOGV || false;
268    static final boolean VALIDATE_TOKENS = false;
269    static final boolean SHOW_ACTIVITY_START_TIME = true;
270
271    // Control over CPU and battery monitoring.
272    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
273    static final boolean MONITOR_CPU_USAGE = true;
274    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
275    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
276    static final boolean MONITOR_THREAD_CPU_USAGE = false;
277
278    // The flags that are set for all calls we make to the package manager.
279    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
280
281    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
282
283    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
284
285    // Maximum number of recent tasks that we can remember.
286    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
287
288    // Maximum number recent bitmaps to keep in memory.
289    static final int MAX_RECENT_BITMAPS = 5;
290
291    // Amount of time after a call to stopAppSwitches() during which we will
292    // prevent further untrusted switches from happening.
293    static final long APP_SWITCH_DELAY_TIME = 5*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real.
297    static final int PROC_START_TIMEOUT = 10*1000;
298
299    // How long we wait for a launched process to attach to the activity manager
300    // before we decide it's never going to come up for real, when the process was
301    // started with a wrapper for instrumentation (such as Valgrind) because it
302    // could take much longer than usual.
303    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
304
305    // How long to wait after going idle before forcing apps to GC.
306    static final int GC_TIMEOUT = 5*1000;
307
308    // The minimum amount of time between successive GC requests for a process.
309    static final int GC_MIN_INTERVAL = 60*1000;
310
311    // The minimum amount of time between successive PSS requests for a process.
312    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process
315    // when the request is due to the memory state being lowered.
316    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
317
318    // The rate at which we check for apps using excessive power -- 15 mins.
319    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on wake locks to start killing things.
323    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on CPU usage to start killing things.
327    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // How long we allow a receiver to run before giving up on it.
330    static final int BROADCAST_FG_TIMEOUT = 10*1000;
331    static final int BROADCAST_BG_TIMEOUT = 60*1000;
332
333    // How long we wait until we timeout on key dispatching.
334    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
335
336    // How long we wait until we timeout on key dispatching during instrumentation.
337    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
338
339    // Amount of time we wait for observers to handle a user switch before
340    // giving up on them and unfreezing the screen.
341    static final int USER_SWITCH_TIMEOUT = 2*1000;
342
343    // Maximum number of users we allow to be running at a time.
344    static final int MAX_RUNNING_USERS = 3;
345
346    // How long to wait in getAssistContextExtras for the activity and foreground services
347    // to respond with the result.
348    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
349
350    // Maximum number of persisted Uri grants a package is allowed
351    static final int MAX_PERSISTED_URI_GRANTS = 128;
352
353    static final int MY_PID = Process.myPid();
354
355    static final String[] EMPTY_STRING_ARRAY = new String[0];
356
357    // How many bytes to write into the dropbox log before truncating
358    static final int DROPBOX_MAX_SIZE = 256 * 1024;
359
360    // Access modes for handleIncomingUser.
361    static final int ALLOW_NON_FULL = 0;
362    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
363    static final int ALLOW_FULL_ONLY = 2;
364
365    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
366
367    /** All system services */
368    SystemServiceManager mSystemServiceManager;
369
370    /** Run all ActivityStacks through this */
371    ActivityStackSupervisor mStackSupervisor;
372
373    public IntentFirewall mIntentFirewall;
374
375    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
376    // default actuion automatically.  Important for devices without direct input
377    // devices.
378    private boolean mShowDialogs = true;
379
380    BroadcastQueue mFgBroadcastQueue;
381    BroadcastQueue mBgBroadcastQueue;
382    // Convenient for easy iteration over the queues. Foreground is first
383    // so that dispatch of foreground broadcasts gets precedence.
384    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
385
386    BroadcastQueue broadcastQueueForIntent(Intent intent) {
387        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
388        if (DEBUG_BACKGROUND_BROADCAST) {
389            Slog.i(TAG, "Broadcast intent " + intent + " on "
390                    + (isFg ? "foreground" : "background")
391                    + " queue");
392        }
393        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
394    }
395
396    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
397        for (BroadcastQueue queue : mBroadcastQueues) {
398            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
399            if (r != null) {
400                return r;
401            }
402        }
403        return null;
404    }
405
406    /**
407     * Activity we have told the window manager to have key focus.
408     */
409    ActivityRecord mFocusedActivity = null;
410
411    /**
412     * List of intents that were used to start the most recent tasks.
413     */
414    ArrayList<TaskRecord> mRecentTasks;
415    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
416
417    /**
418     * For addAppTask: cached of the last activity component that was added.
419     */
420    ComponentName mLastAddedTaskComponent;
421
422    /**
423     * For addAppTask: cached of the last activity uid that was added.
424     */
425    int mLastAddedTaskUid;
426
427    /**
428     * For addAppTask: cached of the last ActivityInfo that was added.
429     */
430    ActivityInfo mLastAddedTaskActivity;
431
432    public class PendingAssistExtras extends Binder implements Runnable {
433        public final ActivityRecord activity;
434        public boolean haveResult = false;
435        public Bundle result = null;
436        public PendingAssistExtras(ActivityRecord _activity) {
437            activity = _activity;
438        }
439        @Override
440        public void run() {
441            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
442            synchronized (this) {
443                haveResult = true;
444                notifyAll();
445            }
446        }
447    }
448
449    final ArrayList<PendingAssistExtras> mPendingAssistExtras
450            = new ArrayList<PendingAssistExtras>();
451
452    /**
453     * Process management.
454     */
455    final ProcessList mProcessList = new ProcessList();
456
457    /**
458     * All of the applications we currently have running organized by name.
459     * The keys are strings of the application package name (as
460     * returned by the package manager), and the keys are ApplicationRecord
461     * objects.
462     */
463    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
464
465    /**
466     * Tracking long-term execution of processes to look for abuse and other
467     * bad app behavior.
468     */
469    final ProcessStatsService mProcessStats;
470
471    /**
472     * The currently running isolated processes.
473     */
474    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
475
476    /**
477     * Counter for assigning isolated process uids, to avoid frequently reusing the
478     * same ones.
479     */
480    int mNextIsolatedProcessUid = 0;
481
482    /**
483     * The currently running heavy-weight process, if any.
484     */
485    ProcessRecord mHeavyWeightProcess = null;
486
487    /**
488     * The last time that various processes have crashed.
489     */
490    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
491
492    /**
493     * Information about a process that is currently marked as bad.
494     */
495    static final class BadProcessInfo {
496        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
497            this.time = time;
498            this.shortMsg = shortMsg;
499            this.longMsg = longMsg;
500            this.stack = stack;
501        }
502
503        final long time;
504        final String shortMsg;
505        final String longMsg;
506        final String stack;
507    }
508
509    /**
510     * Set of applications that we consider to be bad, and will reject
511     * incoming broadcasts from (which the user has no control over).
512     * Processes are added to this set when they have crashed twice within
513     * a minimum amount of time; they are removed from it when they are
514     * later restarted (hopefully due to some user action).  The value is the
515     * time it was added to the list.
516     */
517    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
518
519    /**
520     * All of the processes we currently have running organized by pid.
521     * The keys are the pid running the application.
522     *
523     * <p>NOTE: This object is protected by its own lock, NOT the global
524     * activity manager lock!
525     */
526    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
527
528    /**
529     * All of the processes that have been forced to be foreground.  The key
530     * is the pid of the caller who requested it (we hold a death
531     * link on it).
532     */
533    abstract class ForegroundToken implements IBinder.DeathRecipient {
534        int pid;
535        IBinder token;
536    }
537    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
538
539    /**
540     * List of records for processes that someone had tried to start before the
541     * system was ready.  We don't start them at that point, but ensure they
542     * are started by the time booting is complete.
543     */
544    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
545
546    /**
547     * List of persistent applications that are in the process
548     * of being started.
549     */
550    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
551
552    /**
553     * Processes that are being forcibly torn down.
554     */
555    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
556
557    /**
558     * List of running applications, sorted by recent usage.
559     * The first entry in the list is the least recently used.
560     */
561    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
562
563    /**
564     * Where in mLruProcesses that the processes hosting activities start.
565     */
566    int mLruProcessActivityStart = 0;
567
568    /**
569     * Where in mLruProcesses that the processes hosting services start.
570     * This is after (lower index) than mLruProcessesActivityStart.
571     */
572    int mLruProcessServiceStart = 0;
573
574    /**
575     * List of processes that should gc as soon as things are idle.
576     */
577    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
578
579    /**
580     * Processes we want to collect PSS data from.
581     */
582    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
583
584    /**
585     * Last time we requested PSS data of all processes.
586     */
587    long mLastFullPssTime = SystemClock.uptimeMillis();
588
589    /**
590     * If set, the next time we collect PSS data we should do a full collection
591     * with data from native processes and the kernel.
592     */
593    boolean mFullPssPending = false;
594
595    /**
596     * This is the process holding what we currently consider to be
597     * the "home" activity.
598     */
599    ProcessRecord mHomeProcess;
600
601    /**
602     * This is the process holding the activity the user last visited that
603     * is in a different process from the one they are currently in.
604     */
605    ProcessRecord mPreviousProcess;
606
607    /**
608     * The time at which the previous process was last visible.
609     */
610    long mPreviousProcessVisibleTime;
611
612    /**
613     * Which uses have been started, so are allowed to run code.
614     */
615    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
616
617    /**
618     * LRU list of history of current users.  Most recently current is at the end.
619     */
620    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
621
622    /**
623     * Constant array of the users that are currently started.
624     */
625    int[] mStartedUserArray = new int[] { 0 };
626
627    /**
628     * Registered observers of the user switching mechanics.
629     */
630    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
631            = new RemoteCallbackList<IUserSwitchObserver>();
632
633    /**
634     * Currently active user switch.
635     */
636    Object mCurUserSwitchCallback;
637
638    /**
639     * Packages that the user has asked to have run in screen size
640     * compatibility mode instead of filling the screen.
641     */
642    final CompatModePackages mCompatModePackages;
643
644    /**
645     * Set of IntentSenderRecord objects that are currently active.
646     */
647    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
648            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
649
650    /**
651     * Fingerprints (hashCode()) of stack traces that we've
652     * already logged DropBox entries for.  Guarded by itself.  If
653     * something (rogue user app) forces this over
654     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
655     */
656    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
657    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
658
659    /**
660     * Strict Mode background batched logging state.
661     *
662     * The string buffer is guarded by itself, and its lock is also
663     * used to determine if another batched write is already
664     * in-flight.
665     */
666    private final StringBuilder mStrictModeBuffer = new StringBuilder();
667
668    /**
669     * Keeps track of all IIntentReceivers that have been registered for
670     * broadcasts.  Hash keys are the receiver IBinder, hash value is
671     * a ReceiverList.
672     */
673    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
674            new HashMap<IBinder, ReceiverList>();
675
676    /**
677     * Resolver for broadcast intents to registered receivers.
678     * Holds BroadcastFilter (subclass of IntentFilter).
679     */
680    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
681            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
682        @Override
683        protected boolean allowFilterResult(
684                BroadcastFilter filter, List<BroadcastFilter> dest) {
685            IBinder target = filter.receiverList.receiver.asBinder();
686            for (int i=dest.size()-1; i>=0; i--) {
687                if (dest.get(i).receiverList.receiver.asBinder() == target) {
688                    return false;
689                }
690            }
691            return true;
692        }
693
694        @Override
695        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
696            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
697                    || userId == filter.owningUserId) {
698                return super.newResult(filter, match, userId);
699            }
700            return null;
701        }
702
703        @Override
704        protected BroadcastFilter[] newArray(int size) {
705            return new BroadcastFilter[size];
706        }
707
708        @Override
709        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
710            return packageName.equals(filter.packageName);
711        }
712    };
713
714    /**
715     * State of all active sticky broadcasts per user.  Keys are the action of the
716     * sticky Intent, values are an ArrayList of all broadcasted intents with
717     * that action (which should usually be one).  The SparseArray is keyed
718     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
719     * for stickies that are sent to all users.
720     */
721    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
722            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
723
724    final ActiveServices mServices;
725
726    /**
727     * Backup/restore process management
728     */
729    String mBackupAppName = null;
730    BackupRecord mBackupTarget = null;
731
732    final ProviderMap mProviderMap;
733
734    /**
735     * List of content providers who have clients waiting for them.  The
736     * application is currently being launched and the provider will be
737     * removed from this list once it is published.
738     */
739    final ArrayList<ContentProviderRecord> mLaunchingProviders
740            = new ArrayList<ContentProviderRecord>();
741
742    /**
743     * File storing persisted {@link #mGrantedUriPermissions}.
744     */
745    private final AtomicFile mGrantFile;
746
747    /** XML constants used in {@link #mGrantFile} */
748    private static final String TAG_URI_GRANTS = "uri-grants";
749    private static final String TAG_URI_GRANT = "uri-grant";
750    private static final String ATTR_USER_HANDLE = "userHandle";
751    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
752    private static final String ATTR_TARGET_USER_ID = "targetUserId";
753    private static final String ATTR_SOURCE_PKG = "sourcePkg";
754    private static final String ATTR_TARGET_PKG = "targetPkg";
755    private static final String ATTR_URI = "uri";
756    private static final String ATTR_MODE_FLAGS = "modeFlags";
757    private static final String ATTR_CREATED_TIME = "createdTime";
758    private static final String ATTR_PREFIX = "prefix";
759
760    /**
761     * Global set of specific {@link Uri} permissions that have been granted.
762     * This optimized lookup structure maps from {@link UriPermission#targetUid}
763     * to {@link UriPermission#uri} to {@link UriPermission}.
764     */
765    @GuardedBy("this")
766    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
767            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
768
769    public static class GrantUri {
770        public final int sourceUserId;
771        public final Uri uri;
772        public boolean prefix;
773
774        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
775            this.sourceUserId = sourceUserId;
776            this.uri = uri;
777            this.prefix = prefix;
778        }
779
780        @Override
781        public int hashCode() {
782            return toString().hashCode();
783        }
784
785        @Override
786        public boolean equals(Object o) {
787            if (o instanceof GrantUri) {
788                GrantUri other = (GrantUri) o;
789                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
790                        && prefix == other.prefix;
791            }
792            return false;
793        }
794
795        @Override
796        public String toString() {
797            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
798            if (prefix) result += " [prefix]";
799            return result;
800        }
801
802        public String toSafeString() {
803            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
804            if (prefix) result += " [prefix]";
805            return result;
806        }
807
808        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
809            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
810                    ContentProvider.getUriWithoutUserId(uri), false);
811        }
812    }
813
814    CoreSettingsObserver mCoreSettingsObserver;
815
816    /**
817     * Thread-local storage used to carry caller permissions over through
818     * indirect content-provider access.
819     */
820    private class Identity {
821        public int pid;
822        public int uid;
823
824        Identity(int _pid, int _uid) {
825            pid = _pid;
826            uid = _uid;
827        }
828    }
829
830    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
831
832    /**
833     * All information we have collected about the runtime performance of
834     * any user id that can impact battery performance.
835     */
836    final BatteryStatsService mBatteryStatsService;
837
838    /**
839     * Information about component usage
840     */
841    UsageStatsManagerInternal mUsageStatsService;
842
843    /**
844     * Information about and control over application operations
845     */
846    final AppOpsService mAppOpsService;
847
848    /**
849     * Save recent tasks information across reboots.
850     */
851    final TaskPersister mTaskPersister;
852
853    /**
854     * Current configuration information.  HistoryRecord objects are given
855     * a reference to this object to indicate which configuration they are
856     * currently running in, so this object must be kept immutable.
857     */
858    Configuration mConfiguration = new Configuration();
859
860    /**
861     * Current sequencing integer of the configuration, for skipping old
862     * configurations.
863     */
864    int mConfigurationSeq = 0;
865
866    /**
867     * Hardware-reported OpenGLES version.
868     */
869    final int GL_ES_VERSION;
870
871    /**
872     * List of initialization arguments to pass to all processes when binding applications to them.
873     * For example, references to the commonly used services.
874     */
875    HashMap<String, IBinder> mAppBindArgs;
876
877    /**
878     * Temporary to avoid allocations.  Protected by main lock.
879     */
880    final StringBuilder mStringBuilder = new StringBuilder(256);
881
882    /**
883     * Used to control how we initialize the service.
884     */
885    ComponentName mTopComponent;
886    String mTopAction = Intent.ACTION_MAIN;
887    String mTopData;
888    boolean mProcessesReady = false;
889    boolean mSystemReady = false;
890    boolean mBooting = false;
891    boolean mWaitingUpdate = false;
892    boolean mDidUpdate = false;
893    boolean mOnBattery = false;
894    boolean mLaunchWarningShown = false;
895
896    Context mContext;
897
898    int mFactoryTest;
899
900    boolean mCheckedForSetup;
901
902    /**
903     * The time at which we will allow normal application switches again,
904     * after a call to {@link #stopAppSwitches()}.
905     */
906    long mAppSwitchesAllowedTime;
907
908    /**
909     * This is set to true after the first switch after mAppSwitchesAllowedTime
910     * is set; any switches after that will clear the time.
911     */
912    boolean mDidAppSwitch;
913
914    /**
915     * Last time (in realtime) at which we checked for power usage.
916     */
917    long mLastPowerCheckRealtime;
918
919    /**
920     * Last time (in uptime) at which we checked for power usage.
921     */
922    long mLastPowerCheckUptime;
923
924    /**
925     * Set while we are wanting to sleep, to prevent any
926     * activities from being started/resumed.
927     */
928    private boolean mSleeping = false;
929
930    /**
931     * Set while we are running a voice interaction.  This overrides
932     * sleeping while it is active.
933     */
934    private boolean mRunningVoice = false;
935
936    /**
937     * State of external calls telling us if the device is asleep.
938     */
939    private boolean mWentToSleep = false;
940
941    /**
942     * State of external call telling us if the lock screen is shown.
943     */
944    private boolean mLockScreenShown = false;
945
946    /**
947     * Set if we are shutting down the system, similar to sleeping.
948     */
949    boolean mShuttingDown = false;
950
951    /**
952     * Current sequence id for oom_adj computation traversal.
953     */
954    int mAdjSeq = 0;
955
956    /**
957     * Current sequence id for process LRU updating.
958     */
959    int mLruSeq = 0;
960
961    /**
962     * Keep track of the non-cached/empty process we last found, to help
963     * determine how to distribute cached/empty processes next time.
964     */
965    int mNumNonCachedProcs = 0;
966
967    /**
968     * Keep track of the number of cached hidden procs, to balance oom adj
969     * distribution between those and empty procs.
970     */
971    int mNumCachedHiddenProcs = 0;
972
973    /**
974     * Keep track of the number of service processes we last found, to
975     * determine on the next iteration which should be B services.
976     */
977    int mNumServiceProcs = 0;
978    int mNewNumAServiceProcs = 0;
979    int mNewNumServiceProcs = 0;
980
981    /**
982     * Allow the current computed overall memory level of the system to go down?
983     * This is set to false when we are killing processes for reasons other than
984     * memory management, so that the now smaller process list will not be taken as
985     * an indication that memory is tighter.
986     */
987    boolean mAllowLowerMemLevel = false;
988
989    /**
990     * The last computed memory level, for holding when we are in a state that
991     * processes are going away for other reasons.
992     */
993    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
994
995    /**
996     * The last total number of process we have, to determine if changes actually look
997     * like a shrinking number of process due to lower RAM.
998     */
999    int mLastNumProcesses;
1000
1001    /**
1002     * The uptime of the last time we performed idle maintenance.
1003     */
1004    long mLastIdleTime = SystemClock.uptimeMillis();
1005
1006    /**
1007     * Total time spent with RAM that has been added in the past since the last idle time.
1008     */
1009    long mLowRamTimeSinceLastIdle = 0;
1010
1011    /**
1012     * If RAM is currently low, when that horrible situation started.
1013     */
1014    long mLowRamStartTime = 0;
1015
1016    /**
1017     * For reporting to battery stats the current top application.
1018     */
1019    private String mCurResumedPackage = null;
1020    private int mCurResumedUid = -1;
1021
1022    /**
1023     * For reporting to battery stats the apps currently running foreground
1024     * service.  The ProcessMap is package/uid tuples; each of these contain
1025     * an array of the currently foreground processes.
1026     */
1027    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1028            = new ProcessMap<ArrayList<ProcessRecord>>();
1029
1030    /**
1031     * This is set if we had to do a delayed dexopt of an app before launching
1032     * it, to increase the ANR timeouts in that case.
1033     */
1034    boolean mDidDexOpt;
1035
1036    /**
1037     * Set if the systemServer made a call to enterSafeMode.
1038     */
1039    boolean mSafeMode;
1040
1041    String mDebugApp = null;
1042    boolean mWaitForDebugger = false;
1043    boolean mDebugTransient = false;
1044    String mOrigDebugApp = null;
1045    boolean mOrigWaitForDebugger = false;
1046    boolean mAlwaysFinishActivities = false;
1047    IActivityController mController = null;
1048    String mProfileApp = null;
1049    ProcessRecord mProfileProc = null;
1050    String mProfileFile;
1051    ParcelFileDescriptor mProfileFd;
1052    int mProfileType = 0;
1053    boolean mAutoStopProfiler = false;
1054    String mOpenGlTraceApp = null;
1055
1056    static class ProcessChangeItem {
1057        static final int CHANGE_ACTIVITIES = 1<<0;
1058        static final int CHANGE_PROCESS_STATE = 1<<1;
1059        int changes;
1060        int uid;
1061        int pid;
1062        int processState;
1063        boolean foregroundActivities;
1064    }
1065
1066    final RemoteCallbackList<IProcessObserver> mProcessObservers
1067            = new RemoteCallbackList<IProcessObserver>();
1068    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1069
1070    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1071            = new ArrayList<ProcessChangeItem>();
1072    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1073            = new ArrayList<ProcessChangeItem>();
1074
1075    /**
1076     * Runtime CPU use collection thread.  This object's lock is used to
1077     * protect all related state.
1078     */
1079    final Thread mProcessCpuThread;
1080
1081    /**
1082     * Used to collect process stats when showing not responding dialog.
1083     * Protected by mProcessCpuThread.
1084     */
1085    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1086            MONITOR_THREAD_CPU_USAGE);
1087    final AtomicLong mLastCpuTime = new AtomicLong(0);
1088    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1089
1090    long mLastWriteTime = 0;
1091
1092    /**
1093     * Used to retain an update lock when the foreground activity is in
1094     * immersive mode.
1095     */
1096    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1097
1098    /**
1099     * Set to true after the system has finished booting.
1100     */
1101    boolean mBooted = false;
1102
1103    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1104    int mProcessLimitOverride = -1;
1105
1106    WindowManagerService mWindowManager;
1107
1108    final ActivityThread mSystemThread;
1109
1110    int mCurrentUserId = 0;
1111    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1112
1113    /**
1114     * Mapping from each known user ID to the profile group ID it is associated with.
1115     */
1116    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1117
1118    private UserManagerService mUserManager;
1119
1120    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1121        final ProcessRecord mApp;
1122        final int mPid;
1123        final IApplicationThread mAppThread;
1124
1125        AppDeathRecipient(ProcessRecord app, int pid,
1126                IApplicationThread thread) {
1127            if (localLOGV) Slog.v(
1128                TAG, "New death recipient " + this
1129                + " for thread " + thread.asBinder());
1130            mApp = app;
1131            mPid = pid;
1132            mAppThread = thread;
1133        }
1134
1135        @Override
1136        public void binderDied() {
1137            if (localLOGV) Slog.v(
1138                TAG, "Death received in " + this
1139                + " for thread " + mAppThread.asBinder());
1140            synchronized(ActivityManagerService.this) {
1141                appDiedLocked(mApp, mPid, mAppThread);
1142            }
1143        }
1144    }
1145
1146    static final int SHOW_ERROR_MSG = 1;
1147    static final int SHOW_NOT_RESPONDING_MSG = 2;
1148    static final int SHOW_FACTORY_ERROR_MSG = 3;
1149    static final int UPDATE_CONFIGURATION_MSG = 4;
1150    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1151    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1152    static final int SERVICE_TIMEOUT_MSG = 12;
1153    static final int UPDATE_TIME_ZONE = 13;
1154    static final int SHOW_UID_ERROR_MSG = 14;
1155    static final int IM_FEELING_LUCKY_MSG = 15;
1156    static final int PROC_START_TIMEOUT_MSG = 20;
1157    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1158    static final int KILL_APPLICATION_MSG = 22;
1159    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1160    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1161    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1162    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1163    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1164    static final int CLEAR_DNS_CACHE_MSG = 28;
1165    static final int UPDATE_HTTP_PROXY_MSG = 29;
1166    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1167    static final int DISPATCH_PROCESSES_CHANGED = 31;
1168    static final int DISPATCH_PROCESS_DIED = 32;
1169    static final int REPORT_MEM_USAGE_MSG = 33;
1170    static final int REPORT_USER_SWITCH_MSG = 34;
1171    static final int CONTINUE_USER_SWITCH_MSG = 35;
1172    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1173    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1174    static final int PERSIST_URI_GRANTS_MSG = 38;
1175    static final int REQUEST_ALL_PSS_MSG = 39;
1176    static final int START_PROFILES_MSG = 40;
1177    static final int UPDATE_TIME = 41;
1178    static final int SYSTEM_USER_START_MSG = 42;
1179    static final int SYSTEM_USER_CURRENT_MSG = 43;
1180    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1181    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1182    static final int START_USER_SWITCH_MSG = 46;
1183
1184    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1185    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1186    static final int FIRST_COMPAT_MODE_MSG = 300;
1187    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1188
1189    AlertDialog mUidAlert;
1190    CompatModeDialog mCompatModeDialog;
1191    long mLastMemUsageReportTime = 0;
1192
1193    private LockToAppRequestDialog mLockToAppRequest;
1194
1195    /**
1196     * Flag whether the current user is a "monkey", i.e. whether
1197     * the UI is driven by a UI automation tool.
1198     */
1199    private boolean mUserIsMonkey;
1200
1201    /** Flag whether the device has a recents UI */
1202    final boolean mHasRecents;
1203
1204    final int mThumbnailWidth;
1205    final int mThumbnailHeight;
1206
1207    final ServiceThread mHandlerThread;
1208    final MainHandler mHandler;
1209
1210    final class MainHandler extends Handler {
1211        public MainHandler(Looper looper) {
1212            super(looper, null, true);
1213        }
1214
1215        @Override
1216        public void handleMessage(Message msg) {
1217            switch (msg.what) {
1218            case SHOW_ERROR_MSG: {
1219                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1220                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1221                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1222                synchronized (ActivityManagerService.this) {
1223                    ProcessRecord proc = (ProcessRecord)data.get("app");
1224                    AppErrorResult res = (AppErrorResult) data.get("result");
1225                    if (proc != null && proc.crashDialog != null) {
1226                        Slog.e(TAG, "App already has crash dialog: " + proc);
1227                        if (res != null) {
1228                            res.set(0);
1229                        }
1230                        return;
1231                    }
1232                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1233                            >= Process.FIRST_APPLICATION_UID
1234                            && proc.pid != MY_PID);
1235                    for (int userId : mCurrentProfileIds) {
1236                        isBackground &= (proc.userId != userId);
1237                    }
1238                    if (isBackground && !showBackground) {
1239                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1240                        if (res != null) {
1241                            res.set(0);
1242                        }
1243                        return;
1244                    }
1245                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1246                        Dialog d = new AppErrorDialog(mContext,
1247                                ActivityManagerService.this, res, proc);
1248                        d.show();
1249                        proc.crashDialog = d;
1250                    } else {
1251                        // The device is asleep, so just pretend that the user
1252                        // saw a crash dialog and hit "force quit".
1253                        if (res != null) {
1254                            res.set(0);
1255                        }
1256                    }
1257                }
1258
1259                ensureBootCompleted();
1260            } break;
1261            case SHOW_NOT_RESPONDING_MSG: {
1262                synchronized (ActivityManagerService.this) {
1263                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1264                    ProcessRecord proc = (ProcessRecord)data.get("app");
1265                    if (proc != null && proc.anrDialog != null) {
1266                        Slog.e(TAG, "App already has anr dialog: " + proc);
1267                        return;
1268                    }
1269
1270                    Intent intent = new Intent("android.intent.action.ANR");
1271                    if (!mProcessesReady) {
1272                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1273                                | Intent.FLAG_RECEIVER_FOREGROUND);
1274                    }
1275                    broadcastIntentLocked(null, null, intent,
1276                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1277                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1278
1279                    if (mShowDialogs) {
1280                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1281                                mContext, proc, (ActivityRecord)data.get("activity"),
1282                                msg.arg1 != 0);
1283                        d.show();
1284                        proc.anrDialog = d;
1285                    } else {
1286                        // Just kill the app if there is no dialog to be shown.
1287                        killAppAtUsersRequest(proc, null);
1288                    }
1289                }
1290
1291                ensureBootCompleted();
1292            } break;
1293            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1294                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1295                synchronized (ActivityManagerService.this) {
1296                    ProcessRecord proc = (ProcessRecord) data.get("app");
1297                    if (proc == null) {
1298                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1299                        break;
1300                    }
1301                    if (proc.crashDialog != null) {
1302                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1303                        return;
1304                    }
1305                    AppErrorResult res = (AppErrorResult) data.get("result");
1306                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1307                        Dialog d = new StrictModeViolationDialog(mContext,
1308                                ActivityManagerService.this, res, proc);
1309                        d.show();
1310                        proc.crashDialog = d;
1311                    } else {
1312                        // The device is asleep, so just pretend that the user
1313                        // saw a crash dialog and hit "force quit".
1314                        res.set(0);
1315                    }
1316                }
1317                ensureBootCompleted();
1318            } break;
1319            case SHOW_FACTORY_ERROR_MSG: {
1320                Dialog d = new FactoryErrorDialog(
1321                    mContext, msg.getData().getCharSequence("msg"));
1322                d.show();
1323                ensureBootCompleted();
1324            } break;
1325            case UPDATE_CONFIGURATION_MSG: {
1326                final ContentResolver resolver = mContext.getContentResolver();
1327                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1328            } break;
1329            case GC_BACKGROUND_PROCESSES_MSG: {
1330                synchronized (ActivityManagerService.this) {
1331                    performAppGcsIfAppropriateLocked();
1332                }
1333            } break;
1334            case WAIT_FOR_DEBUGGER_MSG: {
1335                synchronized (ActivityManagerService.this) {
1336                    ProcessRecord app = (ProcessRecord)msg.obj;
1337                    if (msg.arg1 != 0) {
1338                        if (!app.waitedForDebugger) {
1339                            Dialog d = new AppWaitingForDebuggerDialog(
1340                                    ActivityManagerService.this,
1341                                    mContext, app);
1342                            app.waitDialog = d;
1343                            app.waitedForDebugger = true;
1344                            d.show();
1345                        }
1346                    } else {
1347                        if (app.waitDialog != null) {
1348                            app.waitDialog.dismiss();
1349                            app.waitDialog = null;
1350                        }
1351                    }
1352                }
1353            } break;
1354            case SERVICE_TIMEOUT_MSG: {
1355                if (mDidDexOpt) {
1356                    mDidDexOpt = false;
1357                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1358                    nmsg.obj = msg.obj;
1359                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1360                    return;
1361                }
1362                mServices.serviceTimeout((ProcessRecord)msg.obj);
1363            } break;
1364            case UPDATE_TIME_ZONE: {
1365                synchronized (ActivityManagerService.this) {
1366                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1367                        ProcessRecord r = mLruProcesses.get(i);
1368                        if (r.thread != null) {
1369                            try {
1370                                r.thread.updateTimeZone();
1371                            } catch (RemoteException ex) {
1372                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1373                            }
1374                        }
1375                    }
1376                }
1377            } break;
1378            case CLEAR_DNS_CACHE_MSG: {
1379                synchronized (ActivityManagerService.this) {
1380                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1381                        ProcessRecord r = mLruProcesses.get(i);
1382                        if (r.thread != null) {
1383                            try {
1384                                r.thread.clearDnsCache();
1385                            } catch (RemoteException ex) {
1386                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1387                            }
1388                        }
1389                    }
1390                }
1391            } break;
1392            case UPDATE_HTTP_PROXY_MSG: {
1393                ProxyInfo proxy = (ProxyInfo)msg.obj;
1394                String host = "";
1395                String port = "";
1396                String exclList = "";
1397                Uri pacFileUrl = Uri.EMPTY;
1398                if (proxy != null) {
1399                    host = proxy.getHost();
1400                    port = Integer.toString(proxy.getPort());
1401                    exclList = proxy.getExclusionListAsString();
1402                    pacFileUrl = proxy.getPacFileUrl();
1403                }
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to update http proxy for: " +
1412                                        r.info.processName);
1413                            }
1414                        }
1415                    }
1416                }
1417            } break;
1418            case SHOW_UID_ERROR_MSG: {
1419                String title = "System UIDs Inconsistent";
1420                String text = "UIDs on the system are inconsistent, you need to wipe your"
1421                        + " data partition or your device will be unstable.";
1422                Log.e(TAG, title + ": " + text);
1423                if (mShowDialogs) {
1424                    // XXX This is a temporary dialog, no need to localize.
1425                    AlertDialog d = new BaseErrorDialog(mContext);
1426                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1427                    d.setCancelable(false);
1428                    d.setTitle(title);
1429                    d.setMessage(text);
1430                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1431                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1432                    mUidAlert = d;
1433                    d.show();
1434                }
1435            } break;
1436            case IM_FEELING_LUCKY_MSG: {
1437                if (mUidAlert != null) {
1438                    mUidAlert.dismiss();
1439                    mUidAlert = null;
1440                }
1441            } break;
1442            case PROC_START_TIMEOUT_MSG: {
1443                if (mDidDexOpt) {
1444                    mDidDexOpt = false;
1445                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1446                    nmsg.obj = msg.obj;
1447                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1448                    return;
1449                }
1450                ProcessRecord app = (ProcessRecord)msg.obj;
1451                synchronized (ActivityManagerService.this) {
1452                    processStartTimedOutLocked(app);
1453                }
1454            } break;
1455            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1456                synchronized (ActivityManagerService.this) {
1457                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1458                }
1459            } break;
1460            case KILL_APPLICATION_MSG: {
1461                synchronized (ActivityManagerService.this) {
1462                    int appid = msg.arg1;
1463                    boolean restart = (msg.arg2 == 1);
1464                    Bundle bundle = (Bundle)msg.obj;
1465                    String pkg = bundle.getString("pkg");
1466                    String reason = bundle.getString("reason");
1467                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1468                            false, UserHandle.USER_ALL, reason);
1469                }
1470            } break;
1471            case FINALIZE_PENDING_INTENT_MSG: {
1472                ((PendingIntentRecord)msg.obj).completeFinalize();
1473            } break;
1474            case POST_HEAVY_NOTIFICATION_MSG: {
1475                INotificationManager inm = NotificationManager.getService();
1476                if (inm == null) {
1477                    return;
1478                }
1479
1480                ActivityRecord root = (ActivityRecord)msg.obj;
1481                ProcessRecord process = root.app;
1482                if (process == null) {
1483                    return;
1484                }
1485
1486                try {
1487                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1488                    String text = mContext.getString(R.string.heavy_weight_notification,
1489                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1490                    Notification notification = new Notification();
1491                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1492                    notification.when = 0;
1493                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1494                    notification.tickerText = text;
1495                    notification.defaults = 0; // please be quiet
1496                    notification.sound = null;
1497                    notification.vibrate = null;
1498                    notification.color = mContext.getResources().getColor(
1499                            com.android.internal.R.color.system_notification_accent_color);
1500                    notification.setLatestEventInfo(context, text,
1501                            mContext.getText(R.string.heavy_weight_notification_detail),
1502                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1503                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1504                                    new UserHandle(root.userId)));
1505
1506                    try {
1507                        int[] outId = new int[1];
1508                        inm.enqueueNotificationWithTag("android", "android", null,
1509                                R.string.heavy_weight_notification,
1510                                notification, outId, root.userId);
1511                    } catch (RuntimeException e) {
1512                        Slog.w(ActivityManagerService.TAG,
1513                                "Error showing notification for heavy-weight app", e);
1514                    } catch (RemoteException e) {
1515                    }
1516                } catch (NameNotFoundException e) {
1517                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1518                }
1519            } break;
1520            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1521                INotificationManager inm = NotificationManager.getService();
1522                if (inm == null) {
1523                    return;
1524                }
1525                try {
1526                    inm.cancelNotificationWithTag("android", null,
1527                            R.string.heavy_weight_notification,  msg.arg1);
1528                } catch (RuntimeException e) {
1529                    Slog.w(ActivityManagerService.TAG,
1530                            "Error canceling notification for service", e);
1531                } catch (RemoteException e) {
1532                }
1533            } break;
1534            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1535                synchronized (ActivityManagerService.this) {
1536                    checkExcessivePowerUsageLocked(true);
1537                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1538                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1539                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1540                }
1541            } break;
1542            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1543                synchronized (ActivityManagerService.this) {
1544                    ActivityRecord ar = (ActivityRecord)msg.obj;
1545                    if (mCompatModeDialog != null) {
1546                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1547                                ar.info.applicationInfo.packageName)) {
1548                            return;
1549                        }
1550                        mCompatModeDialog.dismiss();
1551                        mCompatModeDialog = null;
1552                    }
1553                    if (ar != null && false) {
1554                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1555                                ar.packageName)) {
1556                            int mode = mCompatModePackages.computeCompatModeLocked(
1557                                    ar.info.applicationInfo);
1558                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1559                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1560                                mCompatModeDialog = new CompatModeDialog(
1561                                        ActivityManagerService.this, mContext,
1562                                        ar.info.applicationInfo);
1563                                mCompatModeDialog.show();
1564                            }
1565                        }
1566                    }
1567                }
1568                break;
1569            }
1570            case DISPATCH_PROCESSES_CHANGED: {
1571                dispatchProcessesChanged();
1572                break;
1573            }
1574            case DISPATCH_PROCESS_DIED: {
1575                final int pid = msg.arg1;
1576                final int uid = msg.arg2;
1577                dispatchProcessDied(pid, uid);
1578                break;
1579            }
1580            case REPORT_MEM_USAGE_MSG: {
1581                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1582                Thread thread = new Thread() {
1583                    @Override public void run() {
1584                        final SparseArray<ProcessMemInfo> infoMap
1585                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1586                        for (int i=0, N=memInfos.size(); i<N; i++) {
1587                            ProcessMemInfo mi = memInfos.get(i);
1588                            infoMap.put(mi.pid, mi);
1589                        }
1590                        updateCpuStatsNow();
1591                        synchronized (mProcessCpuThread) {
1592                            final int N = mProcessCpuTracker.countStats();
1593                            for (int i=0; i<N; i++) {
1594                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1595                                if (st.vsize > 0) {
1596                                    long pss = Debug.getPss(st.pid, null);
1597                                    if (pss > 0) {
1598                                        if (infoMap.indexOfKey(st.pid) < 0) {
1599                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1600                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1601                                            mi.pss = pss;
1602                                            memInfos.add(mi);
1603                                        }
1604                                    }
1605                                }
1606                            }
1607                        }
1608
1609                        long totalPss = 0;
1610                        for (int i=0, N=memInfos.size(); i<N; i++) {
1611                            ProcessMemInfo mi = memInfos.get(i);
1612                            if (mi.pss == 0) {
1613                                mi.pss = Debug.getPss(mi.pid, null);
1614                            }
1615                            totalPss += mi.pss;
1616                        }
1617                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1618                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1619                                if (lhs.oomAdj != rhs.oomAdj) {
1620                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1621                                }
1622                                if (lhs.pss != rhs.pss) {
1623                                    return lhs.pss < rhs.pss ? 1 : -1;
1624                                }
1625                                return 0;
1626                            }
1627                        });
1628
1629                        StringBuilder tag = new StringBuilder(128);
1630                        StringBuilder stack = new StringBuilder(128);
1631                        tag.append("Low on memory -- ");
1632                        appendMemBucket(tag, totalPss, "total", false);
1633                        appendMemBucket(stack, totalPss, "total", true);
1634
1635                        StringBuilder logBuilder = new StringBuilder(1024);
1636                        logBuilder.append("Low on memory:\n");
1637
1638                        boolean firstLine = true;
1639                        int lastOomAdj = Integer.MIN_VALUE;
1640                        for (int i=0, N=memInfos.size(); i<N; i++) {
1641                            ProcessMemInfo mi = memInfos.get(i);
1642
1643                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1644                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1645                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1646                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1647                                if (lastOomAdj != mi.oomAdj) {
1648                                    lastOomAdj = mi.oomAdj;
1649                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1650                                        tag.append(" / ");
1651                                    }
1652                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1653                                        if (firstLine) {
1654                                            stack.append(":");
1655                                            firstLine = false;
1656                                        }
1657                                        stack.append("\n\t at ");
1658                                    } else {
1659                                        stack.append("$");
1660                                    }
1661                                } else {
1662                                    tag.append(" ");
1663                                    stack.append("$");
1664                                }
1665                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1666                                    appendMemBucket(tag, mi.pss, mi.name, false);
1667                                }
1668                                appendMemBucket(stack, mi.pss, mi.name, true);
1669                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1670                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1671                                    stack.append("(");
1672                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1673                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1674                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1675                                            stack.append(":");
1676                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1677                                        }
1678                                    }
1679                                    stack.append(")");
1680                                }
1681                            }
1682
1683                            logBuilder.append("  ");
1684                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1685                            logBuilder.append(' ');
1686                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1687                            logBuilder.append(' ');
1688                            ProcessList.appendRamKb(logBuilder, mi.pss);
1689                            logBuilder.append(" kB: ");
1690                            logBuilder.append(mi.name);
1691                            logBuilder.append(" (");
1692                            logBuilder.append(mi.pid);
1693                            logBuilder.append(") ");
1694                            logBuilder.append(mi.adjType);
1695                            logBuilder.append('\n');
1696                            if (mi.adjReason != null) {
1697                                logBuilder.append("                      ");
1698                                logBuilder.append(mi.adjReason);
1699                                logBuilder.append('\n');
1700                            }
1701                        }
1702
1703                        logBuilder.append("           ");
1704                        ProcessList.appendRamKb(logBuilder, totalPss);
1705                        logBuilder.append(" kB: TOTAL\n");
1706
1707                        long[] infos = new long[Debug.MEMINFO_COUNT];
1708                        Debug.getMemInfo(infos);
1709                        logBuilder.append("  MemInfo: ");
1710                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1711                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1712                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1713                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1714                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1715                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1716                            logBuilder.append("  ZRAM: ");
1717                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1718                            logBuilder.append(" kB RAM, ");
1719                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1720                            logBuilder.append(" kB swap total, ");
1721                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1722                            logBuilder.append(" kB swap free\n");
1723                        }
1724                        Slog.i(TAG, logBuilder.toString());
1725
1726                        StringBuilder dropBuilder = new StringBuilder(1024);
1727                        /*
1728                        StringWriter oomSw = new StringWriter();
1729                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1730                        StringWriter catSw = new StringWriter();
1731                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1732                        String[] emptyArgs = new String[] { };
1733                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1734                        oomPw.flush();
1735                        String oomString = oomSw.toString();
1736                        */
1737                        dropBuilder.append(stack);
1738                        dropBuilder.append('\n');
1739                        dropBuilder.append('\n');
1740                        dropBuilder.append(logBuilder);
1741                        dropBuilder.append('\n');
1742                        /*
1743                        dropBuilder.append(oomString);
1744                        dropBuilder.append('\n');
1745                        */
1746                        StringWriter catSw = new StringWriter();
1747                        synchronized (ActivityManagerService.this) {
1748                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1749                            String[] emptyArgs = new String[] { };
1750                            catPw.println();
1751                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1752                            catPw.println();
1753                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1754                                    false, false, null);
1755                            catPw.println();
1756                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1757                            catPw.flush();
1758                        }
1759                        dropBuilder.append(catSw.toString());
1760                        addErrorToDropBox("lowmem", null, "system_server", null,
1761                                null, tag.toString(), dropBuilder.toString(), null, null);
1762                        //Slog.i(TAG, "Sent to dropbox:");
1763                        //Slog.i(TAG, dropBuilder.toString());
1764                        synchronized (ActivityManagerService.this) {
1765                            long now = SystemClock.uptimeMillis();
1766                            if (mLastMemUsageReportTime < now) {
1767                                mLastMemUsageReportTime = now;
1768                            }
1769                        }
1770                    }
1771                };
1772                thread.start();
1773                break;
1774            }
1775            case START_USER_SWITCH_MSG: {
1776                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1777                break;
1778            }
1779            case REPORT_USER_SWITCH_MSG: {
1780                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1781                break;
1782            }
1783            case CONTINUE_USER_SWITCH_MSG: {
1784                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1785                break;
1786            }
1787            case USER_SWITCH_TIMEOUT_MSG: {
1788                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1789                break;
1790            }
1791            case IMMERSIVE_MODE_LOCK_MSG: {
1792                final boolean nextState = (msg.arg1 != 0);
1793                if (mUpdateLock.isHeld() != nextState) {
1794                    if (DEBUG_IMMERSIVE) {
1795                        final ActivityRecord r = (ActivityRecord) msg.obj;
1796                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1797                    }
1798                    if (nextState) {
1799                        mUpdateLock.acquire();
1800                    } else {
1801                        mUpdateLock.release();
1802                    }
1803                }
1804                break;
1805            }
1806            case PERSIST_URI_GRANTS_MSG: {
1807                writeGrantedUriPermissions();
1808                break;
1809            }
1810            case REQUEST_ALL_PSS_MSG: {
1811                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1812                break;
1813            }
1814            case START_PROFILES_MSG: {
1815                synchronized (ActivityManagerService.this) {
1816                    startProfilesLocked();
1817                }
1818                break;
1819            }
1820            case UPDATE_TIME: {
1821                synchronized (ActivityManagerService.this) {
1822                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1823                        ProcessRecord r = mLruProcesses.get(i);
1824                        if (r.thread != null) {
1825                            try {
1826                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1827                            } catch (RemoteException ex) {
1828                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1829                            }
1830                        }
1831                    }
1832                }
1833                break;
1834            }
1835            case SYSTEM_USER_START_MSG: {
1836                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1837                        Integer.toString(msg.arg1), msg.arg1);
1838                mSystemServiceManager.startUser(msg.arg1);
1839                break;
1840            }
1841            case SYSTEM_USER_CURRENT_MSG: {
1842                mBatteryStatsService.noteEvent(
1843                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1844                        Integer.toString(msg.arg2), msg.arg2);
1845                mBatteryStatsService.noteEvent(
1846                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1847                        Integer.toString(msg.arg1), msg.arg1);
1848                mSystemServiceManager.switchUser(msg.arg1);
1849                mLockToAppRequest.clearPrompt();
1850                break;
1851            }
1852            case ENTER_ANIMATION_COMPLETE_MSG: {
1853                synchronized (ActivityManagerService.this) {
1854                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1855                    if (r != null && r.app != null && r.app.thread != null) {
1856                        try {
1857                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1858                        } catch (RemoteException e) {
1859                        }
1860                    }
1861                }
1862                break;
1863            }
1864            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1865                enableScreenAfterBoot();
1866                break;
1867            }
1868            }
1869        }
1870    };
1871
1872    static final int COLLECT_PSS_BG_MSG = 1;
1873
1874    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1875        @Override
1876        public void handleMessage(Message msg) {
1877            switch (msg.what) {
1878            case COLLECT_PSS_BG_MSG: {
1879                long start = SystemClock.uptimeMillis();
1880                MemInfoReader memInfo = null;
1881                synchronized (ActivityManagerService.this) {
1882                    if (mFullPssPending) {
1883                        mFullPssPending = false;
1884                        memInfo = new MemInfoReader();
1885                    }
1886                }
1887                if (memInfo != null) {
1888                    updateCpuStatsNow();
1889                    long nativeTotalPss = 0;
1890                    synchronized (mProcessCpuThread) {
1891                        final int N = mProcessCpuTracker.countStats();
1892                        for (int j=0; j<N; j++) {
1893                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1894                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1895                                // This is definitely an application process; skip it.
1896                                continue;
1897                            }
1898                            synchronized (mPidsSelfLocked) {
1899                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1900                                    // This is one of our own processes; skip it.
1901                                    continue;
1902                                }
1903                            }
1904                            nativeTotalPss += Debug.getPss(st.pid, null);
1905                        }
1906                    }
1907                    memInfo.readMemInfo();
1908                    synchronized (this) {
1909                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1910                                + (SystemClock.uptimeMillis()-start) + "ms");
1911                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1912                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1913                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1914                                        +memInfo.getSlabSizeKb(),
1915                                nativeTotalPss);
1916                    }
1917                }
1918
1919                int i=0, num=0;
1920                long[] tmp = new long[1];
1921                do {
1922                    ProcessRecord proc;
1923                    int procState;
1924                    int pid;
1925                    synchronized (ActivityManagerService.this) {
1926                        if (i >= mPendingPssProcesses.size()) {
1927                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1928                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1929                            mPendingPssProcesses.clear();
1930                            return;
1931                        }
1932                        proc = mPendingPssProcesses.get(i);
1933                        procState = proc.pssProcState;
1934                        if (proc.thread != null && procState == proc.setProcState) {
1935                            pid = proc.pid;
1936                        } else {
1937                            proc = null;
1938                            pid = 0;
1939                        }
1940                        i++;
1941                    }
1942                    if (proc != null) {
1943                        long pss = Debug.getPss(pid, tmp);
1944                        synchronized (ActivityManagerService.this) {
1945                            if (proc.thread != null && proc.setProcState == procState
1946                                    && proc.pid == pid) {
1947                                num++;
1948                                proc.lastPssTime = SystemClock.uptimeMillis();
1949                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1950                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1951                                        + ": " + pss + " lastPss=" + proc.lastPss
1952                                        + " state=" + ProcessList.makeProcStateString(procState));
1953                                if (proc.initialIdlePss == 0) {
1954                                    proc.initialIdlePss = pss;
1955                                }
1956                                proc.lastPss = pss;
1957                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1958                                    proc.lastCachedPss = pss;
1959                                }
1960                            }
1961                        }
1962                    }
1963                } while (true);
1964            }
1965            }
1966        }
1967    };
1968
1969    /**
1970     * Monitor for package changes and update our internal state.
1971     */
1972    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1973        @Override
1974        public void onPackageRemoved(String packageName, int uid) {
1975            // Remove all tasks with activities in the specified package from the list of recent tasks
1976            synchronized (ActivityManagerService.this) {
1977                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1978                    TaskRecord tr = mRecentTasks.get(i);
1979                    ComponentName cn = tr.intent.getComponent();
1980                    if (cn != null && cn.getPackageName().equals(packageName)) {
1981                        // If the package name matches, remove the task and kill the process
1982                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1983                    }
1984                }
1985            }
1986        }
1987
1988        @Override
1989        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1990            onPackageModified(packageName);
1991            return true;
1992        }
1993
1994        @Override
1995        public void onPackageModified(String packageName) {
1996            final PackageManager pm = mContext.getPackageManager();
1997            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1998                    new ArrayList<Pair<Intent, Integer>>();
1999            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2000            // Copy the list of recent tasks so that we don't hold onto the lock on
2001            // ActivityManagerService for long periods while checking if components exist.
2002            synchronized (ActivityManagerService.this) {
2003                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2004                    TaskRecord tr = mRecentTasks.get(i);
2005                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2006                }
2007            }
2008            // Check the recent tasks and filter out all tasks with components that no longer exist.
2009            Intent tmpI = new Intent();
2010            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2011                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2012                ComponentName cn = p.first.getComponent();
2013                if (cn != null && cn.getPackageName().equals(packageName)) {
2014                    try {
2015                        // Add the task to the list to remove if the component no longer exists
2016                        tmpI.setComponent(cn);
2017                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2018                            tasksToRemove.add(p.second);
2019                        }
2020                    } catch (Exception e) {}
2021                }
2022            }
2023            // Prune all the tasks with removed components from the list of recent tasks
2024            synchronized (ActivityManagerService.this) {
2025                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2026                    // Remove the task but don't kill the process (since other components in that
2027                    // package may still be running and in the background)
2028                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2029                }
2030            }
2031        }
2032
2033        @Override
2034        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2035            // Force stop the specified packages
2036            if (packages != null) {
2037                for (String pkg : packages) {
2038                    synchronized (ActivityManagerService.this) {
2039                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2040                                "finished booting")) {
2041                            return true;
2042                        }
2043                    }
2044                }
2045            }
2046            return false;
2047        }
2048    };
2049
2050    public void setSystemProcess() {
2051        try {
2052            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2053            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2054            ServiceManager.addService("meminfo", new MemBinder(this));
2055            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2056            ServiceManager.addService("dbinfo", new DbBinder(this));
2057            if (MONITOR_CPU_USAGE) {
2058                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2059            }
2060            ServiceManager.addService("permission", new PermissionController(this));
2061
2062            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2063                    "android", STOCK_PM_FLAGS);
2064            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2065
2066            synchronized (this) {
2067                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2068                app.persistent = true;
2069                app.pid = MY_PID;
2070                app.maxAdj = ProcessList.SYSTEM_ADJ;
2071                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2072                mProcessNames.put(app.processName, app.uid, app);
2073                synchronized (mPidsSelfLocked) {
2074                    mPidsSelfLocked.put(app.pid, app);
2075                }
2076                updateLruProcessLocked(app, false, null);
2077                updateOomAdjLocked();
2078            }
2079        } catch (PackageManager.NameNotFoundException e) {
2080            throw new RuntimeException(
2081                    "Unable to find android system package", e);
2082        }
2083    }
2084
2085    public void setWindowManager(WindowManagerService wm) {
2086        mWindowManager = wm;
2087        mStackSupervisor.setWindowManager(wm);
2088    }
2089
2090    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2091        mUsageStatsService = usageStatsManager;
2092    }
2093
2094    public void startObservingNativeCrashes() {
2095        final NativeCrashListener ncl = new NativeCrashListener(this);
2096        ncl.start();
2097    }
2098
2099    public IAppOpsService getAppOpsService() {
2100        return mAppOpsService;
2101    }
2102
2103    static class MemBinder extends Binder {
2104        ActivityManagerService mActivityManagerService;
2105        MemBinder(ActivityManagerService activityManagerService) {
2106            mActivityManagerService = activityManagerService;
2107        }
2108
2109        @Override
2110        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2111            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2112                    != PackageManager.PERMISSION_GRANTED) {
2113                pw.println("Permission Denial: can't dump meminfo from from pid="
2114                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2115                        + " without permission " + android.Manifest.permission.DUMP);
2116                return;
2117            }
2118
2119            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2120        }
2121    }
2122
2123    static class GraphicsBinder extends Binder {
2124        ActivityManagerService mActivityManagerService;
2125        GraphicsBinder(ActivityManagerService activityManagerService) {
2126            mActivityManagerService = activityManagerService;
2127        }
2128
2129        @Override
2130        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2131            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2132                    != PackageManager.PERMISSION_GRANTED) {
2133                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2134                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2135                        + " without permission " + android.Manifest.permission.DUMP);
2136                return;
2137            }
2138
2139            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2140        }
2141    }
2142
2143    static class DbBinder extends Binder {
2144        ActivityManagerService mActivityManagerService;
2145        DbBinder(ActivityManagerService activityManagerService) {
2146            mActivityManagerService = activityManagerService;
2147        }
2148
2149        @Override
2150        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2151            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2152                    != PackageManager.PERMISSION_GRANTED) {
2153                pw.println("Permission Denial: can't dump dbinfo from from pid="
2154                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2155                        + " without permission " + android.Manifest.permission.DUMP);
2156                return;
2157            }
2158
2159            mActivityManagerService.dumpDbInfo(fd, pw, args);
2160        }
2161    }
2162
2163    static class CpuBinder extends Binder {
2164        ActivityManagerService mActivityManagerService;
2165        CpuBinder(ActivityManagerService activityManagerService) {
2166            mActivityManagerService = activityManagerService;
2167        }
2168
2169        @Override
2170        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2171            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2172                    != PackageManager.PERMISSION_GRANTED) {
2173                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2174                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2175                        + " without permission " + android.Manifest.permission.DUMP);
2176                return;
2177            }
2178
2179            synchronized (mActivityManagerService.mProcessCpuThread) {
2180                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2181                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2182                        SystemClock.uptimeMillis()));
2183            }
2184        }
2185    }
2186
2187    public static final class Lifecycle extends SystemService {
2188        private final ActivityManagerService mService;
2189
2190        public Lifecycle(Context context) {
2191            super(context);
2192            mService = new ActivityManagerService(context);
2193        }
2194
2195        @Override
2196        public void onStart() {
2197            mService.start();
2198        }
2199
2200        public ActivityManagerService getService() {
2201            return mService;
2202        }
2203    }
2204
2205    // Note: This method is invoked on the main thread but may need to attach various
2206    // handlers to other threads.  So take care to be explicit about the looper.
2207    public ActivityManagerService(Context systemContext) {
2208        mContext = systemContext;
2209        mFactoryTest = FactoryTest.getMode();
2210        mSystemThread = ActivityThread.currentActivityThread();
2211
2212        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2213
2214        mHandlerThread = new ServiceThread(TAG,
2215                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2216        mHandlerThread.start();
2217        mHandler = new MainHandler(mHandlerThread.getLooper());
2218
2219        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2220                "foreground", BROADCAST_FG_TIMEOUT, false);
2221        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2222                "background", BROADCAST_BG_TIMEOUT, true);
2223        mBroadcastQueues[0] = mFgBroadcastQueue;
2224        mBroadcastQueues[1] = mBgBroadcastQueue;
2225
2226        mServices = new ActiveServices(this);
2227        mProviderMap = new ProviderMap(this);
2228
2229        // TODO: Move creation of battery stats service outside of activity manager service.
2230        File dataDir = Environment.getDataDirectory();
2231        File systemDir = new File(dataDir, "system");
2232        systemDir.mkdirs();
2233        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2234        mBatteryStatsService.getActiveStatistics().readLocked();
2235        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2236        mOnBattery = DEBUG_POWER ? true
2237                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2238        mBatteryStatsService.getActiveStatistics().setCallback(this);
2239
2240        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2241
2242        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2243
2244        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2245
2246        // User 0 is the first and only user that runs at boot.
2247        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2248        mUserLru.add(Integer.valueOf(0));
2249        updateStartedUserArrayLocked();
2250
2251        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2252            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2253
2254        mConfiguration.setToDefaults();
2255        mConfiguration.setLocale(Locale.getDefault());
2256
2257        mConfigurationSeq = mConfiguration.seq = 1;
2258        mProcessCpuTracker.init();
2259
2260        final Resources res = mContext.getResources();
2261        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
2262        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2263        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2264
2265        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2266        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2267        mStackSupervisor = new ActivityStackSupervisor(this);
2268        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2269
2270        mProcessCpuThread = new Thread("CpuTracker") {
2271            @Override
2272            public void run() {
2273                while (true) {
2274                    try {
2275                        try {
2276                            synchronized(this) {
2277                                final long now = SystemClock.uptimeMillis();
2278                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2279                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2280                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2281                                //        + ", write delay=" + nextWriteDelay);
2282                                if (nextWriteDelay < nextCpuDelay) {
2283                                    nextCpuDelay = nextWriteDelay;
2284                                }
2285                                if (nextCpuDelay > 0) {
2286                                    mProcessCpuMutexFree.set(true);
2287                                    this.wait(nextCpuDelay);
2288                                }
2289                            }
2290                        } catch (InterruptedException e) {
2291                        }
2292                        updateCpuStatsNow();
2293                    } catch (Exception e) {
2294                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2295                    }
2296                }
2297            }
2298        };
2299
2300        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2301
2302        Watchdog.getInstance().addMonitor(this);
2303        Watchdog.getInstance().addThread(mHandler);
2304    }
2305
2306    public void setSystemServiceManager(SystemServiceManager mgr) {
2307        mSystemServiceManager = mgr;
2308    }
2309
2310    private void start() {
2311        Process.removeAllProcessGroups();
2312        mProcessCpuThread.start();
2313
2314        mBatteryStatsService.publish(mContext);
2315        mAppOpsService.publish(mContext);
2316        Slog.d("AppOps", "AppOpsService published");
2317        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2318    }
2319
2320    public void initPowerManagement() {
2321        mStackSupervisor.initPowerManagement();
2322        mBatteryStatsService.initPowerManagement();
2323    }
2324
2325    @Override
2326    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2327            throws RemoteException {
2328        if (code == SYSPROPS_TRANSACTION) {
2329            // We need to tell all apps about the system property change.
2330            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2331            synchronized(this) {
2332                final int NP = mProcessNames.getMap().size();
2333                for (int ip=0; ip<NP; ip++) {
2334                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2335                    final int NA = apps.size();
2336                    for (int ia=0; ia<NA; ia++) {
2337                        ProcessRecord app = apps.valueAt(ia);
2338                        if (app.thread != null) {
2339                            procs.add(app.thread.asBinder());
2340                        }
2341                    }
2342                }
2343            }
2344
2345            int N = procs.size();
2346            for (int i=0; i<N; i++) {
2347                Parcel data2 = Parcel.obtain();
2348                try {
2349                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2350                } catch (RemoteException e) {
2351                }
2352                data2.recycle();
2353            }
2354        }
2355        try {
2356            return super.onTransact(code, data, reply, flags);
2357        } catch (RuntimeException e) {
2358            // The activity manager only throws security exceptions, so let's
2359            // log all others.
2360            if (!(e instanceof SecurityException)) {
2361                Slog.wtf(TAG, "Activity Manager Crash", e);
2362            }
2363            throw e;
2364        }
2365    }
2366
2367    void updateCpuStats() {
2368        final long now = SystemClock.uptimeMillis();
2369        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2370            return;
2371        }
2372        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2373            synchronized (mProcessCpuThread) {
2374                mProcessCpuThread.notify();
2375            }
2376        }
2377    }
2378
2379    void updateCpuStatsNow() {
2380        synchronized (mProcessCpuThread) {
2381            mProcessCpuMutexFree.set(false);
2382            final long now = SystemClock.uptimeMillis();
2383            boolean haveNewCpuStats = false;
2384
2385            if (MONITOR_CPU_USAGE &&
2386                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2387                mLastCpuTime.set(now);
2388                haveNewCpuStats = true;
2389                mProcessCpuTracker.update();
2390                //Slog.i(TAG, mProcessCpu.printCurrentState());
2391                //Slog.i(TAG, "Total CPU usage: "
2392                //        + mProcessCpu.getTotalCpuPercent() + "%");
2393
2394                // Slog the cpu usage if the property is set.
2395                if ("true".equals(SystemProperties.get("events.cpu"))) {
2396                    int user = mProcessCpuTracker.getLastUserTime();
2397                    int system = mProcessCpuTracker.getLastSystemTime();
2398                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2399                    int irq = mProcessCpuTracker.getLastIrqTime();
2400                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2401                    int idle = mProcessCpuTracker.getLastIdleTime();
2402
2403                    int total = user + system + iowait + irq + softIrq + idle;
2404                    if (total == 0) total = 1;
2405
2406                    EventLog.writeEvent(EventLogTags.CPU,
2407                            ((user+system+iowait+irq+softIrq) * 100) / total,
2408                            (user * 100) / total,
2409                            (system * 100) / total,
2410                            (iowait * 100) / total,
2411                            (irq * 100) / total,
2412                            (softIrq * 100) / total);
2413                }
2414            }
2415
2416            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2417            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2418            synchronized(bstats) {
2419                synchronized(mPidsSelfLocked) {
2420                    if (haveNewCpuStats) {
2421                        if (mOnBattery) {
2422                            int perc = bstats.startAddingCpuLocked();
2423                            int totalUTime = 0;
2424                            int totalSTime = 0;
2425                            final int N = mProcessCpuTracker.countStats();
2426                            for (int i=0; i<N; i++) {
2427                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2428                                if (!st.working) {
2429                                    continue;
2430                                }
2431                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2432                                int otherUTime = (st.rel_utime*perc)/100;
2433                                int otherSTime = (st.rel_stime*perc)/100;
2434                                totalUTime += otherUTime;
2435                                totalSTime += otherSTime;
2436                                if (pr != null) {
2437                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2438                                    if (ps == null || !ps.isActive()) {
2439                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2440                                                pr.info.uid, pr.processName);
2441                                    }
2442                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2443                                            st.rel_stime-otherSTime);
2444                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2445                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2446                                } else {
2447                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2448                                    if (ps == null || !ps.isActive()) {
2449                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2450                                                bstats.mapUid(st.uid), st.name);
2451                                    }
2452                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2453                                            st.rel_stime-otherSTime);
2454                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2455                                }
2456                            }
2457                            bstats.finishAddingCpuLocked(perc, totalUTime,
2458                                    totalSTime, cpuSpeedTimes);
2459                        }
2460                    }
2461                }
2462
2463                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2464                    mLastWriteTime = now;
2465                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2466                }
2467            }
2468        }
2469    }
2470
2471    @Override
2472    public void batteryNeedsCpuUpdate() {
2473        updateCpuStatsNow();
2474    }
2475
2476    @Override
2477    public void batteryPowerChanged(boolean onBattery) {
2478        // When plugging in, update the CPU stats first before changing
2479        // the plug state.
2480        updateCpuStatsNow();
2481        synchronized (this) {
2482            synchronized(mPidsSelfLocked) {
2483                mOnBattery = DEBUG_POWER ? true : onBattery;
2484            }
2485        }
2486    }
2487
2488    /**
2489     * Initialize the application bind args. These are passed to each
2490     * process when the bindApplication() IPC is sent to the process. They're
2491     * lazily setup to make sure the services are running when they're asked for.
2492     */
2493    private HashMap<String, IBinder> getCommonServicesLocked() {
2494        if (mAppBindArgs == null) {
2495            mAppBindArgs = new HashMap<String, IBinder>();
2496
2497            // Setup the application init args
2498            mAppBindArgs.put("package", ServiceManager.getService("package"));
2499            mAppBindArgs.put("window", ServiceManager.getService("window"));
2500            mAppBindArgs.put(Context.ALARM_SERVICE,
2501                    ServiceManager.getService(Context.ALARM_SERVICE));
2502        }
2503        return mAppBindArgs;
2504    }
2505
2506    final void setFocusedActivityLocked(ActivityRecord r) {
2507        if (mFocusedActivity != r) {
2508            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2509            mFocusedActivity = r;
2510            if (r.task != null && r.task.voiceInteractor != null) {
2511                startRunningVoiceLocked();
2512            } else {
2513                finishRunningVoiceLocked();
2514            }
2515            mStackSupervisor.setFocusedStack(r);
2516            if (r != null) {
2517                mWindowManager.setFocusedApp(r.appToken, true);
2518            }
2519            applyUpdateLockStateLocked(r);
2520        }
2521    }
2522
2523    final void clearFocusedActivity(ActivityRecord r) {
2524        if (mFocusedActivity == r) {
2525            mFocusedActivity = null;
2526        }
2527    }
2528
2529    @Override
2530    public void setFocusedStack(int stackId) {
2531        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2532        synchronized (ActivityManagerService.this) {
2533            ActivityStack stack = mStackSupervisor.getStack(stackId);
2534            if (stack != null) {
2535                ActivityRecord r = stack.topRunningActivityLocked(null);
2536                if (r != null) {
2537                    setFocusedActivityLocked(r);
2538                }
2539            }
2540        }
2541    }
2542
2543    @Override
2544    public void notifyActivityDrawn(IBinder token) {
2545        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2546        synchronized (this) {
2547            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2548            if (r != null) {
2549                r.task.stack.notifyActivityDrawnLocked(r);
2550            }
2551        }
2552    }
2553
2554    final void applyUpdateLockStateLocked(ActivityRecord r) {
2555        // Modifications to the UpdateLock state are done on our handler, outside
2556        // the activity manager's locks.  The new state is determined based on the
2557        // state *now* of the relevant activity record.  The object is passed to
2558        // the handler solely for logging detail, not to be consulted/modified.
2559        final boolean nextState = r != null && r.immersive;
2560        mHandler.sendMessage(
2561                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2562    }
2563
2564    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2565        Message msg = Message.obtain();
2566        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2567        msg.obj = r.task.askedCompatMode ? null : r;
2568        mHandler.sendMessage(msg);
2569    }
2570
2571    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2572            String what, Object obj, ProcessRecord srcApp) {
2573        app.lastActivityTime = now;
2574
2575        if (app.activities.size() > 0) {
2576            // Don't want to touch dependent processes that are hosting activities.
2577            return index;
2578        }
2579
2580        int lrui = mLruProcesses.lastIndexOf(app);
2581        if (lrui < 0) {
2582            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2583                    + what + " " + obj + " from " + srcApp);
2584            return index;
2585        }
2586
2587        if (lrui >= index) {
2588            // Don't want to cause this to move dependent processes *back* in the
2589            // list as if they were less frequently used.
2590            return index;
2591        }
2592
2593        if (lrui >= mLruProcessActivityStart) {
2594            // Don't want to touch dependent processes that are hosting activities.
2595            return index;
2596        }
2597
2598        mLruProcesses.remove(lrui);
2599        if (index > 0) {
2600            index--;
2601        }
2602        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2603                + " in LRU list: " + app);
2604        mLruProcesses.add(index, app);
2605        return index;
2606    }
2607
2608    final void removeLruProcessLocked(ProcessRecord app) {
2609        int lrui = mLruProcesses.lastIndexOf(app);
2610        if (lrui >= 0) {
2611            if (lrui <= mLruProcessActivityStart) {
2612                mLruProcessActivityStart--;
2613            }
2614            if (lrui <= mLruProcessServiceStart) {
2615                mLruProcessServiceStart--;
2616            }
2617            mLruProcesses.remove(lrui);
2618        }
2619    }
2620
2621    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2622            ProcessRecord client) {
2623        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2624                || app.treatLikeActivity;
2625        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2626        if (!activityChange && hasActivity) {
2627            // The process has activities, so we are only allowing activity-based adjustments
2628            // to move it.  It should be kept in the front of the list with other
2629            // processes that have activities, and we don't want those to change their
2630            // order except due to activity operations.
2631            return;
2632        }
2633
2634        mLruSeq++;
2635        final long now = SystemClock.uptimeMillis();
2636        app.lastActivityTime = now;
2637
2638        // First a quick reject: if the app is already at the position we will
2639        // put it, then there is nothing to do.
2640        if (hasActivity) {
2641            final int N = mLruProcesses.size();
2642            if (N > 0 && mLruProcesses.get(N-1) == app) {
2643                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2644                return;
2645            }
2646        } else {
2647            if (mLruProcessServiceStart > 0
2648                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2649                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2650                return;
2651            }
2652        }
2653
2654        int lrui = mLruProcesses.lastIndexOf(app);
2655
2656        if (app.persistent && lrui >= 0) {
2657            // We don't care about the position of persistent processes, as long as
2658            // they are in the list.
2659            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2660            return;
2661        }
2662
2663        /* In progress: compute new position first, so we can avoid doing work
2664           if the process is not actually going to move.  Not yet working.
2665        int addIndex;
2666        int nextIndex;
2667        boolean inActivity = false, inService = false;
2668        if (hasActivity) {
2669            // Process has activities, put it at the very tipsy-top.
2670            addIndex = mLruProcesses.size();
2671            nextIndex = mLruProcessServiceStart;
2672            inActivity = true;
2673        } else if (hasService) {
2674            // Process has services, put it at the top of the service list.
2675            addIndex = mLruProcessActivityStart;
2676            nextIndex = mLruProcessServiceStart;
2677            inActivity = true;
2678            inService = true;
2679        } else  {
2680            // Process not otherwise of interest, it goes to the top of the non-service area.
2681            addIndex = mLruProcessServiceStart;
2682            if (client != null) {
2683                int clientIndex = mLruProcesses.lastIndexOf(client);
2684                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2685                        + app);
2686                if (clientIndex >= 0 && addIndex > clientIndex) {
2687                    addIndex = clientIndex;
2688                }
2689            }
2690            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2691        }
2692
2693        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2694                + mLruProcessActivityStart + "): " + app);
2695        */
2696
2697        if (lrui >= 0) {
2698            if (lrui < mLruProcessActivityStart) {
2699                mLruProcessActivityStart--;
2700            }
2701            if (lrui < mLruProcessServiceStart) {
2702                mLruProcessServiceStart--;
2703            }
2704            /*
2705            if (addIndex > lrui) {
2706                addIndex--;
2707            }
2708            if (nextIndex > lrui) {
2709                nextIndex--;
2710            }
2711            */
2712            mLruProcesses.remove(lrui);
2713        }
2714
2715        /*
2716        mLruProcesses.add(addIndex, app);
2717        if (inActivity) {
2718            mLruProcessActivityStart++;
2719        }
2720        if (inService) {
2721            mLruProcessActivityStart++;
2722        }
2723        */
2724
2725        int nextIndex;
2726        if (hasActivity) {
2727            final int N = mLruProcesses.size();
2728            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2729                // Process doesn't have activities, but has clients with
2730                // activities...  move it up, but one below the top (the top
2731                // should always have a real activity).
2732                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2733                mLruProcesses.add(N-1, app);
2734                // To keep it from spamming the LRU list (by making a bunch of clients),
2735                // we will push down any other entries owned by the app.
2736                final int uid = app.info.uid;
2737                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2738                    ProcessRecord subProc = mLruProcesses.get(i);
2739                    if (subProc.info.uid == uid) {
2740                        // We want to push this one down the list.  If the process after
2741                        // it is for the same uid, however, don't do so, because we don't
2742                        // want them internally to be re-ordered.
2743                        if (mLruProcesses.get(i-1).info.uid != uid) {
2744                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2745                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2746                            ProcessRecord tmp = mLruProcesses.get(i);
2747                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2748                            mLruProcesses.set(i-1, tmp);
2749                            i--;
2750                        }
2751                    } else {
2752                        // A gap, we can stop here.
2753                        break;
2754                    }
2755                }
2756            } else {
2757                // Process has activities, put it at the very tipsy-top.
2758                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2759                mLruProcesses.add(app);
2760            }
2761            nextIndex = mLruProcessServiceStart;
2762        } else if (hasService) {
2763            // Process has services, put it at the top of the service list.
2764            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2765            mLruProcesses.add(mLruProcessActivityStart, app);
2766            nextIndex = mLruProcessServiceStart;
2767            mLruProcessActivityStart++;
2768        } else  {
2769            // Process not otherwise of interest, it goes to the top of the non-service area.
2770            int index = mLruProcessServiceStart;
2771            if (client != null) {
2772                // If there is a client, don't allow the process to be moved up higher
2773                // in the list than that client.
2774                int clientIndex = mLruProcesses.lastIndexOf(client);
2775                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2776                        + " when updating " + app);
2777                if (clientIndex <= lrui) {
2778                    // Don't allow the client index restriction to push it down farther in the
2779                    // list than it already is.
2780                    clientIndex = lrui;
2781                }
2782                if (clientIndex >= 0 && index > clientIndex) {
2783                    index = clientIndex;
2784                }
2785            }
2786            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2787            mLruProcesses.add(index, app);
2788            nextIndex = index-1;
2789            mLruProcessActivityStart++;
2790            mLruProcessServiceStart++;
2791        }
2792
2793        // If the app is currently using a content provider or service,
2794        // bump those processes as well.
2795        for (int j=app.connections.size()-1; j>=0; j--) {
2796            ConnectionRecord cr = app.connections.valueAt(j);
2797            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2798                    && cr.binding.service.app != null
2799                    && cr.binding.service.app.lruSeq != mLruSeq
2800                    && !cr.binding.service.app.persistent) {
2801                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2802                        "service connection", cr, app);
2803            }
2804        }
2805        for (int j=app.conProviders.size()-1; j>=0; j--) {
2806            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2807            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2808                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2809                        "provider reference", cpr, app);
2810            }
2811        }
2812    }
2813
2814    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2815        if (uid == Process.SYSTEM_UID) {
2816            // The system gets to run in any process.  If there are multiple
2817            // processes with the same uid, just pick the first (this
2818            // should never happen).
2819            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2820            if (procs == null) return null;
2821            final int N = procs.size();
2822            for (int i = 0; i < N; i++) {
2823                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2824            }
2825        }
2826        ProcessRecord proc = mProcessNames.get(processName, uid);
2827        if (false && proc != null && !keepIfLarge
2828                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2829                && proc.lastCachedPss >= 4000) {
2830            // Turn this condition on to cause killing to happen regularly, for testing.
2831            if (proc.baseProcessTracker != null) {
2832                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2833            }
2834            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2835                    + "k from cached");
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                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2845                        + "k from cached");
2846            }
2847        }
2848        return proc;
2849    }
2850
2851    void ensurePackageDexOpt(String packageName) {
2852        IPackageManager pm = AppGlobals.getPackageManager();
2853        try {
2854            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2855                mDidDexOpt = true;
2856            }
2857        } catch (RemoteException e) {
2858        }
2859    }
2860
2861    boolean isNextTransitionForward() {
2862        int transit = mWindowManager.getPendingAppTransition();
2863        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2864                || transit == AppTransition.TRANSIT_TASK_OPEN
2865                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2866    }
2867
2868    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2869            String processName, String abiOverride, int uid, Runnable crashHandler) {
2870        synchronized(this) {
2871            ApplicationInfo info = new ApplicationInfo();
2872            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2873            // For isolated processes, the former contains the parent's uid and the latter the
2874            // actual uid of the isolated process.
2875            // In the special case introduced by this method (which is, starting an isolated
2876            // process directly from the SystemServer without an actual parent app process) the
2877            // closest thing to a parent's uid is SYSTEM_UID.
2878            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2879            // the |isolated| logic in the ProcessRecord constructor.
2880            info.uid = Process.SYSTEM_UID;
2881            info.processName = processName;
2882            info.className = entryPoint;
2883            info.packageName = "android";
2884            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2885                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2886                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2887                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2888                    crashHandler);
2889            return proc != null ? proc.pid : 0;
2890        }
2891    }
2892
2893    final ProcessRecord startProcessLocked(String processName,
2894            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2895            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2896            boolean isolated, boolean keepIfLarge) {
2897        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2898                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2899                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2900                null /* crashHandler */);
2901    }
2902
2903    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2904            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2905            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2906            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2907        ProcessRecord app;
2908        if (!isolated) {
2909            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2910        } else {
2911            // If this is an isolated process, it can't re-use an existing process.
2912            app = null;
2913        }
2914        // We don't have to do anything more if:
2915        // (1) There is an existing application record; and
2916        // (2) The caller doesn't think it is dead, OR there is no thread
2917        //     object attached to it so we know it couldn't have crashed; and
2918        // (3) There is a pid assigned to it, so it is either starting or
2919        //     already running.
2920        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2921                + " app=" + app + " knownToBeDead=" + knownToBeDead
2922                + " thread=" + (app != null ? app.thread : null)
2923                + " pid=" + (app != null ? app.pid : -1));
2924        if (app != null && app.pid > 0) {
2925            if (!knownToBeDead || app.thread == null) {
2926                // We already have the app running, or are waiting for it to
2927                // come up (we have a pid but not yet its thread), so keep it.
2928                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2929                // If this is a new package in the process, add the package to the list
2930                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2931                return app;
2932            }
2933
2934            // An application record is attached to a previous process,
2935            // clean it up now.
2936            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2937            Process.killProcessGroup(app.info.uid, app.pid);
2938            handleAppDiedLocked(app, true, true);
2939        }
2940
2941        String hostingNameStr = hostingName != null
2942                ? hostingName.flattenToShortString() : null;
2943
2944        if (!isolated) {
2945            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2946                // If we are in the background, then check to see if this process
2947                // is bad.  If so, we will just silently fail.
2948                if (mBadProcesses.get(info.processName, info.uid) != null) {
2949                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2950                            + "/" + info.processName);
2951                    return null;
2952                }
2953            } else {
2954                // When the user is explicitly starting a process, then clear its
2955                // crash count so that we won't make it bad until they see at
2956                // least one crash dialog again, and make the process good again
2957                // if it had been bad.
2958                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2959                        + "/" + info.processName);
2960                mProcessCrashTimes.remove(info.processName, info.uid);
2961                if (mBadProcesses.get(info.processName, info.uid) != null) {
2962                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2963                            UserHandle.getUserId(info.uid), info.uid,
2964                            info.processName);
2965                    mBadProcesses.remove(info.processName, info.uid);
2966                    if (app != null) {
2967                        app.bad = false;
2968                    }
2969                }
2970            }
2971        }
2972
2973        if (app == null) {
2974            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2975            app.crashHandler = crashHandler;
2976            if (app == null) {
2977                Slog.w(TAG, "Failed making new process record for "
2978                        + processName + "/" + info.uid + " isolated=" + isolated);
2979                return null;
2980            }
2981            mProcessNames.put(processName, app.uid, app);
2982            if (isolated) {
2983                mIsolatedProcesses.put(app.uid, app);
2984            }
2985        } else {
2986            // If this is a new package in the process, add the package to the list
2987            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2988        }
2989
2990        // If the system is not ready yet, then hold off on starting this
2991        // process until it is.
2992        if (!mProcessesReady
2993                && !isAllowedWhileBooting(info)
2994                && !allowWhileBooting) {
2995            if (!mProcessesOnHold.contains(app)) {
2996                mProcessesOnHold.add(app);
2997            }
2998            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2999            return app;
3000        }
3001
3002        startProcessLocked(
3003                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3004        return (app.pid != 0) ? app : null;
3005    }
3006
3007    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3008        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3009    }
3010
3011    private final void startProcessLocked(ProcessRecord app,
3012            String hostingType, String hostingNameStr) {
3013        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3014                null /* entryPoint */, null /* entryPointArgs */);
3015    }
3016
3017    private final void startProcessLocked(ProcessRecord app, String hostingType,
3018            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3019        if (app.pid > 0 && app.pid != MY_PID) {
3020            synchronized (mPidsSelfLocked) {
3021                mPidsSelfLocked.remove(app.pid);
3022                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3023            }
3024            app.setPid(0);
3025        }
3026
3027        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3028                "startProcessLocked removing on hold: " + app);
3029        mProcessesOnHold.remove(app);
3030
3031        updateCpuStats();
3032
3033        try {
3034            int uid = app.uid;
3035
3036            int[] gids = null;
3037            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3038            if (!app.isolated) {
3039                int[] permGids = null;
3040                try {
3041                    final PackageManager pm = mContext.getPackageManager();
3042                    permGids = pm.getPackageGids(app.info.packageName);
3043
3044                    if (Environment.isExternalStorageEmulated()) {
3045                        if (pm.checkPermission(
3046                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3047                                app.info.packageName) == PERMISSION_GRANTED) {
3048                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3049                        } else {
3050                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3051                        }
3052                    }
3053                } catch (PackageManager.NameNotFoundException e) {
3054                    Slog.w(TAG, "Unable to retrieve gids", e);
3055                }
3056
3057                /*
3058                 * Add shared application and profile GIDs so applications can share some
3059                 * resources like shared libraries and access user-wide resources
3060                 */
3061                if (permGids == null) {
3062                    gids = new int[2];
3063                } else {
3064                    gids = new int[permGids.length + 2];
3065                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3066                }
3067                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3068                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3069            }
3070            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3071                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3072                        && mTopComponent != null
3073                        && app.processName.equals(mTopComponent.getPackageName())) {
3074                    uid = 0;
3075                }
3076                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3077                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3078                    uid = 0;
3079                }
3080            }
3081            int debugFlags = 0;
3082            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3083                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3084                // Also turn on CheckJNI for debuggable apps. It's quite
3085                // awkward to turn on otherwise.
3086                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3087            }
3088            // Run the app in safe mode if its manifest requests so or the
3089            // system is booted in safe mode.
3090            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3091                mSafeMode == true) {
3092                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3093            }
3094            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3095                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3096            }
3097            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3098                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3099            }
3100            if ("1".equals(SystemProperties.get("debug.assert"))) {
3101                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3102            }
3103
3104            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3105            if (requiredAbi == null) {
3106                requiredAbi = Build.SUPPORTED_ABIS[0];
3107            }
3108
3109            // Start the process.  It will either succeed and return a result containing
3110            // the PID of the new process, or else throw a RuntimeException.
3111            boolean isActivityProcess = (entryPoint == null);
3112            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3113            Process.ProcessStartResult startResult = Process.start(entryPoint,
3114                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3115                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3116
3117            if (app.isolated) {
3118                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3119            }
3120            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3121
3122            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3123                    UserHandle.getUserId(uid), startResult.pid, uid,
3124                    app.processName, hostingType,
3125                    hostingNameStr != null ? hostingNameStr : "");
3126
3127            if (app.persistent) {
3128                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3129            }
3130
3131            StringBuilder buf = mStringBuilder;
3132            buf.setLength(0);
3133            buf.append("Start proc ");
3134            buf.append(app.processName);
3135            if (!isActivityProcess) {
3136                buf.append(" [");
3137                buf.append(entryPoint);
3138                buf.append("]");
3139            }
3140            buf.append(" for ");
3141            buf.append(hostingType);
3142            if (hostingNameStr != null) {
3143                buf.append(" ");
3144                buf.append(hostingNameStr);
3145            }
3146            buf.append(": pid=");
3147            buf.append(startResult.pid);
3148            buf.append(" uid=");
3149            buf.append(uid);
3150            buf.append(" gids={");
3151            if (gids != null) {
3152                for (int gi=0; gi<gids.length; gi++) {
3153                    if (gi != 0) buf.append(", ");
3154                    buf.append(gids[gi]);
3155
3156                }
3157            }
3158            buf.append("}");
3159            if (requiredAbi != null) {
3160                buf.append(" abi=");
3161                buf.append(requiredAbi);
3162            }
3163            Slog.i(TAG, buf.toString());
3164            app.setPid(startResult.pid);
3165            app.usingWrapper = startResult.usingWrapper;
3166            app.removed = false;
3167            app.killedByAm = false;
3168            synchronized (mPidsSelfLocked) {
3169                this.mPidsSelfLocked.put(startResult.pid, app);
3170                if (isActivityProcess) {
3171                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3172                    msg.obj = app;
3173                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3174                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3175                }
3176            }
3177        } catch (RuntimeException e) {
3178            // XXX do better error recovery.
3179            app.setPid(0);
3180            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3181            if (app.isolated) {
3182                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3183            }
3184            Slog.e(TAG, "Failure starting process " + app.processName, e);
3185        }
3186    }
3187
3188    void updateUsageStats(ActivityRecord component, boolean resumed) {
3189        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3190        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3191        if (resumed) {
3192            if (mUsageStatsService != null) {
3193                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3194                        System.currentTimeMillis(),
3195                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3196            }
3197            synchronized (stats) {
3198                stats.noteActivityResumedLocked(component.app.uid);
3199            }
3200        } else {
3201            if (mUsageStatsService != null) {
3202                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3203                        System.currentTimeMillis(),
3204                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3205            }
3206            synchronized (stats) {
3207                stats.noteActivityPausedLocked(component.app.uid);
3208            }
3209        }
3210    }
3211
3212    Intent getHomeIntent() {
3213        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3214        intent.setComponent(mTopComponent);
3215        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3216            intent.addCategory(Intent.CATEGORY_HOME);
3217        }
3218        return intent;
3219    }
3220
3221    boolean startHomeActivityLocked(int userId) {
3222        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3223                && mTopAction == null) {
3224            // We are running in factory test mode, but unable to find
3225            // the factory test app, so just sit around displaying the
3226            // error message and don't try to start anything.
3227            return false;
3228        }
3229        Intent intent = getHomeIntent();
3230        ActivityInfo aInfo =
3231            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3232        if (aInfo != null) {
3233            intent.setComponent(new ComponentName(
3234                    aInfo.applicationInfo.packageName, aInfo.name));
3235            // Don't do this if the home app is currently being
3236            // instrumented.
3237            aInfo = new ActivityInfo(aInfo);
3238            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3239            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3240                    aInfo.applicationInfo.uid, true);
3241            if (app == null || app.instrumentationClass == null) {
3242                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3243                mStackSupervisor.startHomeActivity(intent, aInfo);
3244            }
3245        }
3246
3247        return true;
3248    }
3249
3250    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3251        ActivityInfo ai = null;
3252        ComponentName comp = intent.getComponent();
3253        try {
3254            if (comp != null) {
3255                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3256            } else {
3257                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3258                        intent,
3259                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3260                            flags, userId);
3261
3262                if (info != null) {
3263                    ai = info.activityInfo;
3264                }
3265            }
3266        } catch (RemoteException e) {
3267            // ignore
3268        }
3269
3270        return ai;
3271    }
3272
3273    /**
3274     * Starts the "new version setup screen" if appropriate.
3275     */
3276    void startSetupActivityLocked() {
3277        // Only do this once per boot.
3278        if (mCheckedForSetup) {
3279            return;
3280        }
3281
3282        // We will show this screen if the current one is a different
3283        // version than the last one shown, and we are not running in
3284        // low-level factory test mode.
3285        final ContentResolver resolver = mContext.getContentResolver();
3286        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3287                Settings.Global.getInt(resolver,
3288                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3289            mCheckedForSetup = true;
3290
3291            // See if we should be showing the platform update setup UI.
3292            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3293            List<ResolveInfo> ris = mContext.getPackageManager()
3294                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3295
3296            // We don't allow third party apps to replace this.
3297            ResolveInfo ri = null;
3298            for (int i=0; ris != null && i<ris.size(); i++) {
3299                if ((ris.get(i).activityInfo.applicationInfo.flags
3300                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3301                    ri = ris.get(i);
3302                    break;
3303                }
3304            }
3305
3306            if (ri != null) {
3307                String vers = ri.activityInfo.metaData != null
3308                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3309                        : null;
3310                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3311                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3312                            Intent.METADATA_SETUP_VERSION);
3313                }
3314                String lastVers = Settings.Secure.getString(
3315                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3316                if (vers != null && !vers.equals(lastVers)) {
3317                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3318                    intent.setComponent(new ComponentName(
3319                            ri.activityInfo.packageName, ri.activityInfo.name));
3320                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3321                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3322                }
3323            }
3324        }
3325    }
3326
3327    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3328        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3329    }
3330
3331    void enforceNotIsolatedCaller(String caller) {
3332        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3333            throw new SecurityException("Isolated process not allowed to call " + caller);
3334        }
3335    }
3336
3337    @Override
3338    public int getFrontActivityScreenCompatMode() {
3339        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3340        synchronized (this) {
3341            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3342        }
3343    }
3344
3345    @Override
3346    public void setFrontActivityScreenCompatMode(int mode) {
3347        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3348                "setFrontActivityScreenCompatMode");
3349        synchronized (this) {
3350            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3351        }
3352    }
3353
3354    @Override
3355    public int getPackageScreenCompatMode(String packageName) {
3356        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3357        synchronized (this) {
3358            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3359        }
3360    }
3361
3362    @Override
3363    public void setPackageScreenCompatMode(String packageName, int mode) {
3364        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3365                "setPackageScreenCompatMode");
3366        synchronized (this) {
3367            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3368        }
3369    }
3370
3371    @Override
3372    public boolean getPackageAskScreenCompat(String packageName) {
3373        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3374        synchronized (this) {
3375            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3376        }
3377    }
3378
3379    @Override
3380    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3381        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3382                "setPackageAskScreenCompat");
3383        synchronized (this) {
3384            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3385        }
3386    }
3387
3388    private void dispatchProcessesChanged() {
3389        int N;
3390        synchronized (this) {
3391            N = mPendingProcessChanges.size();
3392            if (mActiveProcessChanges.length < N) {
3393                mActiveProcessChanges = new ProcessChangeItem[N];
3394            }
3395            mPendingProcessChanges.toArray(mActiveProcessChanges);
3396            mAvailProcessChanges.addAll(mPendingProcessChanges);
3397            mPendingProcessChanges.clear();
3398            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3399        }
3400
3401        int i = mProcessObservers.beginBroadcast();
3402        while (i > 0) {
3403            i--;
3404            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3405            if (observer != null) {
3406                try {
3407                    for (int j=0; j<N; j++) {
3408                        ProcessChangeItem item = mActiveProcessChanges[j];
3409                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3410                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3411                                    + item.pid + " uid=" + item.uid + ": "
3412                                    + item.foregroundActivities);
3413                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3414                                    item.foregroundActivities);
3415                        }
3416                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3417                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3418                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3419                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3420                        }
3421                    }
3422                } catch (RemoteException e) {
3423                }
3424            }
3425        }
3426        mProcessObservers.finishBroadcast();
3427    }
3428
3429    private void dispatchProcessDied(int pid, int uid) {
3430        int i = mProcessObservers.beginBroadcast();
3431        while (i > 0) {
3432            i--;
3433            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3434            if (observer != null) {
3435                try {
3436                    observer.onProcessDied(pid, uid);
3437                } catch (RemoteException e) {
3438                }
3439            }
3440        }
3441        mProcessObservers.finishBroadcast();
3442    }
3443
3444    @Override
3445    public final int startActivity(IApplicationThread caller, String callingPackage,
3446            Intent intent, String resolvedType, IBinder resultTo,
3447            String resultWho, int requestCode, int startFlags,
3448            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3449        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3450                resultWho, requestCode,
3451                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3452    }
3453
3454    @Override
3455    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3456            Intent intent, String resolvedType, IBinder resultTo,
3457            String resultWho, int requestCode, int startFlags,
3458            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3459        enforceNotIsolatedCaller("startActivity");
3460        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3461                false, ALLOW_FULL_ONLY, "startActivity", null);
3462        // TODO: Switch to user app stacks here.
3463        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3464                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3465                null, null, options, userId, null);
3466    }
3467
3468    @Override
3469    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3470            Intent intent, String resolvedType, IBinder resultTo,
3471            String resultWho, int requestCode, int startFlags,
3472            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3473
3474        // This is very dangerous -- it allows you to perform a start activity (including
3475        // permission grants) as any app that may launch one of your own activities.  So
3476        // we will only allow this to be done from activities that are part of the core framework,
3477        // and then only when they are running as the system.
3478        final ActivityRecord sourceRecord;
3479        final int targetUid;
3480        final String targetPackage;
3481        synchronized (this) {
3482            if (resultTo == null) {
3483                throw new SecurityException("Must be called from an activity");
3484            }
3485            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3486            if (sourceRecord == null) {
3487                throw new SecurityException("Called with bad activity token: " + resultTo);
3488            }
3489            if (!sourceRecord.info.packageName.equals("android")) {
3490                throw new SecurityException(
3491                        "Must be called from an activity that is declared in the android package");
3492            }
3493            if (sourceRecord.app == null) {
3494                throw new SecurityException("Called without a process attached to activity");
3495            }
3496            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3497                // This is still okay, as long as this activity is running under the
3498                // uid of the original calling activity.
3499                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3500                    throw new SecurityException(
3501                            "Calling activity in uid " + sourceRecord.app.uid
3502                                    + " must be system uid or original calling uid "
3503                                    + sourceRecord.launchedFromUid);
3504                }
3505            }
3506            targetUid = sourceRecord.launchedFromUid;
3507            targetPackage = sourceRecord.launchedFromPackage;
3508        }
3509
3510        // TODO: Switch to user app stacks here.
3511        try {
3512            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3513                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3514                    null, null, null, null, options, UserHandle.getUserId(sourceRecord.app.uid),
3515                    null);
3516            return ret;
3517        } catch (SecurityException e) {
3518            // XXX need to figure out how to propagate to original app.
3519            // A SecurityException here is generally actually a fault of the original
3520            // calling activity (such as a fairly granting permissions), so propagate it
3521            // back to them.
3522            /*
3523            StringBuilder msg = new StringBuilder();
3524            msg.append("While launching");
3525            msg.append(intent.toString());
3526            msg.append(": ");
3527            msg.append(e.getMessage());
3528            */
3529            throw e;
3530        }
3531    }
3532
3533    @Override
3534    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3535            Intent intent, String resolvedType, IBinder resultTo,
3536            String resultWho, int requestCode, int startFlags, String profileFile,
3537            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3538        enforceNotIsolatedCaller("startActivityAndWait");
3539        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3540                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3541        WaitResult res = new WaitResult();
3542        // TODO: Switch to user app stacks here.
3543        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3544                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3545                res, null, options, userId, null);
3546        return res;
3547    }
3548
3549    @Override
3550    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3551            Intent intent, String resolvedType, IBinder resultTo,
3552            String resultWho, int requestCode, int startFlags, Configuration config,
3553            Bundle options, int userId) {
3554        enforceNotIsolatedCaller("startActivityWithConfig");
3555        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3556                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3557        // TODO: Switch to user app stacks here.
3558        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3559                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3560                null, null, null, config, options, userId, null);
3561        return ret;
3562    }
3563
3564    @Override
3565    public int startActivityIntentSender(IApplicationThread caller,
3566            IntentSender intent, Intent fillInIntent, String resolvedType,
3567            IBinder resultTo, String resultWho, int requestCode,
3568            int flagsMask, int flagsValues, Bundle options) {
3569        enforceNotIsolatedCaller("startActivityIntentSender");
3570        // Refuse possible leaked file descriptors
3571        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3572            throw new IllegalArgumentException("File descriptors passed in Intent");
3573        }
3574
3575        IIntentSender sender = intent.getTarget();
3576        if (!(sender instanceof PendingIntentRecord)) {
3577            throw new IllegalArgumentException("Bad PendingIntent object");
3578        }
3579
3580        PendingIntentRecord pir = (PendingIntentRecord)sender;
3581
3582        synchronized (this) {
3583            // If this is coming from the currently resumed activity, it is
3584            // effectively saying that app switches are allowed at this point.
3585            final ActivityStack stack = getFocusedStack();
3586            if (stack.mResumedActivity != null &&
3587                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3588                mAppSwitchesAllowedTime = 0;
3589            }
3590        }
3591        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3592                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3593        return ret;
3594    }
3595
3596    @Override
3597    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3598            Intent intent, String resolvedType, IVoiceInteractionSession session,
3599            IVoiceInteractor interactor, int startFlags, String profileFile,
3600            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3601        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3602                != PackageManager.PERMISSION_GRANTED) {
3603            String msg = "Permission Denial: startVoiceActivity() from pid="
3604                    + Binder.getCallingPid()
3605                    + ", uid=" + Binder.getCallingUid()
3606                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3607            Slog.w(TAG, msg);
3608            throw new SecurityException(msg);
3609        }
3610        if (session == null || interactor == null) {
3611            throw new NullPointerException("null session or interactor");
3612        }
3613        userId = handleIncomingUser(callingPid, callingUid, userId,
3614                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3615        // TODO: Switch to user app stacks here.
3616        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3617                resolvedType, session, interactor, null, null, 0, startFlags,
3618                profileFile, profileFd, null, null, options, userId, null);
3619    }
3620
3621    @Override
3622    public boolean startNextMatchingActivity(IBinder callingActivity,
3623            Intent intent, Bundle options) {
3624        // Refuse possible leaked file descriptors
3625        if (intent != null && intent.hasFileDescriptors() == true) {
3626            throw new IllegalArgumentException("File descriptors passed in Intent");
3627        }
3628
3629        synchronized (this) {
3630            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3631            if (r == null) {
3632                ActivityOptions.abort(options);
3633                return false;
3634            }
3635            if (r.app == null || r.app.thread == null) {
3636                // The caller is not running...  d'oh!
3637                ActivityOptions.abort(options);
3638                return false;
3639            }
3640            intent = new Intent(intent);
3641            // The caller is not allowed to change the data.
3642            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3643            // And we are resetting to find the next component...
3644            intent.setComponent(null);
3645
3646            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3647
3648            ActivityInfo aInfo = null;
3649            try {
3650                List<ResolveInfo> resolves =
3651                    AppGlobals.getPackageManager().queryIntentActivities(
3652                            intent, r.resolvedType,
3653                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3654                            UserHandle.getCallingUserId());
3655
3656                // Look for the original activity in the list...
3657                final int N = resolves != null ? resolves.size() : 0;
3658                for (int i=0; i<N; i++) {
3659                    ResolveInfo rInfo = resolves.get(i);
3660                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3661                            && rInfo.activityInfo.name.equals(r.info.name)) {
3662                        // We found the current one...  the next matching is
3663                        // after it.
3664                        i++;
3665                        if (i<N) {
3666                            aInfo = resolves.get(i).activityInfo;
3667                        }
3668                        if (debug) {
3669                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3670                                    + "/" + r.info.name);
3671                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3672                                    + "/" + aInfo.name);
3673                        }
3674                        break;
3675                    }
3676                }
3677            } catch (RemoteException e) {
3678            }
3679
3680            if (aInfo == null) {
3681                // Nobody who is next!
3682                ActivityOptions.abort(options);
3683                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3684                return false;
3685            }
3686
3687            intent.setComponent(new ComponentName(
3688                    aInfo.applicationInfo.packageName, aInfo.name));
3689            intent.setFlags(intent.getFlags()&~(
3690                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3691                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3692                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3693                    Intent.FLAG_ACTIVITY_NEW_TASK));
3694
3695            // Okay now we need to start the new activity, replacing the
3696            // currently running activity.  This is a little tricky because
3697            // we want to start the new one as if the current one is finished,
3698            // but not finish the current one first so that there is no flicker.
3699            // And thus...
3700            final boolean wasFinishing = r.finishing;
3701            r.finishing = true;
3702
3703            // Propagate reply information over to the new activity.
3704            final ActivityRecord resultTo = r.resultTo;
3705            final String resultWho = r.resultWho;
3706            final int requestCode = r.requestCode;
3707            r.resultTo = null;
3708            if (resultTo != null) {
3709                resultTo.removeResultsLocked(r, resultWho, requestCode);
3710            }
3711
3712            final long origId = Binder.clearCallingIdentity();
3713            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3714                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3715                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3716                    options, false, null, null);
3717            Binder.restoreCallingIdentity(origId);
3718
3719            r.finishing = wasFinishing;
3720            if (res != ActivityManager.START_SUCCESS) {
3721                return false;
3722            }
3723            return true;
3724        }
3725    }
3726
3727    @Override
3728    public final int startActivityFromRecents(int taskId, Bundle options) {
3729        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3730            String msg = "Permission Denial: startActivityFromRecents called without " +
3731                    START_TASKS_FROM_RECENTS;
3732            Slog.w(TAG, msg);
3733            throw new SecurityException(msg);
3734        }
3735        final int callingUid;
3736        final String callingPackage;
3737        final Intent intent;
3738        final int userId;
3739        synchronized (this) {
3740            final TaskRecord task = recentTaskForIdLocked(taskId);
3741            if (task == null) {
3742                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3743            }
3744            callingUid = task.mCallingUid;
3745            callingPackage = task.mCallingPackage;
3746            intent = task.intent;
3747            userId = task.userId;
3748        }
3749        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3750                options, userId, null);
3751    }
3752
3753    final int startActivityInPackage(int uid, String callingPackage,
3754            Intent intent, String resolvedType, IBinder resultTo,
3755            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3756                    IActivityContainer container) {
3757
3758        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3759                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3760
3761        // TODO: Switch to user app stacks here.
3762        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3763                null, null, resultTo, resultWho, requestCode, startFlags,
3764                null, null, null, null, options, userId, container);
3765        return ret;
3766    }
3767
3768    @Override
3769    public final int startActivities(IApplicationThread caller, String callingPackage,
3770            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3771            int userId) {
3772        enforceNotIsolatedCaller("startActivities");
3773        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3774                false, ALLOW_FULL_ONLY, "startActivity", null);
3775        // TODO: Switch to user app stacks here.
3776        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3777                resolvedTypes, resultTo, options, userId);
3778        return ret;
3779    }
3780
3781    final int startActivitiesInPackage(int uid, String callingPackage,
3782            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3783            Bundle options, int userId) {
3784
3785        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3786                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3787        // TODO: Switch to user app stacks here.
3788        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3789                resultTo, options, userId);
3790        return ret;
3791    }
3792
3793    //explicitly remove thd old information in mRecentTasks when removing existing user.
3794    private void removeRecentTasksForUserLocked(int userId) {
3795        if(userId <= 0) {
3796            Slog.i(TAG, "Can't remove recent task on user " + userId);
3797            return;
3798        }
3799
3800        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3801            TaskRecord tr = mRecentTasks.get(i);
3802            if (tr.userId == userId) {
3803                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3804                        + " when finishing user" + userId);
3805                tr.disposeThumbnail();
3806                mRecentTasks.remove(i);
3807            }
3808        }
3809
3810        // Remove tasks from persistent storage.
3811        mTaskPersister.wakeup(null, true);
3812    }
3813
3814    final void addRecentTaskLocked(TaskRecord task) {
3815        final int N = mRecentTasks.size();
3816        // Quick case: check if the top-most recent task is the same.
3817        if (N > 0 && mRecentTasks.get(0) == task) {
3818            return;
3819        }
3820        // Another quick case: never add voice sessions.
3821        if (task.voiceSession != null) {
3822            return;
3823        }
3824
3825        trimRecentsForTask(task, true);
3826
3827        if (N >= MAX_RECENT_TASKS) {
3828            final TaskRecord tr = mRecentTasks.remove(N - 1);
3829            tr.disposeThumbnail();
3830            tr.closeRecentsChain();
3831        }
3832        mRecentTasks.add(0, task);
3833    }
3834
3835    /**
3836     * If needed, remove oldest existing entries in recents that are for the same kind
3837     * of task as the given one.
3838     */
3839    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
3840        int N = mRecentTasks.size();
3841        final Intent intent = task.intent;
3842        final boolean document = intent != null && intent.isDocument();
3843
3844        int maxRecents = task.maxRecents - 1;
3845        for (int i=0; i<N; i++) {
3846            final TaskRecord tr = mRecentTasks.get(i);
3847            if (task != tr) {
3848                if (task.userId != tr.userId) {
3849                    continue;
3850                }
3851                if (i > MAX_RECENT_BITMAPS) {
3852                    tr.freeLastThumbnail();
3853                }
3854                final Intent trIntent = tr.intent;
3855                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3856                    (intent == null || !intent.filterEquals(trIntent))) {
3857                    continue;
3858                }
3859                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3860                if (document && trIsDocument) {
3861                    // These are the same document activity (not necessarily the same doc).
3862                    if (maxRecents > 0) {
3863                        --maxRecents;
3864                        continue;
3865                    }
3866                    // Hit the maximum number of documents for this task. Fall through
3867                    // and remove this document from recents.
3868                } else if (document || trIsDocument) {
3869                    // Only one of these is a document. Not the droid we're looking for.
3870                    continue;
3871                }
3872            }
3873
3874            if (!doTrim) {
3875                // If the caller is not actually asking for a trim, just tell them we reached
3876                // a point where the trim would happen.
3877                return i;
3878            }
3879
3880            // Either task and tr are the same or, their affinities match or their intents match
3881            // and neither of them is a document, or they are documents using the same activity
3882            // and their maxRecents has been reached.
3883            tr.disposeThumbnail();
3884            mRecentTasks.remove(i);
3885            if (task != tr) {
3886                tr.closeRecentsChain();
3887            }
3888            i--;
3889            N--;
3890            if (task.intent == null) {
3891                // If the new recent task we are adding is not fully
3892                // specified, then replace it with the existing recent task.
3893                task = tr;
3894            }
3895            notifyTaskPersisterLocked(tr, false);
3896        }
3897
3898        return -1;
3899    }
3900
3901    @Override
3902    public void reportActivityFullyDrawn(IBinder token) {
3903        synchronized (this) {
3904            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3905            if (r == null) {
3906                return;
3907            }
3908            r.reportFullyDrawnLocked();
3909        }
3910    }
3911
3912    @Override
3913    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3914        synchronized (this) {
3915            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3916            if (r == null) {
3917                return;
3918            }
3919            final long origId = Binder.clearCallingIdentity();
3920            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3921            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3922                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3923            if (config != null) {
3924                r.frozenBeforeDestroy = true;
3925                if (!updateConfigurationLocked(config, r, false, false)) {
3926                    mStackSupervisor.resumeTopActivitiesLocked();
3927                }
3928            }
3929            Binder.restoreCallingIdentity(origId);
3930        }
3931    }
3932
3933    @Override
3934    public int getRequestedOrientation(IBinder token) {
3935        synchronized (this) {
3936            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3937            if (r == null) {
3938                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3939            }
3940            return mWindowManager.getAppOrientation(r.appToken);
3941        }
3942    }
3943
3944    /**
3945     * This is the internal entry point for handling Activity.finish().
3946     *
3947     * @param token The Binder token referencing the Activity we want to finish.
3948     * @param resultCode Result code, if any, from this Activity.
3949     * @param resultData Result data (Intent), if any, from this Activity.
3950     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3951     *            the root Activity in the task.
3952     *
3953     * @return Returns true if the activity successfully finished, or false if it is still running.
3954     */
3955    @Override
3956    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3957            boolean finishTask) {
3958        // Refuse possible leaked file descriptors
3959        if (resultData != null && resultData.hasFileDescriptors() == true) {
3960            throw new IllegalArgumentException("File descriptors passed in Intent");
3961        }
3962
3963        synchronized(this) {
3964            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3965            if (r == null) {
3966                return true;
3967            }
3968            // Keep track of the root activity of the task before we finish it
3969            TaskRecord tr = r.task;
3970            ActivityRecord rootR = tr.getRootActivity();
3971            // Do not allow task to finish in Lock Task mode.
3972            if (tr == mStackSupervisor.mLockTaskModeTask) {
3973                if (rootR == r) {
3974                    mStackSupervisor.showLockTaskToast();
3975                    return false;
3976                }
3977            }
3978            if (mController != null) {
3979                // Find the first activity that is not finishing.
3980                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3981                if (next != null) {
3982                    // ask watcher if this is allowed
3983                    boolean resumeOK = true;
3984                    try {
3985                        resumeOK = mController.activityResuming(next.packageName);
3986                    } catch (RemoteException e) {
3987                        mController = null;
3988                        Watchdog.getInstance().setActivityController(null);
3989                    }
3990
3991                    if (!resumeOK) {
3992                        return false;
3993                    }
3994                }
3995            }
3996            final long origId = Binder.clearCallingIdentity();
3997            try {
3998                boolean res;
3999                if (finishTask && r == rootR) {
4000                    // If requested, remove the task that is associated to this activity only if it
4001                    // was the root activity in the task.  The result code and data is ignored because
4002                    // we don't support returning them across task boundaries.
4003                    res = removeTaskByIdLocked(tr.taskId, 0);
4004                } else {
4005                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4006                            resultData, "app-request", true);
4007                }
4008                return res;
4009            } finally {
4010                Binder.restoreCallingIdentity(origId);
4011            }
4012        }
4013    }
4014
4015    @Override
4016    public final void finishHeavyWeightApp() {
4017        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4018                != PackageManager.PERMISSION_GRANTED) {
4019            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4020                    + Binder.getCallingPid()
4021                    + ", uid=" + Binder.getCallingUid()
4022                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4023            Slog.w(TAG, msg);
4024            throw new SecurityException(msg);
4025        }
4026
4027        synchronized(this) {
4028            if (mHeavyWeightProcess == null) {
4029                return;
4030            }
4031
4032            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4033                    mHeavyWeightProcess.activities);
4034            for (int i=0; i<activities.size(); i++) {
4035                ActivityRecord r = activities.get(i);
4036                if (!r.finishing) {
4037                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4038                            null, "finish-heavy", true);
4039                }
4040            }
4041
4042            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4043                    mHeavyWeightProcess.userId, 0));
4044            mHeavyWeightProcess = null;
4045        }
4046    }
4047
4048    @Override
4049    public void crashApplication(int uid, int initialPid, String packageName,
4050            String message) {
4051        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4052                != PackageManager.PERMISSION_GRANTED) {
4053            String msg = "Permission Denial: crashApplication() from pid="
4054                    + Binder.getCallingPid()
4055                    + ", uid=" + Binder.getCallingUid()
4056                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4057            Slog.w(TAG, msg);
4058            throw new SecurityException(msg);
4059        }
4060
4061        synchronized(this) {
4062            ProcessRecord proc = null;
4063
4064            // Figure out which process to kill.  We don't trust that initialPid
4065            // still has any relation to current pids, so must scan through the
4066            // list.
4067            synchronized (mPidsSelfLocked) {
4068                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4069                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4070                    if (p.uid != uid) {
4071                        continue;
4072                    }
4073                    if (p.pid == initialPid) {
4074                        proc = p;
4075                        break;
4076                    }
4077                    if (p.pkgList.containsKey(packageName)) {
4078                        proc = p;
4079                    }
4080                }
4081            }
4082
4083            if (proc == null) {
4084                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4085                        + " initialPid=" + initialPid
4086                        + " packageName=" + packageName);
4087                return;
4088            }
4089
4090            if (proc.thread != null) {
4091                if (proc.pid == Process.myPid()) {
4092                    Log.w(TAG, "crashApplication: trying to crash self!");
4093                    return;
4094                }
4095                long ident = Binder.clearCallingIdentity();
4096                try {
4097                    proc.thread.scheduleCrash(message);
4098                } catch (RemoteException e) {
4099                }
4100                Binder.restoreCallingIdentity(ident);
4101            }
4102        }
4103    }
4104
4105    @Override
4106    public final void finishSubActivity(IBinder token, String resultWho,
4107            int requestCode) {
4108        synchronized(this) {
4109            final long origId = Binder.clearCallingIdentity();
4110            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4111            if (r != null) {
4112                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4113            }
4114            Binder.restoreCallingIdentity(origId);
4115        }
4116    }
4117
4118    @Override
4119    public boolean finishActivityAffinity(IBinder token) {
4120        synchronized(this) {
4121            final long origId = Binder.clearCallingIdentity();
4122            try {
4123                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4124
4125                ActivityRecord rootR = r.task.getRootActivity();
4126                // Do not allow task to finish in Lock Task mode.
4127                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4128                    if (rootR == r) {
4129                        mStackSupervisor.showLockTaskToast();
4130                        return false;
4131                    }
4132                }
4133                boolean res = false;
4134                if (r != null) {
4135                    res = r.task.stack.finishActivityAffinityLocked(r);
4136                }
4137                return res;
4138            } finally {
4139                Binder.restoreCallingIdentity(origId);
4140            }
4141        }
4142    }
4143
4144    @Override
4145    public void finishVoiceTask(IVoiceInteractionSession session) {
4146        synchronized(this) {
4147            final long origId = Binder.clearCallingIdentity();
4148            try {
4149                mStackSupervisor.finishVoiceTask(session);
4150            } finally {
4151                Binder.restoreCallingIdentity(origId);
4152            }
4153        }
4154
4155    }
4156
4157    @Override
4158    public boolean willActivityBeVisible(IBinder token) {
4159        synchronized(this) {
4160            ActivityStack stack = ActivityRecord.getStackLocked(token);
4161            if (stack != null) {
4162                return stack.willActivityBeVisibleLocked(token);
4163            }
4164            return false;
4165        }
4166    }
4167
4168    @Override
4169    public void overridePendingTransition(IBinder token, String packageName,
4170            int enterAnim, int exitAnim) {
4171        synchronized(this) {
4172            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4173            if (self == null) {
4174                return;
4175            }
4176
4177            final long origId = Binder.clearCallingIdentity();
4178
4179            if (self.state == ActivityState.RESUMED
4180                    || self.state == ActivityState.PAUSING) {
4181                mWindowManager.overridePendingAppTransition(packageName,
4182                        enterAnim, exitAnim, null);
4183            }
4184
4185            Binder.restoreCallingIdentity(origId);
4186        }
4187    }
4188
4189    /**
4190     * Main function for removing an existing process from the activity manager
4191     * as a result of that process going away.  Clears out all connections
4192     * to the process.
4193     */
4194    private final void handleAppDiedLocked(ProcessRecord app,
4195            boolean restarting, boolean allowRestart) {
4196        int pid = app.pid;
4197        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4198        if (!restarting) {
4199            removeLruProcessLocked(app);
4200            if (pid > 0) {
4201                ProcessList.remove(pid);
4202            }
4203        }
4204
4205        if (mProfileProc == app) {
4206            clearProfilerLocked();
4207        }
4208
4209        // Remove this application's activities from active lists.
4210        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4211
4212        app.activities.clear();
4213
4214        if (app.instrumentationClass != null) {
4215            Slog.w(TAG, "Crash of app " + app.processName
4216                  + " running instrumentation " + app.instrumentationClass);
4217            Bundle info = new Bundle();
4218            info.putString("shortMsg", "Process crashed.");
4219            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4220        }
4221
4222        if (!restarting) {
4223            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4224                // If there was nothing to resume, and we are not already
4225                // restarting this process, but there is a visible activity that
4226                // is hosted by the process...  then make sure all visible
4227                // activities are running, taking care of restarting this
4228                // process.
4229                if (hasVisibleActivities) {
4230                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4231                }
4232            }
4233        }
4234    }
4235
4236    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4237        IBinder threadBinder = thread.asBinder();
4238        // Find the application record.
4239        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4240            ProcessRecord rec = mLruProcesses.get(i);
4241            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4242                return i;
4243            }
4244        }
4245        return -1;
4246    }
4247
4248    final ProcessRecord getRecordForAppLocked(
4249            IApplicationThread thread) {
4250        if (thread == null) {
4251            return null;
4252        }
4253
4254        int appIndex = getLRURecordIndexForAppLocked(thread);
4255        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4256    }
4257
4258    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4259        // If there are no longer any background processes running,
4260        // and the app that died was not running instrumentation,
4261        // then tell everyone we are now low on memory.
4262        boolean haveBg = false;
4263        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4264            ProcessRecord rec = mLruProcesses.get(i);
4265            if (rec.thread != null
4266                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4267                haveBg = true;
4268                break;
4269            }
4270        }
4271
4272        if (!haveBg) {
4273            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4274            if (doReport) {
4275                long now = SystemClock.uptimeMillis();
4276                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4277                    doReport = false;
4278                } else {
4279                    mLastMemUsageReportTime = now;
4280                }
4281            }
4282            final ArrayList<ProcessMemInfo> memInfos
4283                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4284            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4285            long now = SystemClock.uptimeMillis();
4286            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4287                ProcessRecord rec = mLruProcesses.get(i);
4288                if (rec == dyingProc || rec.thread == null) {
4289                    continue;
4290                }
4291                if (doReport) {
4292                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4293                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4294                }
4295                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4296                    // The low memory report is overriding any current
4297                    // state for a GC request.  Make sure to do
4298                    // heavy/important/visible/foreground processes first.
4299                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4300                        rec.lastRequestedGc = 0;
4301                    } else {
4302                        rec.lastRequestedGc = rec.lastLowMemory;
4303                    }
4304                    rec.reportLowMemory = true;
4305                    rec.lastLowMemory = now;
4306                    mProcessesToGc.remove(rec);
4307                    addProcessToGcListLocked(rec);
4308                }
4309            }
4310            if (doReport) {
4311                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4312                mHandler.sendMessage(msg);
4313            }
4314            scheduleAppGcsLocked();
4315        }
4316    }
4317
4318    final void appDiedLocked(ProcessRecord app) {
4319       appDiedLocked(app, app.pid, app.thread);
4320    }
4321
4322    final void appDiedLocked(ProcessRecord app, int pid,
4323            IApplicationThread thread) {
4324
4325        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4326        synchronized (stats) {
4327            stats.noteProcessDiedLocked(app.info.uid, pid);
4328        }
4329
4330        Process.killProcessGroup(app.info.uid, pid);
4331
4332        // Clean up already done if the process has been re-started.
4333        if (app.pid == pid && app.thread != null &&
4334                app.thread.asBinder() == thread.asBinder()) {
4335            boolean doLowMem = app.instrumentationClass == null;
4336            boolean doOomAdj = doLowMem;
4337            if (!app.killedByAm) {
4338                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4339                        + ") has died.");
4340                mAllowLowerMemLevel = true;
4341            } else {
4342                // Note that we always want to do oom adj to update our state with the
4343                // new number of procs.
4344                mAllowLowerMemLevel = false;
4345                doLowMem = false;
4346            }
4347            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4348            if (DEBUG_CLEANUP) Slog.v(
4349                TAG, "Dying app: " + app + ", pid: " + pid
4350                + ", thread: " + thread.asBinder());
4351            handleAppDiedLocked(app, false, true);
4352
4353            if (doOomAdj) {
4354                updateOomAdjLocked();
4355            }
4356            if (doLowMem) {
4357                doLowMemReportIfNeededLocked(app);
4358            }
4359        } else if (app.pid != pid) {
4360            // A new process has already been started.
4361            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4362                    + ") has died and restarted (pid " + app.pid + ").");
4363            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4364        } else if (DEBUG_PROCESSES) {
4365            Slog.d(TAG, "Received spurious death notification for thread "
4366                    + thread.asBinder());
4367        }
4368    }
4369
4370    /**
4371     * If a stack trace dump file is configured, dump process stack traces.
4372     * @param clearTraces causes the dump file to be erased prior to the new
4373     *    traces being written, if true; when false, the new traces will be
4374     *    appended to any existing file content.
4375     * @param firstPids of dalvik VM processes to dump stack traces for first
4376     * @param lastPids of dalvik VM processes to dump stack traces for last
4377     * @param nativeProcs optional list of native process names to dump stack crawls
4378     * @return file containing stack traces, or null if no dump file is configured
4379     */
4380    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4381            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4382        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4383        if (tracesPath == null || tracesPath.length() == 0) {
4384            return null;
4385        }
4386
4387        File tracesFile = new File(tracesPath);
4388        try {
4389            File tracesDir = tracesFile.getParentFile();
4390            if (!tracesDir.exists()) {
4391                tracesFile.mkdirs();
4392                if (!SELinux.restorecon(tracesDir)) {
4393                    return null;
4394                }
4395            }
4396            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4397
4398            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4399            tracesFile.createNewFile();
4400            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4401        } catch (IOException e) {
4402            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4403            return null;
4404        }
4405
4406        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4407        return tracesFile;
4408    }
4409
4410    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4411            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4412        // Use a FileObserver to detect when traces finish writing.
4413        // The order of traces is considered important to maintain for legibility.
4414        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4415            @Override
4416            public synchronized void onEvent(int event, String path) { notify(); }
4417        };
4418
4419        try {
4420            observer.startWatching();
4421
4422            // First collect all of the stacks of the most important pids.
4423            if (firstPids != null) {
4424                try {
4425                    int num = firstPids.size();
4426                    for (int i = 0; i < num; i++) {
4427                        synchronized (observer) {
4428                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4429                            observer.wait(200);  // Wait for write-close, give up after 200msec
4430                        }
4431                    }
4432                } catch (InterruptedException e) {
4433                    Log.wtf(TAG, e);
4434                }
4435            }
4436
4437            // Next collect the stacks of the native pids
4438            if (nativeProcs != null) {
4439                int[] pids = Process.getPidsForCommands(nativeProcs);
4440                if (pids != null) {
4441                    for (int pid : pids) {
4442                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4443                    }
4444                }
4445            }
4446
4447            // Lastly, measure CPU usage.
4448            if (processCpuTracker != null) {
4449                processCpuTracker.init();
4450                System.gc();
4451                processCpuTracker.update();
4452                try {
4453                    synchronized (processCpuTracker) {
4454                        processCpuTracker.wait(500); // measure over 1/2 second.
4455                    }
4456                } catch (InterruptedException e) {
4457                }
4458                processCpuTracker.update();
4459
4460                // We'll take the stack crawls of just the top apps using CPU.
4461                final int N = processCpuTracker.countWorkingStats();
4462                int numProcs = 0;
4463                for (int i=0; i<N && numProcs<5; i++) {
4464                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4465                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4466                        numProcs++;
4467                        try {
4468                            synchronized (observer) {
4469                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4470                                observer.wait(200);  // Wait for write-close, give up after 200msec
4471                            }
4472                        } catch (InterruptedException e) {
4473                            Log.wtf(TAG, e);
4474                        }
4475
4476                    }
4477                }
4478            }
4479        } finally {
4480            observer.stopWatching();
4481        }
4482    }
4483
4484    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4485        if (true || IS_USER_BUILD) {
4486            return;
4487        }
4488        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4489        if (tracesPath == null || tracesPath.length() == 0) {
4490            return;
4491        }
4492
4493        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4494        StrictMode.allowThreadDiskWrites();
4495        try {
4496            final File tracesFile = new File(tracesPath);
4497            final File tracesDir = tracesFile.getParentFile();
4498            final File tracesTmp = new File(tracesDir, "__tmp__");
4499            try {
4500                if (!tracesDir.exists()) {
4501                    tracesFile.mkdirs();
4502                    if (!SELinux.restorecon(tracesDir.getPath())) {
4503                        return;
4504                    }
4505                }
4506                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4507
4508                if (tracesFile.exists()) {
4509                    tracesTmp.delete();
4510                    tracesFile.renameTo(tracesTmp);
4511                }
4512                StringBuilder sb = new StringBuilder();
4513                Time tobj = new Time();
4514                tobj.set(System.currentTimeMillis());
4515                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4516                sb.append(": ");
4517                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4518                sb.append(" since ");
4519                sb.append(msg);
4520                FileOutputStream fos = new FileOutputStream(tracesFile);
4521                fos.write(sb.toString().getBytes());
4522                if (app == null) {
4523                    fos.write("\n*** No application process!".getBytes());
4524                }
4525                fos.close();
4526                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4527            } catch (IOException e) {
4528                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4529                return;
4530            }
4531
4532            if (app != null) {
4533                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4534                firstPids.add(app.pid);
4535                dumpStackTraces(tracesPath, firstPids, null, null, null);
4536            }
4537
4538            File lastTracesFile = null;
4539            File curTracesFile = null;
4540            for (int i=9; i>=0; i--) {
4541                String name = String.format(Locale.US, "slow%02d.txt", i);
4542                curTracesFile = new File(tracesDir, name);
4543                if (curTracesFile.exists()) {
4544                    if (lastTracesFile != null) {
4545                        curTracesFile.renameTo(lastTracesFile);
4546                    } else {
4547                        curTracesFile.delete();
4548                    }
4549                }
4550                lastTracesFile = curTracesFile;
4551            }
4552            tracesFile.renameTo(curTracesFile);
4553            if (tracesTmp.exists()) {
4554                tracesTmp.renameTo(tracesFile);
4555            }
4556        } finally {
4557            StrictMode.setThreadPolicy(oldPolicy);
4558        }
4559    }
4560
4561    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4562            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4563        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4564        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4565
4566        if (mController != null) {
4567            try {
4568                // 0 == continue, -1 = kill process immediately
4569                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4570                if (res < 0 && app.pid != MY_PID) {
4571                    Process.killProcess(app.pid);
4572                    Process.killProcessGroup(app.info.uid, app.pid);
4573                }
4574            } catch (RemoteException e) {
4575                mController = null;
4576                Watchdog.getInstance().setActivityController(null);
4577            }
4578        }
4579
4580        long anrTime = SystemClock.uptimeMillis();
4581        if (MONITOR_CPU_USAGE) {
4582            updateCpuStatsNow();
4583        }
4584
4585        synchronized (this) {
4586            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4587            if (mShuttingDown) {
4588                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4589                return;
4590            } else if (app.notResponding) {
4591                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4592                return;
4593            } else if (app.crashing) {
4594                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4595                return;
4596            }
4597
4598            // In case we come through here for the same app before completing
4599            // this one, mark as anring now so we will bail out.
4600            app.notResponding = true;
4601
4602            // Log the ANR to the event log.
4603            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4604                    app.processName, app.info.flags, annotation);
4605
4606            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4607            firstPids.add(app.pid);
4608
4609            int parentPid = app.pid;
4610            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4611            if (parentPid != app.pid) firstPids.add(parentPid);
4612
4613            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4614
4615            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4616                ProcessRecord r = mLruProcesses.get(i);
4617                if (r != null && r.thread != null) {
4618                    int pid = r.pid;
4619                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4620                        if (r.persistent) {
4621                            firstPids.add(pid);
4622                        } else {
4623                            lastPids.put(pid, Boolean.TRUE);
4624                        }
4625                    }
4626                }
4627            }
4628        }
4629
4630        // Log the ANR to the main log.
4631        StringBuilder info = new StringBuilder();
4632        info.setLength(0);
4633        info.append("ANR in ").append(app.processName);
4634        if (activity != null && activity.shortComponentName != null) {
4635            info.append(" (").append(activity.shortComponentName).append(")");
4636        }
4637        info.append("\n");
4638        info.append("PID: ").append(app.pid).append("\n");
4639        if (annotation != null) {
4640            info.append("Reason: ").append(annotation).append("\n");
4641        }
4642        if (parent != null && parent != activity) {
4643            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4644        }
4645
4646        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4647
4648        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4649                NATIVE_STACKS_OF_INTEREST);
4650
4651        String cpuInfo = null;
4652        if (MONITOR_CPU_USAGE) {
4653            updateCpuStatsNow();
4654            synchronized (mProcessCpuThread) {
4655                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4656            }
4657            info.append(processCpuTracker.printCurrentLoad());
4658            info.append(cpuInfo);
4659        }
4660
4661        info.append(processCpuTracker.printCurrentState(anrTime));
4662
4663        Slog.e(TAG, info.toString());
4664        if (tracesFile == null) {
4665            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4666            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4667        }
4668
4669        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4670                cpuInfo, tracesFile, null);
4671
4672        if (mController != null) {
4673            try {
4674                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4675                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4676                if (res != 0) {
4677                    if (res < 0 && app.pid != MY_PID) {
4678                        Process.killProcess(app.pid);
4679                        Process.killProcessGroup(app.info.uid, app.pid);
4680                    } else {
4681                        synchronized (this) {
4682                            mServices.scheduleServiceTimeoutLocked(app);
4683                        }
4684                    }
4685                    return;
4686                }
4687            } catch (RemoteException e) {
4688                mController = null;
4689                Watchdog.getInstance().setActivityController(null);
4690            }
4691        }
4692
4693        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4694        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4695                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4696
4697        synchronized (this) {
4698            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4699                killUnneededProcessLocked(app, "background ANR");
4700                return;
4701            }
4702
4703            // Set the app's notResponding state, and look up the errorReportReceiver
4704            makeAppNotRespondingLocked(app,
4705                    activity != null ? activity.shortComponentName : null,
4706                    annotation != null ? "ANR " + annotation : "ANR",
4707                    info.toString());
4708
4709            // Bring up the infamous App Not Responding dialog
4710            Message msg = Message.obtain();
4711            HashMap<String, Object> map = new HashMap<String, Object>();
4712            msg.what = SHOW_NOT_RESPONDING_MSG;
4713            msg.obj = map;
4714            msg.arg1 = aboveSystem ? 1 : 0;
4715            map.put("app", app);
4716            if (activity != null) {
4717                map.put("activity", activity);
4718            }
4719
4720            mHandler.sendMessage(msg);
4721        }
4722    }
4723
4724    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4725        if (!mLaunchWarningShown) {
4726            mLaunchWarningShown = true;
4727            mHandler.post(new Runnable() {
4728                @Override
4729                public void run() {
4730                    synchronized (ActivityManagerService.this) {
4731                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4732                        d.show();
4733                        mHandler.postDelayed(new Runnable() {
4734                            @Override
4735                            public void run() {
4736                                synchronized (ActivityManagerService.this) {
4737                                    d.dismiss();
4738                                    mLaunchWarningShown = false;
4739                                }
4740                            }
4741                        }, 4000);
4742                    }
4743                }
4744            });
4745        }
4746    }
4747
4748    @Override
4749    public boolean clearApplicationUserData(final String packageName,
4750            final IPackageDataObserver observer, int userId) {
4751        enforceNotIsolatedCaller("clearApplicationUserData");
4752        int uid = Binder.getCallingUid();
4753        int pid = Binder.getCallingPid();
4754        userId = handleIncomingUser(pid, uid,
4755                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4756        long callingId = Binder.clearCallingIdentity();
4757        try {
4758            IPackageManager pm = AppGlobals.getPackageManager();
4759            int pkgUid = -1;
4760            synchronized(this) {
4761                try {
4762                    pkgUid = pm.getPackageUid(packageName, userId);
4763                } catch (RemoteException e) {
4764                }
4765                if (pkgUid == -1) {
4766                    Slog.w(TAG, "Invalid packageName: " + packageName);
4767                    if (observer != null) {
4768                        try {
4769                            observer.onRemoveCompleted(packageName, false);
4770                        } catch (RemoteException e) {
4771                            Slog.i(TAG, "Observer no longer exists.");
4772                        }
4773                    }
4774                    return false;
4775                }
4776                if (uid == pkgUid || checkComponentPermission(
4777                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4778                        pid, uid, -1, true)
4779                        == PackageManager.PERMISSION_GRANTED) {
4780                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4781                } else {
4782                    throw new SecurityException("PID " + pid + " does not have permission "
4783                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4784                                    + " of package " + packageName);
4785                }
4786
4787                // Remove all tasks match the cleared application package and user
4788                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4789                    final TaskRecord tr = mRecentTasks.get(i);
4790                    final String taskPackageName =
4791                            tr.getBaseIntent().getComponent().getPackageName();
4792                    if (tr.userId != userId) continue;
4793                    if (!taskPackageName.equals(packageName)) continue;
4794                    removeTaskByIdLocked(tr.taskId, 0);
4795                }
4796            }
4797
4798            try {
4799                // Clear application user data
4800                pm.clearApplicationUserData(packageName, observer, userId);
4801
4802                synchronized(this) {
4803                    // Remove all permissions granted from/to this package
4804                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4805                }
4806
4807                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4808                        Uri.fromParts("package", packageName, null));
4809                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4810                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4811                        null, null, 0, null, null, null, false, false, userId);
4812            } catch (RemoteException e) {
4813            }
4814        } finally {
4815            Binder.restoreCallingIdentity(callingId);
4816        }
4817        return true;
4818    }
4819
4820    @Override
4821    public void killBackgroundProcesses(final String packageName, int userId) {
4822        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4823                != PackageManager.PERMISSION_GRANTED &&
4824                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4825                        != PackageManager.PERMISSION_GRANTED) {
4826            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4827                    + Binder.getCallingPid()
4828                    + ", uid=" + Binder.getCallingUid()
4829                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4830            Slog.w(TAG, msg);
4831            throw new SecurityException(msg);
4832        }
4833
4834        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4835                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4836        long callingId = Binder.clearCallingIdentity();
4837        try {
4838            IPackageManager pm = AppGlobals.getPackageManager();
4839            synchronized(this) {
4840                int appId = -1;
4841                try {
4842                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4843                } catch (RemoteException e) {
4844                }
4845                if (appId == -1) {
4846                    Slog.w(TAG, "Invalid packageName: " + packageName);
4847                    return;
4848                }
4849                killPackageProcessesLocked(packageName, appId, userId,
4850                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4851            }
4852        } finally {
4853            Binder.restoreCallingIdentity(callingId);
4854        }
4855    }
4856
4857    @Override
4858    public void killAllBackgroundProcesses() {
4859        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4860                != PackageManager.PERMISSION_GRANTED) {
4861            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4862                    + Binder.getCallingPid()
4863                    + ", uid=" + Binder.getCallingUid()
4864                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4865            Slog.w(TAG, msg);
4866            throw new SecurityException(msg);
4867        }
4868
4869        long callingId = Binder.clearCallingIdentity();
4870        try {
4871            synchronized(this) {
4872                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4873                final int NP = mProcessNames.getMap().size();
4874                for (int ip=0; ip<NP; ip++) {
4875                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4876                    final int NA = apps.size();
4877                    for (int ia=0; ia<NA; ia++) {
4878                        ProcessRecord app = apps.valueAt(ia);
4879                        if (app.persistent) {
4880                            // we don't kill persistent processes
4881                            continue;
4882                        }
4883                        if (app.removed) {
4884                            procs.add(app);
4885                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4886                            app.removed = true;
4887                            procs.add(app);
4888                        }
4889                    }
4890                }
4891
4892                int N = procs.size();
4893                for (int i=0; i<N; i++) {
4894                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4895                }
4896                mAllowLowerMemLevel = true;
4897                updateOomAdjLocked();
4898                doLowMemReportIfNeededLocked(null);
4899            }
4900        } finally {
4901            Binder.restoreCallingIdentity(callingId);
4902        }
4903    }
4904
4905    @Override
4906    public void forceStopPackage(final String packageName, int userId) {
4907        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4908                != PackageManager.PERMISSION_GRANTED) {
4909            String msg = "Permission Denial: forceStopPackage() from pid="
4910                    + Binder.getCallingPid()
4911                    + ", uid=" + Binder.getCallingUid()
4912                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4913            Slog.w(TAG, msg);
4914            throw new SecurityException(msg);
4915        }
4916        final int callingPid = Binder.getCallingPid();
4917        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4918                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4919        long callingId = Binder.clearCallingIdentity();
4920        try {
4921            IPackageManager pm = AppGlobals.getPackageManager();
4922            synchronized(this) {
4923                int[] users = userId == UserHandle.USER_ALL
4924                        ? getUsersLocked() : new int[] { userId };
4925                for (int user : users) {
4926                    int pkgUid = -1;
4927                    try {
4928                        pkgUid = pm.getPackageUid(packageName, user);
4929                    } catch (RemoteException e) {
4930                    }
4931                    if (pkgUid == -1) {
4932                        Slog.w(TAG, "Invalid packageName: " + packageName);
4933                        continue;
4934                    }
4935                    try {
4936                        pm.setPackageStoppedState(packageName, true, user);
4937                    } catch (RemoteException e) {
4938                    } catch (IllegalArgumentException e) {
4939                        Slog.w(TAG, "Failed trying to unstop package "
4940                                + packageName + ": " + e);
4941                    }
4942                    if (isUserRunningLocked(user, false)) {
4943                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4944                    }
4945                }
4946            }
4947        } finally {
4948            Binder.restoreCallingIdentity(callingId);
4949        }
4950    }
4951
4952    @Override
4953    public void addPackageDependency(String packageName) {
4954        synchronized (this) {
4955            int callingPid = Binder.getCallingPid();
4956            if (callingPid == Process.myPid()) {
4957                //  Yeah, um, no.
4958                Slog.w(TAG, "Can't addPackageDependency on system process");
4959                return;
4960            }
4961            ProcessRecord proc;
4962            synchronized (mPidsSelfLocked) {
4963                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4964            }
4965            if (proc != null) {
4966                if (proc.pkgDeps == null) {
4967                    proc.pkgDeps = new ArraySet<String>(1);
4968                }
4969                proc.pkgDeps.add(packageName);
4970            }
4971        }
4972    }
4973
4974    /*
4975     * The pkg name and app id have to be specified.
4976     */
4977    @Override
4978    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4979        if (pkg == null) {
4980            return;
4981        }
4982        // Make sure the uid is valid.
4983        if (appid < 0) {
4984            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4985            return;
4986        }
4987        int callerUid = Binder.getCallingUid();
4988        // Only the system server can kill an application
4989        if (callerUid == Process.SYSTEM_UID) {
4990            // Post an aysnc message to kill the application
4991            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4992            msg.arg1 = appid;
4993            msg.arg2 = 0;
4994            Bundle bundle = new Bundle();
4995            bundle.putString("pkg", pkg);
4996            bundle.putString("reason", reason);
4997            msg.obj = bundle;
4998            mHandler.sendMessage(msg);
4999        } else {
5000            throw new SecurityException(callerUid + " cannot kill pkg: " +
5001                    pkg);
5002        }
5003    }
5004
5005    @Override
5006    public void closeSystemDialogs(String reason) {
5007        enforceNotIsolatedCaller("closeSystemDialogs");
5008
5009        final int pid = Binder.getCallingPid();
5010        final int uid = Binder.getCallingUid();
5011        final long origId = Binder.clearCallingIdentity();
5012        try {
5013            synchronized (this) {
5014                // Only allow this from foreground processes, so that background
5015                // applications can't abuse it to prevent system UI from being shown.
5016                if (uid >= Process.FIRST_APPLICATION_UID) {
5017                    ProcessRecord proc;
5018                    synchronized (mPidsSelfLocked) {
5019                        proc = mPidsSelfLocked.get(pid);
5020                    }
5021                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5022                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5023                                + " from background process " + proc);
5024                        return;
5025                    }
5026                }
5027                closeSystemDialogsLocked(reason);
5028            }
5029        } finally {
5030            Binder.restoreCallingIdentity(origId);
5031        }
5032    }
5033
5034    void closeSystemDialogsLocked(String reason) {
5035        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5036        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5037                | Intent.FLAG_RECEIVER_FOREGROUND);
5038        if (reason != null) {
5039            intent.putExtra("reason", reason);
5040        }
5041        mWindowManager.closeSystemDialogs(reason);
5042
5043        mStackSupervisor.closeSystemDialogsLocked();
5044
5045        broadcastIntentLocked(null, null, intent, null,
5046                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5047                Process.SYSTEM_UID, UserHandle.USER_ALL);
5048    }
5049
5050    @Override
5051    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5052        enforceNotIsolatedCaller("getProcessMemoryInfo");
5053        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5054        for (int i=pids.length-1; i>=0; i--) {
5055            ProcessRecord proc;
5056            int oomAdj;
5057            synchronized (this) {
5058                synchronized (mPidsSelfLocked) {
5059                    proc = mPidsSelfLocked.get(pids[i]);
5060                    oomAdj = proc != null ? proc.setAdj : 0;
5061                }
5062            }
5063            infos[i] = new Debug.MemoryInfo();
5064            Debug.getMemoryInfo(pids[i], infos[i]);
5065            if (proc != null) {
5066                synchronized (this) {
5067                    if (proc.thread != null && proc.setAdj == oomAdj) {
5068                        // Record this for posterity if the process has been stable.
5069                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5070                                infos[i].getTotalUss(), false, proc.pkgList);
5071                    }
5072                }
5073            }
5074        }
5075        return infos;
5076    }
5077
5078    @Override
5079    public long[] getProcessPss(int[] pids) {
5080        enforceNotIsolatedCaller("getProcessPss");
5081        long[] pss = new long[pids.length];
5082        for (int i=pids.length-1; i>=0; i--) {
5083            ProcessRecord proc;
5084            int oomAdj;
5085            synchronized (this) {
5086                synchronized (mPidsSelfLocked) {
5087                    proc = mPidsSelfLocked.get(pids[i]);
5088                    oomAdj = proc != null ? proc.setAdj : 0;
5089                }
5090            }
5091            long[] tmpUss = new long[1];
5092            pss[i] = Debug.getPss(pids[i], tmpUss);
5093            if (proc != null) {
5094                synchronized (this) {
5095                    if (proc.thread != null && proc.setAdj == oomAdj) {
5096                        // Record this for posterity if the process has been stable.
5097                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5098                    }
5099                }
5100            }
5101        }
5102        return pss;
5103    }
5104
5105    @Override
5106    public void killApplicationProcess(String processName, int uid) {
5107        if (processName == null) {
5108            return;
5109        }
5110
5111        int callerUid = Binder.getCallingUid();
5112        // Only the system server can kill an application
5113        if (callerUid == Process.SYSTEM_UID) {
5114            synchronized (this) {
5115                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5116                if (app != null && app.thread != null) {
5117                    try {
5118                        app.thread.scheduleSuicide();
5119                    } catch (RemoteException e) {
5120                        // If the other end already died, then our work here is done.
5121                    }
5122                } else {
5123                    Slog.w(TAG, "Process/uid not found attempting kill of "
5124                            + processName + " / " + uid);
5125                }
5126            }
5127        } else {
5128            throw new SecurityException(callerUid + " cannot kill app process: " +
5129                    processName);
5130        }
5131    }
5132
5133    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5134        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5135                false, true, false, false, UserHandle.getUserId(uid), reason);
5136        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5137                Uri.fromParts("package", packageName, null));
5138        if (!mProcessesReady) {
5139            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5140                    | Intent.FLAG_RECEIVER_FOREGROUND);
5141        }
5142        intent.putExtra(Intent.EXTRA_UID, uid);
5143        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5144        broadcastIntentLocked(null, null, intent,
5145                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5146                false, false,
5147                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5148    }
5149
5150    private void forceStopUserLocked(int userId, String reason) {
5151        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5152        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5153        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5154                | Intent.FLAG_RECEIVER_FOREGROUND);
5155        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5156        broadcastIntentLocked(null, null, intent,
5157                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5158                false, false,
5159                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5160    }
5161
5162    private final boolean killPackageProcessesLocked(String packageName, int appId,
5163            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5164            boolean doit, boolean evenPersistent, String reason) {
5165        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5166
5167        // Remove all processes this package may have touched: all with the
5168        // same UID (except for the system or root user), and all whose name
5169        // matches the package name.
5170        final int NP = mProcessNames.getMap().size();
5171        for (int ip=0; ip<NP; ip++) {
5172            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5173            final int NA = apps.size();
5174            for (int ia=0; ia<NA; ia++) {
5175                ProcessRecord app = apps.valueAt(ia);
5176                if (app.persistent && !evenPersistent) {
5177                    // we don't kill persistent processes
5178                    continue;
5179                }
5180                if (app.removed) {
5181                    if (doit) {
5182                        procs.add(app);
5183                    }
5184                    continue;
5185                }
5186
5187                // Skip process if it doesn't meet our oom adj requirement.
5188                if (app.setAdj < minOomAdj) {
5189                    continue;
5190                }
5191
5192                // If no package is specified, we call all processes under the
5193                // give user id.
5194                if (packageName == null) {
5195                    if (app.userId != userId) {
5196                        continue;
5197                    }
5198                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5199                        continue;
5200                    }
5201                // Package has been specified, we want to hit all processes
5202                // that match it.  We need to qualify this by the processes
5203                // that are running under the specified app and user ID.
5204                } else {
5205                    final boolean isDep = app.pkgDeps != null
5206                            && app.pkgDeps.contains(packageName);
5207                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5208                        continue;
5209                    }
5210                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5211                        continue;
5212                    }
5213                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5214                        continue;
5215                    }
5216                }
5217
5218                // Process has passed all conditions, kill it!
5219                if (!doit) {
5220                    return true;
5221                }
5222                app.removed = true;
5223                procs.add(app);
5224            }
5225        }
5226
5227        int N = procs.size();
5228        for (int i=0; i<N; i++) {
5229            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5230        }
5231        updateOomAdjLocked();
5232        return N > 0;
5233    }
5234
5235    private final boolean forceStopPackageLocked(String name, int appId,
5236            boolean callerWillRestart, boolean purgeCache, boolean doit,
5237            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5238        int i;
5239        int N;
5240
5241        if (userId == UserHandle.USER_ALL && name == null) {
5242            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5243        }
5244
5245        if (appId < 0 && name != null) {
5246            try {
5247                appId = UserHandle.getAppId(
5248                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5249            } catch (RemoteException e) {
5250            }
5251        }
5252
5253        if (doit) {
5254            if (name != null) {
5255                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5256                        + " user=" + userId + ": " + reason);
5257            } else {
5258                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5259            }
5260
5261            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5262            for (int ip=pmap.size()-1; ip>=0; ip--) {
5263                SparseArray<Long> ba = pmap.valueAt(ip);
5264                for (i=ba.size()-1; i>=0; i--) {
5265                    boolean remove = false;
5266                    final int entUid = ba.keyAt(i);
5267                    if (name != null) {
5268                        if (userId == UserHandle.USER_ALL) {
5269                            if (UserHandle.getAppId(entUid) == appId) {
5270                                remove = true;
5271                            }
5272                        } else {
5273                            if (entUid == UserHandle.getUid(userId, appId)) {
5274                                remove = true;
5275                            }
5276                        }
5277                    } else if (UserHandle.getUserId(entUid) == userId) {
5278                        remove = true;
5279                    }
5280                    if (remove) {
5281                        ba.removeAt(i);
5282                    }
5283                }
5284                if (ba.size() == 0) {
5285                    pmap.removeAt(ip);
5286                }
5287            }
5288        }
5289
5290        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5291                -100, callerWillRestart, true, doit, evenPersistent,
5292                name == null ? ("stop user " + userId) : ("stop " + name));
5293
5294        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5295            if (!doit) {
5296                return true;
5297            }
5298            didSomething = true;
5299        }
5300
5301        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5302            if (!doit) {
5303                return true;
5304            }
5305            didSomething = true;
5306        }
5307
5308        if (name == null) {
5309            // Remove all sticky broadcasts from this user.
5310            mStickyBroadcasts.remove(userId);
5311        }
5312
5313        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5314        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5315                userId, providers)) {
5316            if (!doit) {
5317                return true;
5318            }
5319            didSomething = true;
5320        }
5321        N = providers.size();
5322        for (i=0; i<N; i++) {
5323            removeDyingProviderLocked(null, providers.get(i), true);
5324        }
5325
5326        // Remove transient permissions granted from/to this package/user
5327        removeUriPermissionsForPackageLocked(name, userId, false);
5328
5329        if (name == null || uninstalling) {
5330            // Remove pending intents.  For now we only do this when force
5331            // stopping users, because we have some problems when doing this
5332            // for packages -- app widgets are not currently cleaned up for
5333            // such packages, so they can be left with bad pending intents.
5334            if (mIntentSenderRecords.size() > 0) {
5335                Iterator<WeakReference<PendingIntentRecord>> it
5336                        = mIntentSenderRecords.values().iterator();
5337                while (it.hasNext()) {
5338                    WeakReference<PendingIntentRecord> wpir = it.next();
5339                    if (wpir == null) {
5340                        it.remove();
5341                        continue;
5342                    }
5343                    PendingIntentRecord pir = wpir.get();
5344                    if (pir == null) {
5345                        it.remove();
5346                        continue;
5347                    }
5348                    if (name == null) {
5349                        // Stopping user, remove all objects for the user.
5350                        if (pir.key.userId != userId) {
5351                            // Not the same user, skip it.
5352                            continue;
5353                        }
5354                    } else {
5355                        if (UserHandle.getAppId(pir.uid) != appId) {
5356                            // Different app id, skip it.
5357                            continue;
5358                        }
5359                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5360                            // Different user, skip it.
5361                            continue;
5362                        }
5363                        if (!pir.key.packageName.equals(name)) {
5364                            // Different package, skip it.
5365                            continue;
5366                        }
5367                    }
5368                    if (!doit) {
5369                        return true;
5370                    }
5371                    didSomething = true;
5372                    it.remove();
5373                    pir.canceled = true;
5374                    if (pir.key.activity != null) {
5375                        pir.key.activity.pendingResults.remove(pir.ref);
5376                    }
5377                }
5378            }
5379        }
5380
5381        if (doit) {
5382            if (purgeCache && name != null) {
5383                AttributeCache ac = AttributeCache.instance();
5384                if (ac != null) {
5385                    ac.removePackage(name);
5386                }
5387            }
5388            if (mBooted) {
5389                mStackSupervisor.resumeTopActivitiesLocked();
5390                mStackSupervisor.scheduleIdleLocked();
5391            }
5392        }
5393
5394        return didSomething;
5395    }
5396
5397    private final boolean removeProcessLocked(ProcessRecord app,
5398            boolean callerWillRestart, boolean allowRestart, String reason) {
5399        final String name = app.processName;
5400        final int uid = app.uid;
5401        if (DEBUG_PROCESSES) Slog.d(
5402            TAG, "Force removing proc " + app.toShortString() + " (" + name
5403            + "/" + uid + ")");
5404
5405        mProcessNames.remove(name, uid);
5406        mIsolatedProcesses.remove(app.uid);
5407        if (mHeavyWeightProcess == app) {
5408            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5409                    mHeavyWeightProcess.userId, 0));
5410            mHeavyWeightProcess = null;
5411        }
5412        boolean needRestart = false;
5413        if (app.pid > 0 && app.pid != MY_PID) {
5414            int pid = app.pid;
5415            synchronized (mPidsSelfLocked) {
5416                mPidsSelfLocked.remove(pid);
5417                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5418            }
5419            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5420            if (app.isolated) {
5421                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5422            }
5423            killUnneededProcessLocked(app, reason);
5424            Process.killProcessGroup(app.info.uid, app.pid);
5425            handleAppDiedLocked(app, true, allowRestart);
5426            removeLruProcessLocked(app);
5427
5428            if (app.persistent && !app.isolated) {
5429                if (!callerWillRestart) {
5430                    addAppLocked(app.info, false, null /* ABI override */);
5431                } else {
5432                    needRestart = true;
5433                }
5434            }
5435        } else {
5436            mRemovedProcesses.add(app);
5437        }
5438
5439        return needRestart;
5440    }
5441
5442    private final void processStartTimedOutLocked(ProcessRecord app) {
5443        final int pid = app.pid;
5444        boolean gone = false;
5445        synchronized (mPidsSelfLocked) {
5446            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5447            if (knownApp != null && knownApp.thread == null) {
5448                mPidsSelfLocked.remove(pid);
5449                gone = true;
5450            }
5451        }
5452
5453        if (gone) {
5454            Slog.w(TAG, "Process " + app + " failed to attach");
5455            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5456                    pid, app.uid, app.processName);
5457            mProcessNames.remove(app.processName, app.uid);
5458            mIsolatedProcesses.remove(app.uid);
5459            if (mHeavyWeightProcess == app) {
5460                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5461                        mHeavyWeightProcess.userId, 0));
5462                mHeavyWeightProcess = null;
5463            }
5464            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5465            if (app.isolated) {
5466                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5467            }
5468            // Take care of any launching providers waiting for this process.
5469            checkAppInLaunchingProvidersLocked(app, true);
5470            // Take care of any services that are waiting for the process.
5471            mServices.processStartTimedOutLocked(app);
5472            killUnneededProcessLocked(app, "start timeout");
5473            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5474                Slog.w(TAG, "Unattached app died before backup, skipping");
5475                try {
5476                    IBackupManager bm = IBackupManager.Stub.asInterface(
5477                            ServiceManager.getService(Context.BACKUP_SERVICE));
5478                    bm.agentDisconnected(app.info.packageName);
5479                } catch (RemoteException e) {
5480                    // Can't happen; the backup manager is local
5481                }
5482            }
5483            if (isPendingBroadcastProcessLocked(pid)) {
5484                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5485                skipPendingBroadcastLocked(pid);
5486            }
5487        } else {
5488            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5489        }
5490    }
5491
5492    private final boolean attachApplicationLocked(IApplicationThread thread,
5493            int pid) {
5494
5495        // Find the application record that is being attached...  either via
5496        // the pid if we are running in multiple processes, or just pull the
5497        // next app record if we are emulating process with anonymous threads.
5498        ProcessRecord app;
5499        if (pid != MY_PID && pid >= 0) {
5500            synchronized (mPidsSelfLocked) {
5501                app = mPidsSelfLocked.get(pid);
5502            }
5503        } else {
5504            app = null;
5505        }
5506
5507        if (app == null) {
5508            Slog.w(TAG, "No pending application record for pid " + pid
5509                    + " (IApplicationThread " + thread + "); dropping process");
5510            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5511            if (pid > 0 && pid != MY_PID) {
5512                Process.killProcessQuiet(pid);
5513                //TODO: Process.killProcessGroup(app.info.uid, pid);
5514            } else {
5515                try {
5516                    thread.scheduleExit();
5517                } catch (Exception e) {
5518                    // Ignore exceptions.
5519                }
5520            }
5521            return false;
5522        }
5523
5524        // If this application record is still attached to a previous
5525        // process, clean it up now.
5526        if (app.thread != null) {
5527            handleAppDiedLocked(app, true, true);
5528        }
5529
5530        // Tell the process all about itself.
5531
5532        if (localLOGV) Slog.v(
5533                TAG, "Binding process pid " + pid + " to record " + app);
5534
5535        final String processName = app.processName;
5536        try {
5537            AppDeathRecipient adr = new AppDeathRecipient(
5538                    app, pid, thread);
5539            thread.asBinder().linkToDeath(adr, 0);
5540            app.deathRecipient = adr;
5541        } catch (RemoteException e) {
5542            app.resetPackageList(mProcessStats);
5543            startProcessLocked(app, "link fail", processName);
5544            return false;
5545        }
5546
5547        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5548
5549        app.makeActive(thread, mProcessStats);
5550        app.curAdj = app.setAdj = -100;
5551        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5552        app.forcingToForeground = null;
5553        updateProcessForegroundLocked(app, false, false);
5554        app.hasShownUi = false;
5555        app.debugging = false;
5556        app.cached = false;
5557
5558        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5559
5560        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5561        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5562
5563        if (!normalMode) {
5564            Slog.i(TAG, "Launching preboot mode app: " + app);
5565        }
5566
5567        if (localLOGV) Slog.v(
5568            TAG, "New app record " + app
5569            + " thread=" + thread.asBinder() + " pid=" + pid);
5570        try {
5571            int testMode = IApplicationThread.DEBUG_OFF;
5572            if (mDebugApp != null && mDebugApp.equals(processName)) {
5573                testMode = mWaitForDebugger
5574                    ? IApplicationThread.DEBUG_WAIT
5575                    : IApplicationThread.DEBUG_ON;
5576                app.debugging = true;
5577                if (mDebugTransient) {
5578                    mDebugApp = mOrigDebugApp;
5579                    mWaitForDebugger = mOrigWaitForDebugger;
5580                }
5581            }
5582            String profileFile = app.instrumentationProfileFile;
5583            ParcelFileDescriptor profileFd = null;
5584            boolean profileAutoStop = false;
5585            if (mProfileApp != null && mProfileApp.equals(processName)) {
5586                mProfileProc = app;
5587                profileFile = mProfileFile;
5588                profileFd = mProfileFd;
5589                profileAutoStop = mAutoStopProfiler;
5590            }
5591            boolean enableOpenGlTrace = false;
5592            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5593                enableOpenGlTrace = true;
5594                mOpenGlTraceApp = null;
5595            }
5596
5597            // If the app is being launched for restore or full backup, set it up specially
5598            boolean isRestrictedBackupMode = false;
5599            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5600                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5601                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5602                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5603            }
5604
5605            ensurePackageDexOpt(app.instrumentationInfo != null
5606                    ? app.instrumentationInfo.packageName
5607                    : app.info.packageName);
5608            if (app.instrumentationClass != null) {
5609                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5610            }
5611            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5612                    + processName + " with config " + mConfiguration);
5613            ApplicationInfo appInfo = app.instrumentationInfo != null
5614                    ? app.instrumentationInfo : app.info;
5615            app.compat = compatibilityInfoForPackageLocked(appInfo);
5616            if (profileFd != null) {
5617                profileFd = profileFd.dup();
5618            }
5619            thread.bindApplication(processName, appInfo, providers,
5620                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5621                    app.instrumentationArguments, app.instrumentationWatcher,
5622                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5623                    isRestrictedBackupMode || !normalMode, app.persistent,
5624                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5625                    mCoreSettingsObserver.getCoreSettingsLocked());
5626            updateLruProcessLocked(app, false, null);
5627            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5628        } catch (Exception e) {
5629            // todo: Yikes!  What should we do?  For now we will try to
5630            // start another process, but that could easily get us in
5631            // an infinite loop of restarting processes...
5632            Slog.w(TAG, "Exception thrown during bind!", e);
5633
5634            app.resetPackageList(mProcessStats);
5635            app.unlinkDeathRecipient();
5636            startProcessLocked(app, "bind fail", processName);
5637            return false;
5638        }
5639
5640        // Remove this record from the list of starting applications.
5641        mPersistentStartingProcesses.remove(app);
5642        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5643                "Attach application locked removing on hold: " + app);
5644        mProcessesOnHold.remove(app);
5645
5646        boolean badApp = false;
5647        boolean didSomething = false;
5648
5649        // See if the top visible activity is waiting to run in this process...
5650        if (normalMode) {
5651            try {
5652                if (mStackSupervisor.attachApplicationLocked(app)) {
5653                    didSomething = true;
5654                }
5655            } catch (Exception e) {
5656                badApp = true;
5657            }
5658        }
5659
5660        // Find any services that should be running in this process...
5661        if (!badApp) {
5662            try {
5663                didSomething |= mServices.attachApplicationLocked(app, processName);
5664            } catch (Exception e) {
5665                badApp = true;
5666            }
5667        }
5668
5669        // Check if a next-broadcast receiver is in this process...
5670        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5671            try {
5672                didSomething |= sendPendingBroadcastsLocked(app);
5673            } catch (Exception e) {
5674                // If the app died trying to launch the receiver we declare it 'bad'
5675                badApp = true;
5676            }
5677        }
5678
5679        // Check whether the next backup agent is in this process...
5680        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5681            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5682            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5683            try {
5684                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5685                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5686                        mBackupTarget.backupMode);
5687            } catch (Exception e) {
5688                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5689                e.printStackTrace();
5690            }
5691        }
5692
5693        if (badApp) {
5694            // todo: Also need to kill application to deal with all
5695            // kinds of exceptions.
5696            handleAppDiedLocked(app, false, true);
5697            return false;
5698        }
5699
5700        if (!didSomething) {
5701            updateOomAdjLocked();
5702        }
5703
5704        return true;
5705    }
5706
5707    @Override
5708    public final void attachApplication(IApplicationThread thread) {
5709        synchronized (this) {
5710            int callingPid = Binder.getCallingPid();
5711            final long origId = Binder.clearCallingIdentity();
5712            attachApplicationLocked(thread, callingPid);
5713            Binder.restoreCallingIdentity(origId);
5714        }
5715    }
5716
5717    @Override
5718    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5719        final long origId = Binder.clearCallingIdentity();
5720        synchronized (this) {
5721            ActivityStack stack = ActivityRecord.getStackLocked(token);
5722            if (stack != null) {
5723                ActivityRecord r =
5724                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5725                if (stopProfiling) {
5726                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5727                        try {
5728                            mProfileFd.close();
5729                        } catch (IOException e) {
5730                        }
5731                        clearProfilerLocked();
5732                    }
5733                }
5734            }
5735        }
5736        Binder.restoreCallingIdentity(origId);
5737    }
5738
5739    void postEnableScreenAfterBootLocked() {
5740        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5741    }
5742
5743    void enableScreenAfterBoot() {
5744        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5745                SystemClock.uptimeMillis());
5746        mWindowManager.enableScreenAfterBoot();
5747
5748        synchronized (this) {
5749            updateEventDispatchingLocked();
5750        }
5751    }
5752
5753    @Override
5754    public void showBootMessage(final CharSequence msg, final boolean always) {
5755        enforceNotIsolatedCaller("showBootMessage");
5756        mWindowManager.showBootMessage(msg, always);
5757    }
5758
5759    @Override
5760    public void keyguardWaitingForActivityDrawn() {
5761        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5762        final long token = Binder.clearCallingIdentity();
5763        try {
5764            synchronized (this) {
5765                if (DEBUG_LOCKSCREEN) logLockScreen("");
5766                mWindowManager.keyguardWaitingForActivityDrawn();
5767            }
5768        } finally {
5769            Binder.restoreCallingIdentity(token);
5770        }
5771    }
5772
5773    final void finishBooting() {
5774        // Register receivers to handle package update events
5775        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5776
5777        // Let system services know.
5778        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5779
5780        synchronized (this) {
5781            // Ensure that any processes we had put on hold are now started
5782            // up.
5783            final int NP = mProcessesOnHold.size();
5784            if (NP > 0) {
5785                ArrayList<ProcessRecord> procs =
5786                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5787                for (int ip=0; ip<NP; ip++) {
5788                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5789                            + procs.get(ip));
5790                    startProcessLocked(procs.get(ip), "on-hold", null);
5791                }
5792            }
5793
5794            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5795                // Start looking for apps that are abusing wake locks.
5796                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5797                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5798                // Tell anyone interested that we are done booting!
5799                SystemProperties.set("sys.boot_completed", "1");
5800                SystemProperties.set("dev.bootcomplete", "1");
5801                for (int i=0; i<mStartedUsers.size(); i++) {
5802                    UserStartedState uss = mStartedUsers.valueAt(i);
5803                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5804                        uss.mState = UserStartedState.STATE_RUNNING;
5805                        final int userId = mStartedUsers.keyAt(i);
5806                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5807                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5808                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5809                        broadcastIntentLocked(null, null, intent, null,
5810                                new IIntentReceiver.Stub() {
5811                                    @Override
5812                                    public void performReceive(Intent intent, int resultCode,
5813                                            String data, Bundle extras, boolean ordered,
5814                                            boolean sticky, int sendingUser) {
5815                                        synchronized (ActivityManagerService.this) {
5816                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5817                                                    true, false);
5818                                        }
5819                                    }
5820                                },
5821                                0, null, null,
5822                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5823                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5824                                userId);
5825                    }
5826                }
5827                scheduleStartProfilesLocked();
5828            }
5829        }
5830    }
5831
5832    final void ensureBootCompleted() {
5833        boolean booting;
5834        boolean enableScreen;
5835        synchronized (this) {
5836            booting = mBooting;
5837            mBooting = false;
5838            enableScreen = !mBooted;
5839            mBooted = true;
5840        }
5841
5842        if (booting) {
5843            finishBooting();
5844        }
5845
5846        if (enableScreen) {
5847            enableScreenAfterBoot();
5848        }
5849    }
5850
5851    @Override
5852    public final void activityResumed(IBinder token) {
5853        final long origId = Binder.clearCallingIdentity();
5854        synchronized(this) {
5855            ActivityStack stack = ActivityRecord.getStackLocked(token);
5856            if (stack != null) {
5857                ActivityRecord.activityResumedLocked(token);
5858            }
5859        }
5860        Binder.restoreCallingIdentity(origId);
5861    }
5862
5863    @Override
5864    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5865        final long origId = Binder.clearCallingIdentity();
5866        synchronized(this) {
5867            ActivityStack stack = ActivityRecord.getStackLocked(token);
5868            if (stack != null) {
5869                stack.activityPausedLocked(token, false, persistentState);
5870            }
5871        }
5872        Binder.restoreCallingIdentity(origId);
5873    }
5874
5875    @Override
5876    public final void activityStopped(IBinder token, Bundle icicle,
5877            PersistableBundle persistentState, CharSequence description) {
5878        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5879
5880        // Refuse possible leaked file descriptors
5881        if (icicle != null && icicle.hasFileDescriptors()) {
5882            throw new IllegalArgumentException("File descriptors passed in Bundle");
5883        }
5884
5885        final long origId = Binder.clearCallingIdentity();
5886
5887        synchronized (this) {
5888            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5889            if (r != null) {
5890                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5891            }
5892        }
5893
5894        trimApplications();
5895
5896        Binder.restoreCallingIdentity(origId);
5897    }
5898
5899    @Override
5900    public final void activityDestroyed(IBinder token) {
5901        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5902        synchronized (this) {
5903            ActivityStack stack = ActivityRecord.getStackLocked(token);
5904            if (stack != null) {
5905                stack.activityDestroyedLocked(token);
5906            }
5907        }
5908    }
5909
5910    @Override
5911    public final void backgroundResourcesReleased(IBinder token) {
5912        final long origId = Binder.clearCallingIdentity();
5913        try {
5914            synchronized (this) {
5915                ActivityStack stack = ActivityRecord.getStackLocked(token);
5916                if (stack != null) {
5917                    stack.backgroundResourcesReleased(token);
5918                }
5919            }
5920        } finally {
5921            Binder.restoreCallingIdentity(origId);
5922        }
5923    }
5924
5925    @Override
5926    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5927        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5928    }
5929
5930    @Override
5931    public final void notifyEnterAnimationComplete(IBinder token) {
5932        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5933    }
5934
5935    @Override
5936    public String getCallingPackage(IBinder token) {
5937        synchronized (this) {
5938            ActivityRecord r = getCallingRecordLocked(token);
5939            return r != null ? r.info.packageName : null;
5940        }
5941    }
5942
5943    @Override
5944    public ComponentName getCallingActivity(IBinder token) {
5945        synchronized (this) {
5946            ActivityRecord r = getCallingRecordLocked(token);
5947            return r != null ? r.intent.getComponent() : null;
5948        }
5949    }
5950
5951    private ActivityRecord getCallingRecordLocked(IBinder token) {
5952        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5953        if (r == null) {
5954            return null;
5955        }
5956        return r.resultTo;
5957    }
5958
5959    @Override
5960    public ComponentName getActivityClassForToken(IBinder token) {
5961        synchronized(this) {
5962            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5963            if (r == null) {
5964                return null;
5965            }
5966            return r.intent.getComponent();
5967        }
5968    }
5969
5970    @Override
5971    public String getPackageForToken(IBinder token) {
5972        synchronized(this) {
5973            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5974            if (r == null) {
5975                return null;
5976            }
5977            return r.packageName;
5978        }
5979    }
5980
5981    @Override
5982    public IIntentSender getIntentSender(int type,
5983            String packageName, IBinder token, String resultWho,
5984            int requestCode, Intent[] intents, String[] resolvedTypes,
5985            int flags, Bundle options, int userId) {
5986        enforceNotIsolatedCaller("getIntentSender");
5987        // Refuse possible leaked file descriptors
5988        if (intents != null) {
5989            if (intents.length < 1) {
5990                throw new IllegalArgumentException("Intents array length must be >= 1");
5991            }
5992            for (int i=0; i<intents.length; i++) {
5993                Intent intent = intents[i];
5994                if (intent != null) {
5995                    if (intent.hasFileDescriptors()) {
5996                        throw new IllegalArgumentException("File descriptors passed in Intent");
5997                    }
5998                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5999                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6000                        throw new IllegalArgumentException(
6001                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6002                    }
6003                    intents[i] = new Intent(intent);
6004                }
6005            }
6006            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6007                throw new IllegalArgumentException(
6008                        "Intent array length does not match resolvedTypes length");
6009            }
6010        }
6011        if (options != null) {
6012            if (options.hasFileDescriptors()) {
6013                throw new IllegalArgumentException("File descriptors passed in options");
6014            }
6015        }
6016
6017        synchronized(this) {
6018            int callingUid = Binder.getCallingUid();
6019            int origUserId = userId;
6020            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6021                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6022                    ALLOW_NON_FULL, "getIntentSender", null);
6023            if (origUserId == UserHandle.USER_CURRENT) {
6024                // We don't want to evaluate this until the pending intent is
6025                // actually executed.  However, we do want to always do the
6026                // security checking for it above.
6027                userId = UserHandle.USER_CURRENT;
6028            }
6029            try {
6030                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6031                    int uid = AppGlobals.getPackageManager()
6032                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6033                    if (!UserHandle.isSameApp(callingUid, uid)) {
6034                        String msg = "Permission Denial: getIntentSender() from pid="
6035                            + Binder.getCallingPid()
6036                            + ", uid=" + Binder.getCallingUid()
6037                            + ", (need uid=" + uid + ")"
6038                            + " is not allowed to send as package " + packageName;
6039                        Slog.w(TAG, msg);
6040                        throw new SecurityException(msg);
6041                    }
6042                }
6043
6044                return getIntentSenderLocked(type, packageName, callingUid, userId,
6045                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6046
6047            } catch (RemoteException e) {
6048                throw new SecurityException(e);
6049            }
6050        }
6051    }
6052
6053    IIntentSender getIntentSenderLocked(int type, String packageName,
6054            int callingUid, int userId, IBinder token, String resultWho,
6055            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6056            Bundle options) {
6057        if (DEBUG_MU)
6058            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6059        ActivityRecord activity = null;
6060        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6061            activity = ActivityRecord.isInStackLocked(token);
6062            if (activity == null) {
6063                return null;
6064            }
6065            if (activity.finishing) {
6066                return null;
6067            }
6068        }
6069
6070        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6071        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6072        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6073        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6074                |PendingIntent.FLAG_UPDATE_CURRENT);
6075
6076        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6077                type, packageName, activity, resultWho,
6078                requestCode, intents, resolvedTypes, flags, options, userId);
6079        WeakReference<PendingIntentRecord> ref;
6080        ref = mIntentSenderRecords.get(key);
6081        PendingIntentRecord rec = ref != null ? ref.get() : null;
6082        if (rec != null) {
6083            if (!cancelCurrent) {
6084                if (updateCurrent) {
6085                    if (rec.key.requestIntent != null) {
6086                        rec.key.requestIntent.replaceExtras(intents != null ?
6087                                intents[intents.length - 1] : null);
6088                    }
6089                    if (intents != null) {
6090                        intents[intents.length-1] = rec.key.requestIntent;
6091                        rec.key.allIntents = intents;
6092                        rec.key.allResolvedTypes = resolvedTypes;
6093                    } else {
6094                        rec.key.allIntents = null;
6095                        rec.key.allResolvedTypes = null;
6096                    }
6097                }
6098                return rec;
6099            }
6100            rec.canceled = true;
6101            mIntentSenderRecords.remove(key);
6102        }
6103        if (noCreate) {
6104            return rec;
6105        }
6106        rec = new PendingIntentRecord(this, key, callingUid);
6107        mIntentSenderRecords.put(key, rec.ref);
6108        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6109            if (activity.pendingResults == null) {
6110                activity.pendingResults
6111                        = new HashSet<WeakReference<PendingIntentRecord>>();
6112            }
6113            activity.pendingResults.add(rec.ref);
6114        }
6115        return rec;
6116    }
6117
6118    @Override
6119    public void cancelIntentSender(IIntentSender sender) {
6120        if (!(sender instanceof PendingIntentRecord)) {
6121            return;
6122        }
6123        synchronized(this) {
6124            PendingIntentRecord rec = (PendingIntentRecord)sender;
6125            try {
6126                int uid = AppGlobals.getPackageManager()
6127                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6128                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6129                    String msg = "Permission Denial: cancelIntentSender() from pid="
6130                        + Binder.getCallingPid()
6131                        + ", uid=" + Binder.getCallingUid()
6132                        + " is not allowed to cancel packges "
6133                        + rec.key.packageName;
6134                    Slog.w(TAG, msg);
6135                    throw new SecurityException(msg);
6136                }
6137            } catch (RemoteException e) {
6138                throw new SecurityException(e);
6139            }
6140            cancelIntentSenderLocked(rec, true);
6141        }
6142    }
6143
6144    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6145        rec.canceled = true;
6146        mIntentSenderRecords.remove(rec.key);
6147        if (cleanActivity && rec.key.activity != null) {
6148            rec.key.activity.pendingResults.remove(rec.ref);
6149        }
6150    }
6151
6152    @Override
6153    public String getPackageForIntentSender(IIntentSender pendingResult) {
6154        if (!(pendingResult instanceof PendingIntentRecord)) {
6155            return null;
6156        }
6157        try {
6158            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6159            return res.key.packageName;
6160        } catch (ClassCastException e) {
6161        }
6162        return null;
6163    }
6164
6165    @Override
6166    public int getUidForIntentSender(IIntentSender sender) {
6167        if (sender instanceof PendingIntentRecord) {
6168            try {
6169                PendingIntentRecord res = (PendingIntentRecord)sender;
6170                return res.uid;
6171            } catch (ClassCastException e) {
6172            }
6173        }
6174        return -1;
6175    }
6176
6177    @Override
6178    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6179        if (!(pendingResult instanceof PendingIntentRecord)) {
6180            return false;
6181        }
6182        try {
6183            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6184            if (res.key.allIntents == null) {
6185                return false;
6186            }
6187            for (int i=0; i<res.key.allIntents.length; i++) {
6188                Intent intent = res.key.allIntents[i];
6189                if (intent.getPackage() != null && intent.getComponent() != null) {
6190                    return false;
6191                }
6192            }
6193            return true;
6194        } catch (ClassCastException e) {
6195        }
6196        return false;
6197    }
6198
6199    @Override
6200    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6201        if (!(pendingResult instanceof PendingIntentRecord)) {
6202            return false;
6203        }
6204        try {
6205            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6206            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6207                return true;
6208            }
6209            return false;
6210        } catch (ClassCastException e) {
6211        }
6212        return false;
6213    }
6214
6215    @Override
6216    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6217        if (!(pendingResult instanceof PendingIntentRecord)) {
6218            return null;
6219        }
6220        try {
6221            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6222            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6223        } catch (ClassCastException e) {
6224        }
6225        return null;
6226    }
6227
6228    @Override
6229    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6230        if (!(pendingResult instanceof PendingIntentRecord)) {
6231            return null;
6232        }
6233        try {
6234            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6235            Intent intent = res.key.requestIntent;
6236            if (intent != null) {
6237                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6238                        || res.lastTagPrefix.equals(prefix))) {
6239                    return res.lastTag;
6240                }
6241                res.lastTagPrefix = prefix;
6242                StringBuilder sb = new StringBuilder(128);
6243                if (prefix != null) {
6244                    sb.append(prefix);
6245                }
6246                if (intent.getAction() != null) {
6247                    sb.append(intent.getAction());
6248                } else if (intent.getComponent() != null) {
6249                    intent.getComponent().appendShortString(sb);
6250                } else {
6251                    sb.append("?");
6252                }
6253                return res.lastTag = sb.toString();
6254            }
6255        } catch (ClassCastException e) {
6256        }
6257        return null;
6258    }
6259
6260    @Override
6261    public void setProcessLimit(int max) {
6262        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6263                "setProcessLimit()");
6264        synchronized (this) {
6265            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6266            mProcessLimitOverride = max;
6267        }
6268        trimApplications();
6269    }
6270
6271    @Override
6272    public int getProcessLimit() {
6273        synchronized (this) {
6274            return mProcessLimitOverride;
6275        }
6276    }
6277
6278    void foregroundTokenDied(ForegroundToken token) {
6279        synchronized (ActivityManagerService.this) {
6280            synchronized (mPidsSelfLocked) {
6281                ForegroundToken cur
6282                    = mForegroundProcesses.get(token.pid);
6283                if (cur != token) {
6284                    return;
6285                }
6286                mForegroundProcesses.remove(token.pid);
6287                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6288                if (pr == null) {
6289                    return;
6290                }
6291                pr.forcingToForeground = null;
6292                updateProcessForegroundLocked(pr, false, false);
6293            }
6294            updateOomAdjLocked();
6295        }
6296    }
6297
6298    @Override
6299    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6300        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6301                "setProcessForeground()");
6302        synchronized(this) {
6303            boolean changed = false;
6304
6305            synchronized (mPidsSelfLocked) {
6306                ProcessRecord pr = mPidsSelfLocked.get(pid);
6307                if (pr == null && isForeground) {
6308                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6309                    return;
6310                }
6311                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6312                if (oldToken != null) {
6313                    oldToken.token.unlinkToDeath(oldToken, 0);
6314                    mForegroundProcesses.remove(pid);
6315                    if (pr != null) {
6316                        pr.forcingToForeground = null;
6317                    }
6318                    changed = true;
6319                }
6320                if (isForeground && token != null) {
6321                    ForegroundToken newToken = new ForegroundToken() {
6322                        @Override
6323                        public void binderDied() {
6324                            foregroundTokenDied(this);
6325                        }
6326                    };
6327                    newToken.pid = pid;
6328                    newToken.token = token;
6329                    try {
6330                        token.linkToDeath(newToken, 0);
6331                        mForegroundProcesses.put(pid, newToken);
6332                        pr.forcingToForeground = token;
6333                        changed = true;
6334                    } catch (RemoteException e) {
6335                        // If the process died while doing this, we will later
6336                        // do the cleanup with the process death link.
6337                    }
6338                }
6339            }
6340
6341            if (changed) {
6342                updateOomAdjLocked();
6343            }
6344        }
6345    }
6346
6347    // =========================================================
6348    // PERMISSIONS
6349    // =========================================================
6350
6351    static class PermissionController extends IPermissionController.Stub {
6352        ActivityManagerService mActivityManagerService;
6353        PermissionController(ActivityManagerService activityManagerService) {
6354            mActivityManagerService = activityManagerService;
6355        }
6356
6357        @Override
6358        public boolean checkPermission(String permission, int pid, int uid) {
6359            return mActivityManagerService.checkPermission(permission, pid,
6360                    uid) == PackageManager.PERMISSION_GRANTED;
6361        }
6362    }
6363
6364    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6365        @Override
6366        public int checkComponentPermission(String permission, int pid, int uid,
6367                int owningUid, boolean exported) {
6368            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6369                    owningUid, exported);
6370        }
6371
6372        @Override
6373        public Object getAMSLock() {
6374            return ActivityManagerService.this;
6375        }
6376    }
6377
6378    /**
6379     * This can be called with or without the global lock held.
6380     */
6381    int checkComponentPermission(String permission, int pid, int uid,
6382            int owningUid, boolean exported) {
6383        // We might be performing an operation on behalf of an indirect binder
6384        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6385        // client identity accordingly before proceeding.
6386        Identity tlsIdentity = sCallerIdentity.get();
6387        if (tlsIdentity != null) {
6388            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6389                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6390            uid = tlsIdentity.uid;
6391            pid = tlsIdentity.pid;
6392        }
6393
6394        if (pid == MY_PID) {
6395            return PackageManager.PERMISSION_GRANTED;
6396        }
6397
6398        return ActivityManager.checkComponentPermission(permission, uid,
6399                owningUid, exported);
6400    }
6401
6402    /**
6403     * As the only public entry point for permissions checking, this method
6404     * can enforce the semantic that requesting a check on a null global
6405     * permission is automatically denied.  (Internally a null permission
6406     * string is used when calling {@link #checkComponentPermission} in cases
6407     * when only uid-based security is needed.)
6408     *
6409     * This can be called with or without the global lock held.
6410     */
6411    @Override
6412    public int checkPermission(String permission, int pid, int uid) {
6413        if (permission == null) {
6414            return PackageManager.PERMISSION_DENIED;
6415        }
6416        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6417    }
6418
6419    /**
6420     * Binder IPC calls go through the public entry point.
6421     * This can be called with or without the global lock held.
6422     */
6423    int checkCallingPermission(String permission) {
6424        return checkPermission(permission,
6425                Binder.getCallingPid(),
6426                UserHandle.getAppId(Binder.getCallingUid()));
6427    }
6428
6429    /**
6430     * This can be called with or without the global lock held.
6431     */
6432    void enforceCallingPermission(String permission, String func) {
6433        if (checkCallingPermission(permission)
6434                == PackageManager.PERMISSION_GRANTED) {
6435            return;
6436        }
6437
6438        String msg = "Permission Denial: " + func + " from pid="
6439                + Binder.getCallingPid()
6440                + ", uid=" + Binder.getCallingUid()
6441                + " requires " + permission;
6442        Slog.w(TAG, msg);
6443        throw new SecurityException(msg);
6444    }
6445
6446    /**
6447     * Determine if UID is holding permissions required to access {@link Uri} in
6448     * the given {@link ProviderInfo}. Final permission checking is always done
6449     * in {@link ContentProvider}.
6450     */
6451    private final boolean checkHoldingPermissionsLocked(
6452            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6453        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6454                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6455        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6456            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6457                    != PERMISSION_GRANTED) {
6458                return false;
6459            }
6460        }
6461        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6462    }
6463
6464    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6465            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6466        if (pi.applicationInfo.uid == uid) {
6467            return true;
6468        } else if (!pi.exported) {
6469            return false;
6470        }
6471
6472        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6473        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6474        try {
6475            // check if target holds top-level <provider> permissions
6476            if (!readMet && pi.readPermission != null && considerUidPermissions
6477                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6478                readMet = true;
6479            }
6480            if (!writeMet && pi.writePermission != null && considerUidPermissions
6481                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6482                writeMet = true;
6483            }
6484
6485            // track if unprotected read/write is allowed; any denied
6486            // <path-permission> below removes this ability
6487            boolean allowDefaultRead = pi.readPermission == null;
6488            boolean allowDefaultWrite = pi.writePermission == null;
6489
6490            // check if target holds any <path-permission> that match uri
6491            final PathPermission[] pps = pi.pathPermissions;
6492            if (pps != null) {
6493                final String path = grantUri.uri.getPath();
6494                int i = pps.length;
6495                while (i > 0 && (!readMet || !writeMet)) {
6496                    i--;
6497                    PathPermission pp = pps[i];
6498                    if (pp.match(path)) {
6499                        if (!readMet) {
6500                            final String pprperm = pp.getReadPermission();
6501                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6502                                    + pprperm + " for " + pp.getPath()
6503                                    + ": match=" + pp.match(path)
6504                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6505                            if (pprperm != null) {
6506                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6507                                        == PERMISSION_GRANTED) {
6508                                    readMet = true;
6509                                } else {
6510                                    allowDefaultRead = false;
6511                                }
6512                            }
6513                        }
6514                        if (!writeMet) {
6515                            final String ppwperm = pp.getWritePermission();
6516                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6517                                    + ppwperm + " for " + pp.getPath()
6518                                    + ": match=" + pp.match(path)
6519                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6520                            if (ppwperm != null) {
6521                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6522                                        == PERMISSION_GRANTED) {
6523                                    writeMet = true;
6524                                } else {
6525                                    allowDefaultWrite = false;
6526                                }
6527                            }
6528                        }
6529                    }
6530                }
6531            }
6532
6533            // grant unprotected <provider> read/write, if not blocked by
6534            // <path-permission> above
6535            if (allowDefaultRead) readMet = true;
6536            if (allowDefaultWrite) writeMet = true;
6537
6538        } catch (RemoteException e) {
6539            return false;
6540        }
6541
6542        return readMet && writeMet;
6543    }
6544
6545    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6546        ProviderInfo pi = null;
6547        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6548        if (cpr != null) {
6549            pi = cpr.info;
6550        } else {
6551            try {
6552                pi = AppGlobals.getPackageManager().resolveContentProvider(
6553                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6554            } catch (RemoteException ex) {
6555            }
6556        }
6557        return pi;
6558    }
6559
6560    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6561        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6562        if (targetUris != null) {
6563            return targetUris.get(grantUri);
6564        }
6565        return null;
6566    }
6567
6568    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6569            String targetPkg, int targetUid, GrantUri grantUri) {
6570        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6571        if (targetUris == null) {
6572            targetUris = Maps.newArrayMap();
6573            mGrantedUriPermissions.put(targetUid, targetUris);
6574        }
6575
6576        UriPermission perm = targetUris.get(grantUri);
6577        if (perm == null) {
6578            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6579            targetUris.put(grantUri, perm);
6580        }
6581
6582        return perm;
6583    }
6584
6585    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6586            final int modeFlags) {
6587        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6588        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6589                : UriPermission.STRENGTH_OWNED;
6590
6591        // Root gets to do everything.
6592        if (uid == 0) {
6593            return true;
6594        }
6595
6596        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6597        if (perms == null) return false;
6598
6599        // First look for exact match
6600        final UriPermission exactPerm = perms.get(grantUri);
6601        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6602            return true;
6603        }
6604
6605        // No exact match, look for prefixes
6606        final int N = perms.size();
6607        for (int i = 0; i < N; i++) {
6608            final UriPermission perm = perms.valueAt(i);
6609            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6610                    && perm.getStrength(modeFlags) >= minStrength) {
6611                return true;
6612            }
6613        }
6614
6615        return false;
6616    }
6617
6618    @Override
6619    public int checkUriPermission(Uri uri, int pid, int uid,
6620            final int modeFlags, int userId) {
6621        enforceNotIsolatedCaller("checkUriPermission");
6622
6623        // Another redirected-binder-call permissions check as in
6624        // {@link checkComponentPermission}.
6625        Identity tlsIdentity = sCallerIdentity.get();
6626        if (tlsIdentity != null) {
6627            uid = tlsIdentity.uid;
6628            pid = tlsIdentity.pid;
6629        }
6630
6631        // Our own process gets to do everything.
6632        if (pid == MY_PID) {
6633            return PackageManager.PERMISSION_GRANTED;
6634        }
6635        synchronized (this) {
6636            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6637                    ? PackageManager.PERMISSION_GRANTED
6638                    : PackageManager.PERMISSION_DENIED;
6639        }
6640    }
6641
6642    /**
6643     * Check if the targetPkg can be granted permission to access uri by
6644     * the callingUid using the given modeFlags.  Throws a security exception
6645     * if callingUid is not allowed to do this.  Returns the uid of the target
6646     * if the URI permission grant should be performed; returns -1 if it is not
6647     * needed (for example targetPkg already has permission to access the URI).
6648     * If you already know the uid of the target, you can supply it in
6649     * lastTargetUid else set that to -1.
6650     */
6651    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6652            final int modeFlags, int lastTargetUid) {
6653        if (!Intent.isAccessUriMode(modeFlags)) {
6654            return -1;
6655        }
6656
6657        if (targetPkg != null) {
6658            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6659                    "Checking grant " + targetPkg + " permission to " + grantUri);
6660        }
6661
6662        final IPackageManager pm = AppGlobals.getPackageManager();
6663
6664        // If this is not a content: uri, we can't do anything with it.
6665        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6666            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6667                    "Can't grant URI permission for non-content URI: " + grantUri);
6668            return -1;
6669        }
6670
6671        final String authority = grantUri.uri.getAuthority();
6672        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6673        if (pi == null) {
6674            Slog.w(TAG, "No content provider found for permission check: " +
6675                    grantUri.uri.toSafeString());
6676            return -1;
6677        }
6678
6679        int targetUid = lastTargetUid;
6680        if (targetUid < 0 && targetPkg != null) {
6681            try {
6682                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6683                if (targetUid < 0) {
6684                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6685                            "Can't grant URI permission no uid for: " + targetPkg);
6686                    return -1;
6687                }
6688            } catch (RemoteException ex) {
6689                return -1;
6690            }
6691        }
6692
6693        if (targetUid >= 0) {
6694            // First...  does the target actually need this permission?
6695            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6696                // No need to grant the target this permission.
6697                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6698                        "Target " + targetPkg + " already has full permission to " + grantUri);
6699                return -1;
6700            }
6701        } else {
6702            // First...  there is no target package, so can anyone access it?
6703            boolean allowed = pi.exported;
6704            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6705                if (pi.readPermission != null) {
6706                    allowed = false;
6707                }
6708            }
6709            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6710                if (pi.writePermission != null) {
6711                    allowed = false;
6712                }
6713            }
6714            if (allowed) {
6715                return -1;
6716            }
6717        }
6718
6719        /* There is a special cross user grant if:
6720         * - The target is on another user.
6721         * - Apps on the current user can access the uri without any uid permissions.
6722         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6723         * grant uri permissions.
6724         */
6725        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6726                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6727                modeFlags, false /*without considering the uid permissions*/);
6728
6729        // Second...  is the provider allowing granting of URI permissions?
6730        if (!specialCrossUserGrant) {
6731            if (!pi.grantUriPermissions) {
6732                throw new SecurityException("Provider " + pi.packageName
6733                        + "/" + pi.name
6734                        + " does not allow granting of Uri permissions (uri "
6735                        + grantUri + ")");
6736            }
6737            if (pi.uriPermissionPatterns != null) {
6738                final int N = pi.uriPermissionPatterns.length;
6739                boolean allowed = false;
6740                for (int i=0; i<N; i++) {
6741                    if (pi.uriPermissionPatterns[i] != null
6742                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6743                        allowed = true;
6744                        break;
6745                    }
6746                }
6747                if (!allowed) {
6748                    throw new SecurityException("Provider " + pi.packageName
6749                            + "/" + pi.name
6750                            + " does not allow granting of permission to path of Uri "
6751                            + grantUri);
6752                }
6753            }
6754        }
6755
6756        // Third...  does the caller itself have permission to access
6757        // this uri?
6758        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6759            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6760                // Require they hold a strong enough Uri permission
6761                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6762                    throw new SecurityException("Uid " + callingUid
6763                            + " does not have permission to uri " + grantUri);
6764                }
6765            }
6766        }
6767        return targetUid;
6768    }
6769
6770    @Override
6771    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6772            final int modeFlags, int userId) {
6773        enforceNotIsolatedCaller("checkGrantUriPermission");
6774        synchronized(this) {
6775            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6776                    new GrantUri(userId, uri, false), modeFlags, -1);
6777        }
6778    }
6779
6780    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6781            final int modeFlags, UriPermissionOwner owner) {
6782        if (!Intent.isAccessUriMode(modeFlags)) {
6783            return;
6784        }
6785
6786        // So here we are: the caller has the assumed permission
6787        // to the uri, and the target doesn't.  Let's now give this to
6788        // the target.
6789
6790        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6791                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6792
6793        final String authority = grantUri.uri.getAuthority();
6794        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6795        if (pi == null) {
6796            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6797            return;
6798        }
6799
6800        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6801            grantUri.prefix = true;
6802        }
6803        final UriPermission perm = findOrCreateUriPermissionLocked(
6804                pi.packageName, targetPkg, targetUid, grantUri);
6805        perm.grantModes(modeFlags, owner);
6806    }
6807
6808    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6809            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6810        if (targetPkg == null) {
6811            throw new NullPointerException("targetPkg");
6812        }
6813        int targetUid;
6814        final IPackageManager pm = AppGlobals.getPackageManager();
6815        try {
6816            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6817        } catch (RemoteException ex) {
6818            return;
6819        }
6820
6821        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6822                targetUid);
6823        if (targetUid < 0) {
6824            return;
6825        }
6826
6827        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6828                owner);
6829    }
6830
6831    static class NeededUriGrants extends ArrayList<GrantUri> {
6832        final String targetPkg;
6833        final int targetUid;
6834        final int flags;
6835
6836        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6837            this.targetPkg = targetPkg;
6838            this.targetUid = targetUid;
6839            this.flags = flags;
6840        }
6841    }
6842
6843    /**
6844     * Like checkGrantUriPermissionLocked, but takes an Intent.
6845     */
6846    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6847            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6848        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6849                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6850                + " clip=" + (intent != null ? intent.getClipData() : null)
6851                + " from " + intent + "; flags=0x"
6852                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6853
6854        if (targetPkg == null) {
6855            throw new NullPointerException("targetPkg");
6856        }
6857
6858        if (intent == null) {
6859            return null;
6860        }
6861        Uri data = intent.getData();
6862        ClipData clip = intent.getClipData();
6863        if (data == null && clip == null) {
6864            return null;
6865        }
6866        // Default userId for uris in the intent (if they don't specify it themselves)
6867        int contentUserHint = intent.getContentUserHint();
6868        if (contentUserHint == UserHandle.USER_CURRENT) {
6869            contentUserHint = UserHandle.getUserId(callingUid);
6870        }
6871        final IPackageManager pm = AppGlobals.getPackageManager();
6872        int targetUid;
6873        if (needed != null) {
6874            targetUid = needed.targetUid;
6875        } else {
6876            try {
6877                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6878            } catch (RemoteException ex) {
6879                return null;
6880            }
6881            if (targetUid < 0) {
6882                if (DEBUG_URI_PERMISSION) {
6883                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6884                            + " on user " + targetUserId);
6885                }
6886                return null;
6887            }
6888        }
6889        if (data != null) {
6890            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6891            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6892                    targetUid);
6893            if (targetUid > 0) {
6894                if (needed == null) {
6895                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6896                }
6897                needed.add(grantUri);
6898            }
6899        }
6900        if (clip != null) {
6901            for (int i=0; i<clip.getItemCount(); i++) {
6902                Uri uri = clip.getItemAt(i).getUri();
6903                if (uri != null) {
6904                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6905                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6906                            targetUid);
6907                    if (targetUid > 0) {
6908                        if (needed == null) {
6909                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6910                        }
6911                        needed.add(grantUri);
6912                    }
6913                } else {
6914                    Intent clipIntent = clip.getItemAt(i).getIntent();
6915                    if (clipIntent != null) {
6916                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6917                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6918                        if (newNeeded != null) {
6919                            needed = newNeeded;
6920                        }
6921                    }
6922                }
6923            }
6924        }
6925
6926        return needed;
6927    }
6928
6929    /**
6930     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6931     */
6932    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6933            UriPermissionOwner owner) {
6934        if (needed != null) {
6935            for (int i=0; i<needed.size(); i++) {
6936                GrantUri grantUri = needed.get(i);
6937                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6938                        grantUri, needed.flags, owner);
6939            }
6940        }
6941    }
6942
6943    void grantUriPermissionFromIntentLocked(int callingUid,
6944            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6945        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6946                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6947        if (needed == null) {
6948            return;
6949        }
6950
6951        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6952    }
6953
6954    @Override
6955    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6956            final int modeFlags, int userId) {
6957        enforceNotIsolatedCaller("grantUriPermission");
6958        GrantUri grantUri = new GrantUri(userId, uri, false);
6959        synchronized(this) {
6960            final ProcessRecord r = getRecordForAppLocked(caller);
6961            if (r == null) {
6962                throw new SecurityException("Unable to find app for caller "
6963                        + caller
6964                        + " when granting permission to uri " + grantUri);
6965            }
6966            if (targetPkg == null) {
6967                throw new IllegalArgumentException("null target");
6968            }
6969            if (grantUri == null) {
6970                throw new IllegalArgumentException("null uri");
6971            }
6972
6973            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6974                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6975                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6976                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6977
6978            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6979                    UserHandle.getUserId(r.uid));
6980        }
6981    }
6982
6983    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6984        if (perm.modeFlags == 0) {
6985            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6986                    perm.targetUid);
6987            if (perms != null) {
6988                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6989                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6990
6991                perms.remove(perm.uri);
6992                if (perms.isEmpty()) {
6993                    mGrantedUriPermissions.remove(perm.targetUid);
6994                }
6995            }
6996        }
6997    }
6998
6999    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7000        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7001
7002        final IPackageManager pm = AppGlobals.getPackageManager();
7003        final String authority = grantUri.uri.getAuthority();
7004        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7005        if (pi == null) {
7006            Slog.w(TAG, "No content provider found for permission revoke: "
7007                    + grantUri.toSafeString());
7008            return;
7009        }
7010
7011        // Does the caller have this permission on the URI?
7012        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7013            // Right now, if you are not the original owner of the permission,
7014            // you are not allowed to revoke it.
7015            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7016                throw new SecurityException("Uid " + callingUid
7017                        + " does not have permission to uri " + grantUri);
7018            //}
7019        }
7020
7021        boolean persistChanged = false;
7022
7023        // Go through all of the permissions and remove any that match.
7024        int N = mGrantedUriPermissions.size();
7025        for (int i = 0; i < N; i++) {
7026            final int targetUid = mGrantedUriPermissions.keyAt(i);
7027            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7028
7029            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7030                final UriPermission perm = it.next();
7031                if (perm.uri.sourceUserId == grantUri.sourceUserId
7032                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7033                    if (DEBUG_URI_PERMISSION)
7034                        Slog.v(TAG,
7035                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7036                    persistChanged |= perm.revokeModes(
7037                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7038                    if (perm.modeFlags == 0) {
7039                        it.remove();
7040                    }
7041                }
7042            }
7043
7044            if (perms.isEmpty()) {
7045                mGrantedUriPermissions.remove(targetUid);
7046                N--;
7047                i--;
7048            }
7049        }
7050
7051        if (persistChanged) {
7052            schedulePersistUriGrants();
7053        }
7054    }
7055
7056    @Override
7057    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7058            int userId) {
7059        enforceNotIsolatedCaller("revokeUriPermission");
7060        synchronized(this) {
7061            final ProcessRecord r = getRecordForAppLocked(caller);
7062            if (r == null) {
7063                throw new SecurityException("Unable to find app for caller "
7064                        + caller
7065                        + " when revoking permission to uri " + uri);
7066            }
7067            if (uri == null) {
7068                Slog.w(TAG, "revokeUriPermission: null uri");
7069                return;
7070            }
7071
7072            if (!Intent.isAccessUriMode(modeFlags)) {
7073                return;
7074            }
7075
7076            final IPackageManager pm = AppGlobals.getPackageManager();
7077            final String authority = uri.getAuthority();
7078            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7079            if (pi == null) {
7080                Slog.w(TAG, "No content provider found for permission revoke: "
7081                        + uri.toSafeString());
7082                return;
7083            }
7084
7085            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7086        }
7087    }
7088
7089    /**
7090     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7091     * given package.
7092     *
7093     * @param packageName Package name to match, or {@code null} to apply to all
7094     *            packages.
7095     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7096     *            to all users.
7097     * @param persistable If persistable grants should be removed.
7098     */
7099    private void removeUriPermissionsForPackageLocked(
7100            String packageName, int userHandle, boolean persistable) {
7101        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7102            throw new IllegalArgumentException("Must narrow by either package or user");
7103        }
7104
7105        boolean persistChanged = false;
7106
7107        int N = mGrantedUriPermissions.size();
7108        for (int i = 0; i < N; i++) {
7109            final int targetUid = mGrantedUriPermissions.keyAt(i);
7110            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7111
7112            // Only inspect grants matching user
7113            if (userHandle == UserHandle.USER_ALL
7114                    || userHandle == UserHandle.getUserId(targetUid)) {
7115                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7116                    final UriPermission perm = it.next();
7117
7118                    // Only inspect grants matching package
7119                    if (packageName == null || perm.sourcePkg.equals(packageName)
7120                            || perm.targetPkg.equals(packageName)) {
7121                        persistChanged |= perm.revokeModes(
7122                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7123
7124                        // Only remove when no modes remain; any persisted grants
7125                        // will keep this alive.
7126                        if (perm.modeFlags == 0) {
7127                            it.remove();
7128                        }
7129                    }
7130                }
7131
7132                if (perms.isEmpty()) {
7133                    mGrantedUriPermissions.remove(targetUid);
7134                    N--;
7135                    i--;
7136                }
7137            }
7138        }
7139
7140        if (persistChanged) {
7141            schedulePersistUriGrants();
7142        }
7143    }
7144
7145    @Override
7146    public IBinder newUriPermissionOwner(String name) {
7147        enforceNotIsolatedCaller("newUriPermissionOwner");
7148        synchronized(this) {
7149            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7150            return owner.getExternalTokenLocked();
7151        }
7152    }
7153
7154    @Override
7155    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7156            final int modeFlags, int sourceUserId, int targetUserId) {
7157        synchronized(this) {
7158            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7159            if (owner == null) {
7160                throw new IllegalArgumentException("Unknown owner: " + token);
7161            }
7162            if (fromUid != Binder.getCallingUid()) {
7163                if (Binder.getCallingUid() != Process.myUid()) {
7164                    // Only system code can grant URI permissions on behalf
7165                    // of other users.
7166                    throw new SecurityException("nice try");
7167                }
7168            }
7169            if (targetPkg == null) {
7170                throw new IllegalArgumentException("null target");
7171            }
7172            if (uri == null) {
7173                throw new IllegalArgumentException("null uri");
7174            }
7175
7176            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7177                    modeFlags, owner, targetUserId);
7178        }
7179    }
7180
7181    @Override
7182    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7183        synchronized(this) {
7184            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7185            if (owner == null) {
7186                throw new IllegalArgumentException("Unknown owner: " + token);
7187            }
7188
7189            if (uri == null) {
7190                owner.removeUriPermissionsLocked(mode);
7191            } else {
7192                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7193            }
7194        }
7195    }
7196
7197    private void schedulePersistUriGrants() {
7198        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7199            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7200                    10 * DateUtils.SECOND_IN_MILLIS);
7201        }
7202    }
7203
7204    private void writeGrantedUriPermissions() {
7205        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7206
7207        // Snapshot permissions so we can persist without lock
7208        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7209        synchronized (this) {
7210            final int size = mGrantedUriPermissions.size();
7211            for (int i = 0; i < size; i++) {
7212                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7213                for (UriPermission perm : perms.values()) {
7214                    if (perm.persistedModeFlags != 0) {
7215                        persist.add(perm.snapshot());
7216                    }
7217                }
7218            }
7219        }
7220
7221        FileOutputStream fos = null;
7222        try {
7223            fos = mGrantFile.startWrite();
7224
7225            XmlSerializer out = new FastXmlSerializer();
7226            out.setOutput(fos, "utf-8");
7227            out.startDocument(null, true);
7228            out.startTag(null, TAG_URI_GRANTS);
7229            for (UriPermission.Snapshot perm : persist) {
7230                out.startTag(null, TAG_URI_GRANT);
7231                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7232                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7233                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7234                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7235                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7236                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7237                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7238                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7239                out.endTag(null, TAG_URI_GRANT);
7240            }
7241            out.endTag(null, TAG_URI_GRANTS);
7242            out.endDocument();
7243
7244            mGrantFile.finishWrite(fos);
7245        } catch (IOException e) {
7246            if (fos != null) {
7247                mGrantFile.failWrite(fos);
7248            }
7249        }
7250    }
7251
7252    private void readGrantedUriPermissionsLocked() {
7253        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7254
7255        final long now = System.currentTimeMillis();
7256
7257        FileInputStream fis = null;
7258        try {
7259            fis = mGrantFile.openRead();
7260            final XmlPullParser in = Xml.newPullParser();
7261            in.setInput(fis, null);
7262
7263            int type;
7264            while ((type = in.next()) != END_DOCUMENT) {
7265                final String tag = in.getName();
7266                if (type == START_TAG) {
7267                    if (TAG_URI_GRANT.equals(tag)) {
7268                        final int sourceUserId;
7269                        final int targetUserId;
7270                        final int userHandle = readIntAttribute(in,
7271                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7272                        if (userHandle != UserHandle.USER_NULL) {
7273                            // For backwards compatibility.
7274                            sourceUserId = userHandle;
7275                            targetUserId = userHandle;
7276                        } else {
7277                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7278                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7279                        }
7280                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7281                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7282                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7283                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7284                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7285                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7286
7287                        // Sanity check that provider still belongs to source package
7288                        final ProviderInfo pi = getProviderInfoLocked(
7289                                uri.getAuthority(), sourceUserId);
7290                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7291                            int targetUid = -1;
7292                            try {
7293                                targetUid = AppGlobals.getPackageManager()
7294                                        .getPackageUid(targetPkg, targetUserId);
7295                            } catch (RemoteException e) {
7296                            }
7297                            if (targetUid != -1) {
7298                                final UriPermission perm = findOrCreateUriPermissionLocked(
7299                                        sourcePkg, targetPkg, targetUid,
7300                                        new GrantUri(sourceUserId, uri, prefix));
7301                                perm.initPersistedModes(modeFlags, createdTime);
7302                            }
7303                        } else {
7304                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7305                                    + " but instead found " + pi);
7306                        }
7307                    }
7308                }
7309            }
7310        } catch (FileNotFoundException e) {
7311            // Missing grants is okay
7312        } catch (IOException e) {
7313            Log.wtf(TAG, "Failed reading Uri grants", e);
7314        } catch (XmlPullParserException e) {
7315            Log.wtf(TAG, "Failed reading Uri grants", e);
7316        } finally {
7317            IoUtils.closeQuietly(fis);
7318        }
7319    }
7320
7321    @Override
7322    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7323        enforceNotIsolatedCaller("takePersistableUriPermission");
7324
7325        Preconditions.checkFlagsArgument(modeFlags,
7326                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7327
7328        synchronized (this) {
7329            final int callingUid = Binder.getCallingUid();
7330            boolean persistChanged = false;
7331            GrantUri grantUri = new GrantUri(userId, uri, false);
7332
7333            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7334                    new GrantUri(userId, uri, false));
7335            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7336                    new GrantUri(userId, uri, true));
7337
7338            final boolean exactValid = (exactPerm != null)
7339                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7340            final boolean prefixValid = (prefixPerm != null)
7341                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7342
7343            if (!(exactValid || prefixValid)) {
7344                throw new SecurityException("No persistable permission grants found for UID "
7345                        + callingUid + " and Uri " + grantUri.toSafeString());
7346            }
7347
7348            if (exactValid) {
7349                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7350            }
7351            if (prefixValid) {
7352                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7353            }
7354
7355            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7356
7357            if (persistChanged) {
7358                schedulePersistUriGrants();
7359            }
7360        }
7361    }
7362
7363    @Override
7364    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7365        enforceNotIsolatedCaller("releasePersistableUriPermission");
7366
7367        Preconditions.checkFlagsArgument(modeFlags,
7368                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7369
7370        synchronized (this) {
7371            final int callingUid = Binder.getCallingUid();
7372            boolean persistChanged = false;
7373
7374            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7375                    new GrantUri(userId, uri, false));
7376            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7377                    new GrantUri(userId, uri, true));
7378            if (exactPerm == null && prefixPerm == null) {
7379                throw new SecurityException("No permission grants found for UID " + callingUid
7380                        + " and Uri " + uri.toSafeString());
7381            }
7382
7383            if (exactPerm != null) {
7384                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7385                removeUriPermissionIfNeededLocked(exactPerm);
7386            }
7387            if (prefixPerm != null) {
7388                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7389                removeUriPermissionIfNeededLocked(prefixPerm);
7390            }
7391
7392            if (persistChanged) {
7393                schedulePersistUriGrants();
7394            }
7395        }
7396    }
7397
7398    /**
7399     * Prune any older {@link UriPermission} for the given UID until outstanding
7400     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7401     *
7402     * @return if any mutations occured that require persisting.
7403     */
7404    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7405        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7406        if (perms == null) return false;
7407        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7408
7409        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7410        for (UriPermission perm : perms.values()) {
7411            if (perm.persistedModeFlags != 0) {
7412                persisted.add(perm);
7413            }
7414        }
7415
7416        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7417        if (trimCount <= 0) return false;
7418
7419        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7420        for (int i = 0; i < trimCount; i++) {
7421            final UriPermission perm = persisted.get(i);
7422
7423            if (DEBUG_URI_PERMISSION) {
7424                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7425            }
7426
7427            perm.releasePersistableModes(~0);
7428            removeUriPermissionIfNeededLocked(perm);
7429        }
7430
7431        return true;
7432    }
7433
7434    @Override
7435    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7436            String packageName, boolean incoming) {
7437        enforceNotIsolatedCaller("getPersistedUriPermissions");
7438        Preconditions.checkNotNull(packageName, "packageName");
7439
7440        final int callingUid = Binder.getCallingUid();
7441        final IPackageManager pm = AppGlobals.getPackageManager();
7442        try {
7443            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7444            if (packageUid != callingUid) {
7445                throw new SecurityException(
7446                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7447            }
7448        } catch (RemoteException e) {
7449            throw new SecurityException("Failed to verify package name ownership");
7450        }
7451
7452        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7453        synchronized (this) {
7454            if (incoming) {
7455                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7456                        callingUid);
7457                if (perms == null) {
7458                    Slog.w(TAG, "No permission grants found for " + packageName);
7459                } else {
7460                    for (UriPermission perm : perms.values()) {
7461                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7462                            result.add(perm.buildPersistedPublicApiObject());
7463                        }
7464                    }
7465                }
7466            } else {
7467                final int size = mGrantedUriPermissions.size();
7468                for (int i = 0; i < size; i++) {
7469                    final ArrayMap<GrantUri, UriPermission> perms =
7470                            mGrantedUriPermissions.valueAt(i);
7471                    for (UriPermission perm : perms.values()) {
7472                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7473                            result.add(perm.buildPersistedPublicApiObject());
7474                        }
7475                    }
7476                }
7477            }
7478        }
7479        return new ParceledListSlice<android.content.UriPermission>(result);
7480    }
7481
7482    @Override
7483    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7484        synchronized (this) {
7485            ProcessRecord app =
7486                who != null ? getRecordForAppLocked(who) : null;
7487            if (app == null) return;
7488
7489            Message msg = Message.obtain();
7490            msg.what = WAIT_FOR_DEBUGGER_MSG;
7491            msg.obj = app;
7492            msg.arg1 = waiting ? 1 : 0;
7493            mHandler.sendMessage(msg);
7494        }
7495    }
7496
7497    @Override
7498    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7499        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7500        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7501        outInfo.availMem = Process.getFreeMemory();
7502        outInfo.totalMem = Process.getTotalMemory();
7503        outInfo.threshold = homeAppMem;
7504        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7505        outInfo.hiddenAppThreshold = cachedAppMem;
7506        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7507                ProcessList.SERVICE_ADJ);
7508        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7509                ProcessList.VISIBLE_APP_ADJ);
7510        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7511                ProcessList.FOREGROUND_APP_ADJ);
7512    }
7513
7514    // =========================================================
7515    // TASK MANAGEMENT
7516    // =========================================================
7517
7518    @Override
7519    public List<IAppTask> getAppTasks() {
7520        final PackageManager pm = mContext.getPackageManager();
7521        int callingUid = Binder.getCallingUid();
7522        long ident = Binder.clearCallingIdentity();
7523
7524        // Compose the list of packages for this id to test against
7525        HashSet<String> packages = new HashSet<String>();
7526        String[] uidPackages = pm.getPackagesForUid(callingUid);
7527        for (int i = 0; i < uidPackages.length; i++) {
7528            packages.add(uidPackages[i]);
7529        }
7530
7531        synchronized(this) {
7532            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7533            try {
7534                if (localLOGV) Slog.v(TAG, "getAppTasks");
7535
7536                final int N = mRecentTasks.size();
7537                for (int i = 0; i < N; i++) {
7538                    TaskRecord tr = mRecentTasks.get(i);
7539                    // Skip tasks that do not match the package name
7540                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7541                        ActivityManager.RecentTaskInfo taskInfo =
7542                                createRecentTaskInfoFromTaskRecord(tr);
7543                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7544                        list.add(taskImpl);
7545                    }
7546                }
7547            } finally {
7548                Binder.restoreCallingIdentity(ident);
7549            }
7550            return list;
7551        }
7552    }
7553
7554    @Override
7555    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7556        final int callingUid = Binder.getCallingUid();
7557        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7558
7559        synchronized(this) {
7560            if (localLOGV) Slog.v(
7561                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7562
7563            final boolean allowed = checkCallingPermission(
7564                    android.Manifest.permission.GET_TASKS)
7565                    == PackageManager.PERMISSION_GRANTED;
7566            if (!allowed) {
7567                Slog.w(TAG, "getTasks: caller " + callingUid
7568                        + " does not hold GET_TASKS; limiting output");
7569            }
7570
7571            // TODO: Improve with MRU list from all ActivityStacks.
7572            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7573        }
7574
7575        return list;
7576    }
7577
7578    TaskRecord getMostRecentTask() {
7579        return mRecentTasks.get(0);
7580    }
7581
7582    /**
7583     * Creates a new RecentTaskInfo from a TaskRecord.
7584     */
7585    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7586        // Update the task description to reflect any changes in the task stack
7587        tr.updateTaskDescription();
7588
7589        // Compose the recent task info
7590        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7591        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7592        rti.persistentId = tr.taskId;
7593        rti.baseIntent = new Intent(tr.getBaseIntent());
7594        rti.origActivity = tr.origActivity;
7595        rti.description = tr.lastDescription;
7596        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7597        rti.userId = tr.userId;
7598        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7599        rti.firstActiveTime = tr.firstActiveTime;
7600        rti.lastActiveTime = tr.lastActiveTime;
7601        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7602        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7603        return rti;
7604    }
7605
7606    @Override
7607    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7608        final int callingUid = Binder.getCallingUid();
7609        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7610                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7611
7612        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7613        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7614        synchronized (this) {
7615            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7616                    == PackageManager.PERMISSION_GRANTED;
7617            if (!allowed) {
7618                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7619                        + " does not hold GET_TASKS; limiting output");
7620            }
7621            final boolean detailed = checkCallingPermission(
7622                    android.Manifest.permission.GET_DETAILED_TASKS)
7623                    == PackageManager.PERMISSION_GRANTED;
7624
7625            IPackageManager pm = AppGlobals.getPackageManager();
7626
7627            final int N = mRecentTasks.size();
7628            ArrayList<ActivityManager.RecentTaskInfo> res
7629                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7630                            maxNum < N ? maxNum : N);
7631
7632            final Set<Integer> includedUsers;
7633            if (includeProfiles) {
7634                includedUsers = getProfileIdsLocked(userId);
7635            } else {
7636                includedUsers = new HashSet<Integer>();
7637            }
7638            includedUsers.add(Integer.valueOf(userId));
7639
7640            // Regroup affiliated tasks together.
7641            for (int i = 0; i < N; ) {
7642                TaskRecord task = mRecentTasks.remove(i);
7643                if (mTmpRecents.contains(task)) {
7644                    continue;
7645                }
7646                int affiliatedTaskId = task.mAffiliatedTaskId;
7647                while (true) {
7648                    TaskRecord next = task.mNextAffiliate;
7649                    if (next == null) {
7650                        break;
7651                    }
7652                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7653                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7654                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7655                        task.setNextAffiliate(null);
7656                        if (next.mPrevAffiliate == task) {
7657                            next.setPrevAffiliate(null);
7658                        }
7659                        break;
7660                    }
7661                    if (next.mPrevAffiliate != task) {
7662                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7663                                next.mPrevAffiliate + " task=" + task);
7664                        next.setPrevAffiliate(null);
7665                        break;
7666                    }
7667                    if (!mRecentTasks.contains(next)) {
7668                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7669                        task.setNextAffiliate(null);
7670                        if (next.mPrevAffiliate == task) {
7671                            next.setPrevAffiliate(null);
7672                        }
7673                        break;
7674                    }
7675                    task = next;
7676                }
7677                // task is now the end of the list
7678                do {
7679                    mRecentTasks.remove(task);
7680                    mRecentTasks.add(i++, task);
7681                    mTmpRecents.add(task);
7682                } while ((task = task.mPrevAffiliate) != null);
7683            }
7684            mTmpRecents.clear();
7685            // mRecentTasks is now in sorted, affiliated order.
7686
7687            for (int i=0; i<N && maxNum > 0; i++) {
7688                TaskRecord tr = mRecentTasks.get(i);
7689                // Only add calling user or related users recent tasks
7690                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7691                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7692                    continue;
7693                }
7694
7695                // Return the entry if desired by the caller.  We always return
7696                // the first entry, because callers always expect this to be the
7697                // foreground app.  We may filter others if the caller has
7698                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7699                // we should exclude the entry.
7700
7701                if (i == 0
7702                        || withExcluded
7703                        || (tr.intent == null)
7704                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7705                                == 0)) {
7706                    if (!allowed) {
7707                        // If the caller doesn't have the GET_TASKS permission, then only
7708                        // allow them to see a small subset of tasks -- their own and home.
7709                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7710                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7711                            continue;
7712                        }
7713                    }
7714                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7715                        // Don't include auto remove tasks that are finished or finishing.
7716                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7717                                + tr);
7718                        continue;
7719                    }
7720
7721                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7722                    if (!detailed) {
7723                        rti.baseIntent.replaceExtras((Bundle)null);
7724                    }
7725
7726                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7727                        // Check whether this activity is currently available.
7728                        try {
7729                            if (rti.origActivity != null) {
7730                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7731                                        == null) {
7732                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail orig act: "
7733                                            + tr);
7734                                    continue;
7735                                }
7736                            } else if (rti.baseIntent != null) {
7737                                if (pm.queryIntentActivities(rti.baseIntent,
7738                                        null, 0, userId) == null) {
7739                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail intent: "
7740                                            + tr);
7741                                    continue;
7742                                }
7743                            }
7744                        } catch (RemoteException e) {
7745                            // Will never happen.
7746                        }
7747                    }
7748
7749                    res.add(rti);
7750                    maxNum--;
7751                }
7752            }
7753            return res;
7754        }
7755    }
7756
7757    private TaskRecord recentTaskForIdLocked(int id) {
7758        final int N = mRecentTasks.size();
7759            for (int i=0; i<N; i++) {
7760                TaskRecord tr = mRecentTasks.get(i);
7761                if (tr.taskId == id) {
7762                    return tr;
7763                }
7764            }
7765            return null;
7766    }
7767
7768    @Override
7769    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7770        synchronized (this) {
7771            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7772                    "getTaskThumbnail()");
7773            TaskRecord tr = recentTaskForIdLocked(id);
7774            if (tr != null) {
7775                return tr.getTaskThumbnailLocked();
7776            }
7777        }
7778        return null;
7779    }
7780
7781    @Override
7782    public int addAppTask(IBinder activityToken, Intent intent,
7783            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7784        final int callingUid = Binder.getCallingUid();
7785        final long callingIdent = Binder.clearCallingIdentity();
7786
7787        try {
7788            synchronized (this) {
7789                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7790                if (r == null) {
7791                    throw new IllegalArgumentException("Activity does not exist; token="
7792                            + activityToken);
7793                }
7794                ComponentName comp = intent.getComponent();
7795                if (comp == null) {
7796                    throw new IllegalArgumentException("Intent " + intent
7797                            + " must specify explicit component");
7798                }
7799                if (thumbnail.getWidth() != mThumbnailWidth
7800                        || thumbnail.getHeight() != mThumbnailHeight) {
7801                    throw new IllegalArgumentException("Bad thumbnail size: got "
7802                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7803                            + mThumbnailWidth + "x" + mThumbnailHeight);
7804                }
7805                if (intent.getSelector() != null) {
7806                    intent.setSelector(null);
7807                }
7808                if (intent.getSourceBounds() != null) {
7809                    intent.setSourceBounds(null);
7810                }
7811                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7812                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7813                        // The caller has added this as an auto-remove task...  that makes no
7814                        // sense, so turn off auto-remove.
7815                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7816                    }
7817                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7818                    // Must be a new task.
7819                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7820                }
7821                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7822                    mLastAddedTaskActivity = null;
7823                }
7824                ActivityInfo ainfo = mLastAddedTaskActivity;
7825                if (ainfo == null) {
7826                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7827                            comp, 0, UserHandle.getUserId(callingUid));
7828                    if (ainfo.applicationInfo.uid != callingUid) {
7829                        throw new SecurityException(
7830                                "Can't add task for another application: target uid="
7831                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7832                    }
7833                }
7834
7835                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7836                        intent, description);
7837
7838                int trimIdx = trimRecentsForTask(task, false);
7839                if (trimIdx >= 0) {
7840                    // If this would have caused a trim, then we'll abort because that
7841                    // means it would be added at the end of the list but then just removed.
7842                    return -1;
7843                }
7844
7845                final int N = mRecentTasks.size();
7846                if (N >= (MAX_RECENT_TASKS-1)) {
7847                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7848                    tr.disposeThumbnail();
7849                    tr.closeRecentsChain();
7850                }
7851
7852                mRecentTasks.add(task);
7853                r.task.stack.addTask(task, false, false);
7854
7855                task.setLastThumbnail(thumbnail);
7856                task.freeLastThumbnail();
7857
7858                return task.taskId;
7859            }
7860        } finally {
7861            Binder.restoreCallingIdentity(callingIdent);
7862        }
7863    }
7864
7865    @Override
7866    public Point getAppTaskThumbnailSize() {
7867        synchronized (this) {
7868            return new Point(mThumbnailWidth,  mThumbnailHeight);
7869        }
7870    }
7871
7872    @Override
7873    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7874        synchronized (this) {
7875            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7876            if (r != null) {
7877                r.taskDescription = td;
7878                r.task.updateTaskDescription();
7879            }
7880        }
7881    }
7882
7883    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7884        if (!pr.killedByAm) {
7885            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7886            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7887                    pr.processName, pr.setAdj, reason);
7888            pr.killedByAm = true;
7889            Process.killProcessQuiet(pr.pid);
7890            Process.killProcessGroup(pr.info.uid, pr.pid);
7891        }
7892    }
7893
7894    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7895        tr.disposeThumbnail();
7896        mRecentTasks.remove(tr);
7897        tr.closeRecentsChain();
7898        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7899        Intent baseIntent = new Intent(
7900                tr.intent != null ? tr.intent : tr.affinityIntent);
7901        ComponentName component = baseIntent.getComponent();
7902        if (component == null) {
7903            Slog.w(TAG, "Now component for base intent of task: " + tr);
7904            return;
7905        }
7906
7907        // Find any running services associated with this app.
7908        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7909
7910        if (killProcesses) {
7911            // Find any running processes associated with this app.
7912            final String pkg = component.getPackageName();
7913            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7914            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7915            for (int i=0; i<pmap.size(); i++) {
7916                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7917                for (int j=0; j<uids.size(); j++) {
7918                    ProcessRecord proc = uids.valueAt(j);
7919                    if (proc.userId != tr.userId) {
7920                        continue;
7921                    }
7922                    if (!proc.pkgList.containsKey(pkg)) {
7923                        continue;
7924                    }
7925                    procs.add(proc);
7926                }
7927            }
7928
7929            // Kill the running processes.
7930            for (int i=0; i<procs.size(); i++) {
7931                ProcessRecord pr = procs.get(i);
7932                if (pr == mHomeProcess) {
7933                    // Don't kill the home process along with tasks from the same package.
7934                    continue;
7935                }
7936                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7937                    killUnneededProcessLocked(pr, "remove task");
7938                } else {
7939                    pr.waitingToKill = "remove task";
7940                }
7941            }
7942        }
7943    }
7944
7945    /**
7946     * Removes the task with the specified task id.
7947     *
7948     * @param taskId Identifier of the task to be removed.
7949     * @param flags Additional operational flags.  May be 0 or
7950     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7951     * @return Returns true if the given task was found and removed.
7952     */
7953    private boolean removeTaskByIdLocked(int taskId, int flags) {
7954        TaskRecord tr = recentTaskForIdLocked(taskId);
7955        if (tr != null) {
7956            tr.removeTaskActivitiesLocked();
7957            cleanUpRemovedTaskLocked(tr, flags);
7958            if (tr.isPersistable) {
7959                notifyTaskPersisterLocked(null, true);
7960            }
7961            return true;
7962        }
7963        return false;
7964    }
7965
7966    @Override
7967    public boolean removeTask(int taskId, int flags) {
7968        synchronized (this) {
7969            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7970                    "removeTask()");
7971            long ident = Binder.clearCallingIdentity();
7972            try {
7973                return removeTaskByIdLocked(taskId, flags);
7974            } finally {
7975                Binder.restoreCallingIdentity(ident);
7976            }
7977        }
7978    }
7979
7980    /**
7981     * TODO: Add mController hook
7982     */
7983    @Override
7984    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7985        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7986                "moveTaskToFront()");
7987
7988        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7989        synchronized(this) {
7990            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7991                    Binder.getCallingUid(), "Task to front")) {
7992                ActivityOptions.abort(options);
7993                return;
7994            }
7995            final long origId = Binder.clearCallingIdentity();
7996            try {
7997                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7998                if (task == null) {
7999                    return;
8000                }
8001                if (mStackSupervisor.isLockTaskModeViolation(task)) {
8002                    mStackSupervisor.showLockTaskToast();
8003                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8004                    return;
8005                }
8006                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8007                if (prev != null && prev.isRecentsActivity()) {
8008                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8009                }
8010                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8011            } finally {
8012                Binder.restoreCallingIdentity(origId);
8013            }
8014            ActivityOptions.abort(options);
8015        }
8016    }
8017
8018    @Override
8019    public void moveTaskToBack(int taskId) {
8020        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8021                "moveTaskToBack()");
8022
8023        synchronized(this) {
8024            TaskRecord tr = recentTaskForIdLocked(taskId);
8025            if (tr != null) {
8026                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8027                ActivityStack stack = tr.stack;
8028                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8029                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8030                            Binder.getCallingUid(), "Task to back")) {
8031                        return;
8032                    }
8033                }
8034                final long origId = Binder.clearCallingIdentity();
8035                try {
8036                    stack.moveTaskToBackLocked(taskId, null);
8037                } finally {
8038                    Binder.restoreCallingIdentity(origId);
8039                }
8040            }
8041        }
8042    }
8043
8044    /**
8045     * Moves an activity, and all of the other activities within the same task, to the bottom
8046     * of the history stack.  The activity's order within the task is unchanged.
8047     *
8048     * @param token A reference to the activity we wish to move
8049     * @param nonRoot If false then this only works if the activity is the root
8050     *                of a task; if true it will work for any activity in a task.
8051     * @return Returns true if the move completed, false if not.
8052     */
8053    @Override
8054    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8055        enforceNotIsolatedCaller("moveActivityTaskToBack");
8056        synchronized(this) {
8057            final long origId = Binder.clearCallingIdentity();
8058            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8059            if (taskId >= 0) {
8060                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8061            }
8062            Binder.restoreCallingIdentity(origId);
8063        }
8064        return false;
8065    }
8066
8067    @Override
8068    public void moveTaskBackwards(int task) {
8069        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8070                "moveTaskBackwards()");
8071
8072        synchronized(this) {
8073            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8074                    Binder.getCallingUid(), "Task backwards")) {
8075                return;
8076            }
8077            final long origId = Binder.clearCallingIdentity();
8078            moveTaskBackwardsLocked(task);
8079            Binder.restoreCallingIdentity(origId);
8080        }
8081    }
8082
8083    private final void moveTaskBackwardsLocked(int task) {
8084        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8085    }
8086
8087    @Override
8088    public IBinder getHomeActivityToken() throws RemoteException {
8089        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8090                "getHomeActivityToken()");
8091        synchronized (this) {
8092            return mStackSupervisor.getHomeActivityToken();
8093        }
8094    }
8095
8096    @Override
8097    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8098            IActivityContainerCallback callback) throws RemoteException {
8099        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8100                "createActivityContainer()");
8101        synchronized (this) {
8102            if (parentActivityToken == null) {
8103                throw new IllegalArgumentException("parent token must not be null");
8104            }
8105            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8106            if (r == null) {
8107                return null;
8108            }
8109            if (callback == null) {
8110                throw new IllegalArgumentException("callback must not be null");
8111            }
8112            return mStackSupervisor.createActivityContainer(r, callback);
8113        }
8114    }
8115
8116    @Override
8117    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8118        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8119                "deleteActivityContainer()");
8120        synchronized (this) {
8121            mStackSupervisor.deleteActivityContainer(container);
8122        }
8123    }
8124
8125    @Override
8126    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8127            throws RemoteException {
8128        synchronized (this) {
8129            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8130            if (stack != null) {
8131                return stack.mActivityContainer;
8132            }
8133            return null;
8134        }
8135    }
8136
8137    @Override
8138    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8139        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8140                "moveTaskToStack()");
8141        if (stackId == HOME_STACK_ID) {
8142            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8143                    new RuntimeException("here").fillInStackTrace());
8144        }
8145        synchronized (this) {
8146            long ident = Binder.clearCallingIdentity();
8147            try {
8148                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8149                        + stackId + " toTop=" + toTop);
8150                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8151            } finally {
8152                Binder.restoreCallingIdentity(ident);
8153            }
8154        }
8155    }
8156
8157    @Override
8158    public void resizeStack(int stackBoxId, Rect bounds) {
8159        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8160                "resizeStackBox()");
8161        long ident = Binder.clearCallingIdentity();
8162        try {
8163            mWindowManager.resizeStack(stackBoxId, bounds);
8164        } finally {
8165            Binder.restoreCallingIdentity(ident);
8166        }
8167    }
8168
8169    @Override
8170    public List<StackInfo> getAllStackInfos() {
8171        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8172                "getAllStackInfos()");
8173        long ident = Binder.clearCallingIdentity();
8174        try {
8175            synchronized (this) {
8176                return mStackSupervisor.getAllStackInfosLocked();
8177            }
8178        } finally {
8179            Binder.restoreCallingIdentity(ident);
8180        }
8181    }
8182
8183    @Override
8184    public StackInfo getStackInfo(int stackId) {
8185        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8186                "getStackInfo()");
8187        long ident = Binder.clearCallingIdentity();
8188        try {
8189            synchronized (this) {
8190                return mStackSupervisor.getStackInfoLocked(stackId);
8191            }
8192        } finally {
8193            Binder.restoreCallingIdentity(ident);
8194        }
8195    }
8196
8197    @Override
8198    public boolean isInHomeStack(int taskId) {
8199        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8200                "getStackInfo()");
8201        long ident = Binder.clearCallingIdentity();
8202        try {
8203            synchronized (this) {
8204                TaskRecord tr = recentTaskForIdLocked(taskId);
8205                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8206            }
8207        } finally {
8208            Binder.restoreCallingIdentity(ident);
8209        }
8210    }
8211
8212    @Override
8213    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8214        synchronized(this) {
8215            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8216        }
8217    }
8218
8219    private boolean isLockTaskAuthorized(String pkg) {
8220        final DevicePolicyManager dpm = (DevicePolicyManager)
8221                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8222        try {
8223            int uid = mContext.getPackageManager().getPackageUid(pkg,
8224                    Binder.getCallingUserHandle().getIdentifier());
8225            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8226        } catch (NameNotFoundException e) {
8227            return false;
8228        }
8229    }
8230
8231    void startLockTaskMode(TaskRecord task) {
8232        final String pkg;
8233        synchronized (this) {
8234            pkg = task.intent.getComponent().getPackageName();
8235        }
8236        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8237        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8238            final TaskRecord taskRecord = task;
8239            mHandler.post(new Runnable() {
8240                @Override
8241                public void run() {
8242                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8243                }
8244            });
8245            return;
8246        }
8247        long ident = Binder.clearCallingIdentity();
8248        try {
8249            synchronized (this) {
8250                // Since we lost lock on task, make sure it is still there.
8251                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8252                if (task != null) {
8253                    if (!isSystemInitiated
8254                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8255                        throw new IllegalArgumentException("Invalid task, not in foreground");
8256                    }
8257                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8258                }
8259            }
8260        } finally {
8261            Binder.restoreCallingIdentity(ident);
8262        }
8263    }
8264
8265    @Override
8266    public void startLockTaskMode(int taskId) {
8267        final TaskRecord task;
8268        long ident = Binder.clearCallingIdentity();
8269        try {
8270            synchronized (this) {
8271                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8272            }
8273        } finally {
8274            Binder.restoreCallingIdentity(ident);
8275        }
8276        if (task != null) {
8277            startLockTaskMode(task);
8278        }
8279    }
8280
8281    @Override
8282    public void startLockTaskMode(IBinder token) {
8283        final TaskRecord task;
8284        long ident = Binder.clearCallingIdentity();
8285        try {
8286            synchronized (this) {
8287                final ActivityRecord r = ActivityRecord.forToken(token);
8288                if (r == null) {
8289                    return;
8290                }
8291                task = r.task;
8292            }
8293        } finally {
8294            Binder.restoreCallingIdentity(ident);
8295        }
8296        if (task != null) {
8297            startLockTaskMode(task);
8298        }
8299    }
8300
8301    @Override
8302    public void startLockTaskModeOnCurrent() throws RemoteException {
8303        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8304        ActivityRecord r = null;
8305        synchronized (this) {
8306            r = mStackSupervisor.topRunningActivityLocked();
8307        }
8308        startLockTaskMode(r.task);
8309    }
8310
8311    @Override
8312    public void stopLockTaskMode() {
8313        // Verify that the user matches the package of the intent for the TaskRecord
8314        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8315        // and stopLockTaskMode.
8316        final int callingUid = Binder.getCallingUid();
8317        if (callingUid != Process.SYSTEM_UID) {
8318            try {
8319                String pkg =
8320                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8321                int uid = mContext.getPackageManager().getPackageUid(pkg,
8322                        Binder.getCallingUserHandle().getIdentifier());
8323                if (uid != callingUid) {
8324                    throw new SecurityException("Invalid uid, expected " + uid);
8325                }
8326            } catch (NameNotFoundException e) {
8327                Log.d(TAG, "stopLockTaskMode " + e);
8328                return;
8329            }
8330        }
8331        long ident = Binder.clearCallingIdentity();
8332        try {
8333            Log.d(TAG, "stopLockTaskMode");
8334            // Stop lock task
8335            synchronized (this) {
8336                mStackSupervisor.setLockTaskModeLocked(null, false);
8337            }
8338        } finally {
8339            Binder.restoreCallingIdentity(ident);
8340        }
8341    }
8342
8343    @Override
8344    public void stopLockTaskModeOnCurrent() throws RemoteException {
8345        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8346        long ident = Binder.clearCallingIdentity();
8347        try {
8348            stopLockTaskMode();
8349        } finally {
8350            Binder.restoreCallingIdentity(ident);
8351        }
8352    }
8353
8354    @Override
8355    public boolean isInLockTaskMode() {
8356        synchronized (this) {
8357            return mStackSupervisor.isInLockTaskMode();
8358        }
8359    }
8360
8361    // =========================================================
8362    // CONTENT PROVIDERS
8363    // =========================================================
8364
8365    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8366        List<ProviderInfo> providers = null;
8367        try {
8368            providers = AppGlobals.getPackageManager().
8369                queryContentProviders(app.processName, app.uid,
8370                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8371        } catch (RemoteException ex) {
8372        }
8373        if (DEBUG_MU)
8374            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8375        int userId = app.userId;
8376        if (providers != null) {
8377            int N = providers.size();
8378            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8379            for (int i=0; i<N; i++) {
8380                ProviderInfo cpi =
8381                    (ProviderInfo)providers.get(i);
8382                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8383                        cpi.name, cpi.flags);
8384                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8385                    // This is a singleton provider, but a user besides the
8386                    // default user is asking to initialize a process it runs
8387                    // in...  well, no, it doesn't actually run in this process,
8388                    // it runs in the process of the default user.  Get rid of it.
8389                    providers.remove(i);
8390                    N--;
8391                    i--;
8392                    continue;
8393                }
8394
8395                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8396                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8397                if (cpr == null) {
8398                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8399                    mProviderMap.putProviderByClass(comp, cpr);
8400                }
8401                if (DEBUG_MU)
8402                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8403                app.pubProviders.put(cpi.name, cpr);
8404                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8405                    // Don't add this if it is a platform component that is marked
8406                    // to run in multiple processes, because this is actually
8407                    // part of the framework so doesn't make sense to track as a
8408                    // separate apk in the process.
8409                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8410                            mProcessStats);
8411                }
8412                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8413            }
8414        }
8415        return providers;
8416    }
8417
8418    /**
8419     * Check if {@link ProcessRecord} has a possible chance at accessing the
8420     * given {@link ProviderInfo}. Final permission checking is always done
8421     * in {@link ContentProvider}.
8422     */
8423    private final String checkContentProviderPermissionLocked(
8424            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8425        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8426        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8427        boolean checkedGrants = false;
8428        if (checkUser) {
8429            // Looking for cross-user grants before enforcing the typical cross-users permissions
8430            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8431            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8432                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8433                    return null;
8434                }
8435                checkedGrants = true;
8436            }
8437            userId = handleIncomingUser(callingPid, callingUid, userId,
8438                    false, ALLOW_NON_FULL,
8439                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8440            if (userId != tmpTargetUserId) {
8441                // When we actually went to determine the final targer user ID, this ended
8442                // up different than our initial check for the authority.  This is because
8443                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8444                // SELF.  So we need to re-check the grants again.
8445                checkedGrants = false;
8446            }
8447        }
8448        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8449                cpi.applicationInfo.uid, cpi.exported)
8450                == PackageManager.PERMISSION_GRANTED) {
8451            return null;
8452        }
8453        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8454                cpi.applicationInfo.uid, cpi.exported)
8455                == PackageManager.PERMISSION_GRANTED) {
8456            return null;
8457        }
8458
8459        PathPermission[] pps = cpi.pathPermissions;
8460        if (pps != null) {
8461            int i = pps.length;
8462            while (i > 0) {
8463                i--;
8464                PathPermission pp = pps[i];
8465                String pprperm = pp.getReadPermission();
8466                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8467                        cpi.applicationInfo.uid, cpi.exported)
8468                        == PackageManager.PERMISSION_GRANTED) {
8469                    return null;
8470                }
8471                String ppwperm = pp.getWritePermission();
8472                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8473                        cpi.applicationInfo.uid, cpi.exported)
8474                        == PackageManager.PERMISSION_GRANTED) {
8475                    return null;
8476                }
8477            }
8478        }
8479        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8480            return null;
8481        }
8482
8483        String msg;
8484        if (!cpi.exported) {
8485            msg = "Permission Denial: opening provider " + cpi.name
8486                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8487                    + ", uid=" + callingUid + ") that is not exported from uid "
8488                    + cpi.applicationInfo.uid;
8489        } else {
8490            msg = "Permission Denial: opening provider " + cpi.name
8491                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8492                    + ", uid=" + callingUid + ") requires "
8493                    + cpi.readPermission + " or " + cpi.writePermission;
8494        }
8495        Slog.w(TAG, msg);
8496        return msg;
8497    }
8498
8499    /**
8500     * Returns if the ContentProvider has granted a uri to callingUid
8501     */
8502    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8503        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8504        if (perms != null) {
8505            for (int i=perms.size()-1; i>=0; i--) {
8506                GrantUri grantUri = perms.keyAt(i);
8507                if (grantUri.sourceUserId == userId || !checkUser) {
8508                    if (matchesProvider(grantUri.uri, cpi)) {
8509                        return true;
8510                    }
8511                }
8512            }
8513        }
8514        return false;
8515    }
8516
8517    /**
8518     * Returns true if the uri authority is one of the authorities specified in the provider.
8519     */
8520    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8521        String uriAuth = uri.getAuthority();
8522        String cpiAuth = cpi.authority;
8523        if (cpiAuth.indexOf(';') == -1) {
8524            return cpiAuth.equals(uriAuth);
8525        }
8526        String[] cpiAuths = cpiAuth.split(";");
8527        int length = cpiAuths.length;
8528        for (int i = 0; i < length; i++) {
8529            if (cpiAuths[i].equals(uriAuth)) return true;
8530        }
8531        return false;
8532    }
8533
8534    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8535            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8536        if (r != null) {
8537            for (int i=0; i<r.conProviders.size(); i++) {
8538                ContentProviderConnection conn = r.conProviders.get(i);
8539                if (conn.provider == cpr) {
8540                    if (DEBUG_PROVIDER) Slog.v(TAG,
8541                            "Adding provider requested by "
8542                            + r.processName + " from process "
8543                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8544                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8545                    if (stable) {
8546                        conn.stableCount++;
8547                        conn.numStableIncs++;
8548                    } else {
8549                        conn.unstableCount++;
8550                        conn.numUnstableIncs++;
8551                    }
8552                    return conn;
8553                }
8554            }
8555            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8556            if (stable) {
8557                conn.stableCount = 1;
8558                conn.numStableIncs = 1;
8559            } else {
8560                conn.unstableCount = 1;
8561                conn.numUnstableIncs = 1;
8562            }
8563            cpr.connections.add(conn);
8564            r.conProviders.add(conn);
8565            return conn;
8566        }
8567        cpr.addExternalProcessHandleLocked(externalProcessToken);
8568        return null;
8569    }
8570
8571    boolean decProviderCountLocked(ContentProviderConnection conn,
8572            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8573        if (conn != null) {
8574            cpr = conn.provider;
8575            if (DEBUG_PROVIDER) Slog.v(TAG,
8576                    "Removing provider requested by "
8577                    + conn.client.processName + " from process "
8578                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8579                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8580            if (stable) {
8581                conn.stableCount--;
8582            } else {
8583                conn.unstableCount--;
8584            }
8585            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8586                cpr.connections.remove(conn);
8587                conn.client.conProviders.remove(conn);
8588                return true;
8589            }
8590            return false;
8591        }
8592        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8593        return false;
8594    }
8595
8596    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8597            String name, IBinder token, boolean stable, int userId) {
8598        ContentProviderRecord cpr;
8599        ContentProviderConnection conn = null;
8600        ProviderInfo cpi = null;
8601
8602        synchronized(this) {
8603            ProcessRecord r = null;
8604            if (caller != null) {
8605                r = getRecordForAppLocked(caller);
8606                if (r == null) {
8607                    throw new SecurityException(
8608                            "Unable to find app for caller " + caller
8609                          + " (pid=" + Binder.getCallingPid()
8610                          + ") when getting content provider " + name);
8611                }
8612            }
8613
8614            boolean checkCrossUser = true;
8615
8616            // First check if this content provider has been published...
8617            cpr = mProviderMap.getProviderByName(name, userId);
8618            // If that didn't work, check if it exists for user 0 and then
8619            // verify that it's a singleton provider before using it.
8620            if (cpr == null && userId != UserHandle.USER_OWNER) {
8621                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8622                if (cpr != null) {
8623                    cpi = cpr.info;
8624                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8625                            cpi.name, cpi.flags)
8626                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8627                        userId = UserHandle.USER_OWNER;
8628                        checkCrossUser = false;
8629                    } else {
8630                        cpr = null;
8631                        cpi = null;
8632                    }
8633                }
8634            }
8635
8636            boolean providerRunning = cpr != null;
8637            if (providerRunning) {
8638                cpi = cpr.info;
8639                String msg;
8640                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8641                        != null) {
8642                    throw new SecurityException(msg);
8643                }
8644
8645                if (r != null && cpr.canRunHere(r)) {
8646                    // This provider has been published or is in the process
8647                    // of being published...  but it is also allowed to run
8648                    // in the caller's process, so don't make a connection
8649                    // and just let the caller instantiate its own instance.
8650                    ContentProviderHolder holder = cpr.newHolder(null);
8651                    // don't give caller the provider object, it needs
8652                    // to make its own.
8653                    holder.provider = null;
8654                    return holder;
8655                }
8656
8657                final long origId = Binder.clearCallingIdentity();
8658
8659                // In this case the provider instance already exists, so we can
8660                // return it right away.
8661                conn = incProviderCountLocked(r, cpr, token, stable);
8662                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8663                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8664                        // If this is a perceptible app accessing the provider,
8665                        // make sure to count it as being accessed and thus
8666                        // back up on the LRU list.  This is good because
8667                        // content providers are often expensive to start.
8668                        updateLruProcessLocked(cpr.proc, false, null);
8669                    }
8670                }
8671
8672                if (cpr.proc != null) {
8673                    if (false) {
8674                        if (cpr.name.flattenToShortString().equals(
8675                                "com.android.providers.calendar/.CalendarProvider2")) {
8676                            Slog.v(TAG, "****************** KILLING "
8677                                + cpr.name.flattenToShortString());
8678                            Process.killProcess(cpr.proc.pid);
8679                        }
8680                    }
8681                    boolean success = updateOomAdjLocked(cpr.proc);
8682                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8683                    // NOTE: there is still a race here where a signal could be
8684                    // pending on the process even though we managed to update its
8685                    // adj level.  Not sure what to do about this, but at least
8686                    // the race is now smaller.
8687                    if (!success) {
8688                        // Uh oh...  it looks like the provider's process
8689                        // has been killed on us.  We need to wait for a new
8690                        // process to be started, and make sure its death
8691                        // doesn't kill our process.
8692                        Slog.i(TAG,
8693                                "Existing provider " + cpr.name.flattenToShortString()
8694                                + " is crashing; detaching " + r);
8695                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8696                        appDiedLocked(cpr.proc);
8697                        if (!lastRef) {
8698                            // This wasn't the last ref our process had on
8699                            // the provider...  we have now been killed, bail.
8700                            return null;
8701                        }
8702                        providerRunning = false;
8703                        conn = null;
8704                    }
8705                }
8706
8707                Binder.restoreCallingIdentity(origId);
8708            }
8709
8710            boolean singleton;
8711            if (!providerRunning) {
8712                try {
8713                    cpi = AppGlobals.getPackageManager().
8714                        resolveContentProvider(name,
8715                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8716                } catch (RemoteException ex) {
8717                }
8718                if (cpi == null) {
8719                    return null;
8720                }
8721                // If the provider is a singleton AND
8722                // (it's a call within the same user || the provider is a
8723                // privileged app)
8724                // Then allow connecting to the singleton provider
8725                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8726                        cpi.name, cpi.flags)
8727                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8728                if (singleton) {
8729                    userId = UserHandle.USER_OWNER;
8730                }
8731                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8732
8733                String msg;
8734                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8735                        != null) {
8736                    throw new SecurityException(msg);
8737                }
8738
8739                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8740                        && !cpi.processName.equals("system")) {
8741                    // If this content provider does not run in the system
8742                    // process, and the system is not yet ready to run other
8743                    // processes, then fail fast instead of hanging.
8744                    throw new IllegalArgumentException(
8745                            "Attempt to launch content provider before system ready");
8746                }
8747
8748                // Make sure that the user who owns this provider is started.  If not,
8749                // we don't want to allow it to run.
8750                if (mStartedUsers.get(userId) == null) {
8751                    Slog.w(TAG, "Unable to launch app "
8752                            + cpi.applicationInfo.packageName + "/"
8753                            + cpi.applicationInfo.uid + " for provider "
8754                            + name + ": user " + userId + " is stopped");
8755                    return null;
8756                }
8757
8758                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8759                cpr = mProviderMap.getProviderByClass(comp, userId);
8760                final boolean firstClass = cpr == null;
8761                if (firstClass) {
8762                    try {
8763                        ApplicationInfo ai =
8764                            AppGlobals.getPackageManager().
8765                                getApplicationInfo(
8766                                        cpi.applicationInfo.packageName,
8767                                        STOCK_PM_FLAGS, userId);
8768                        if (ai == null) {
8769                            Slog.w(TAG, "No package info for content provider "
8770                                    + cpi.name);
8771                            return null;
8772                        }
8773                        ai = getAppInfoForUser(ai, userId);
8774                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8775                    } catch (RemoteException ex) {
8776                        // pm is in same process, this will never happen.
8777                    }
8778                }
8779
8780                if (r != null && cpr.canRunHere(r)) {
8781                    // If this is a multiprocess provider, then just return its
8782                    // info and allow the caller to instantiate it.  Only do
8783                    // this if the provider is the same user as the caller's
8784                    // process, or can run as root (so can be in any process).
8785                    return cpr.newHolder(null);
8786                }
8787
8788                if (DEBUG_PROVIDER) {
8789                    RuntimeException e = new RuntimeException("here");
8790                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8791                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8792                }
8793
8794                // This is single process, and our app is now connecting to it.
8795                // See if we are already in the process of launching this
8796                // provider.
8797                final int N = mLaunchingProviders.size();
8798                int i;
8799                for (i=0; i<N; i++) {
8800                    if (mLaunchingProviders.get(i) == cpr) {
8801                        break;
8802                    }
8803                }
8804
8805                // If the provider is not already being launched, then get it
8806                // started.
8807                if (i >= N) {
8808                    final long origId = Binder.clearCallingIdentity();
8809
8810                    try {
8811                        // Content provider is now in use, its package can't be stopped.
8812                        try {
8813                            AppGlobals.getPackageManager().setPackageStoppedState(
8814                                    cpr.appInfo.packageName, false, userId);
8815                        } catch (RemoteException e) {
8816                        } catch (IllegalArgumentException e) {
8817                            Slog.w(TAG, "Failed trying to unstop package "
8818                                    + cpr.appInfo.packageName + ": " + e);
8819                        }
8820
8821                        // Use existing process if already started
8822                        ProcessRecord proc = getProcessRecordLocked(
8823                                cpi.processName, cpr.appInfo.uid, false);
8824                        if (proc != null && proc.thread != null) {
8825                            if (DEBUG_PROVIDER) {
8826                                Slog.d(TAG, "Installing in existing process " + proc);
8827                            }
8828                            proc.pubProviders.put(cpi.name, cpr);
8829                            try {
8830                                proc.thread.scheduleInstallProvider(cpi);
8831                            } catch (RemoteException e) {
8832                            }
8833                        } else {
8834                            proc = startProcessLocked(cpi.processName,
8835                                    cpr.appInfo, false, 0, "content provider",
8836                                    new ComponentName(cpi.applicationInfo.packageName,
8837                                            cpi.name), false, false, false);
8838                            if (proc == null) {
8839                                Slog.w(TAG, "Unable to launch app "
8840                                        + cpi.applicationInfo.packageName + "/"
8841                                        + cpi.applicationInfo.uid + " for provider "
8842                                        + name + ": process is bad");
8843                                return null;
8844                            }
8845                        }
8846                        cpr.launchingApp = proc;
8847                        mLaunchingProviders.add(cpr);
8848                    } finally {
8849                        Binder.restoreCallingIdentity(origId);
8850                    }
8851                }
8852
8853                // Make sure the provider is published (the same provider class
8854                // may be published under multiple names).
8855                if (firstClass) {
8856                    mProviderMap.putProviderByClass(comp, cpr);
8857                }
8858
8859                mProviderMap.putProviderByName(name, cpr);
8860                conn = incProviderCountLocked(r, cpr, token, stable);
8861                if (conn != null) {
8862                    conn.waiting = true;
8863                }
8864            }
8865        }
8866
8867        // Wait for the provider to be published...
8868        synchronized (cpr) {
8869            while (cpr.provider == null) {
8870                if (cpr.launchingApp == null) {
8871                    Slog.w(TAG, "Unable to launch app "
8872                            + cpi.applicationInfo.packageName + "/"
8873                            + cpi.applicationInfo.uid + " for provider "
8874                            + name + ": launching app became null");
8875                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8876                            UserHandle.getUserId(cpi.applicationInfo.uid),
8877                            cpi.applicationInfo.packageName,
8878                            cpi.applicationInfo.uid, name);
8879                    return null;
8880                }
8881                try {
8882                    if (DEBUG_MU) {
8883                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8884                                + cpr.launchingApp);
8885                    }
8886                    if (conn != null) {
8887                        conn.waiting = true;
8888                    }
8889                    cpr.wait();
8890                } catch (InterruptedException ex) {
8891                } finally {
8892                    if (conn != null) {
8893                        conn.waiting = false;
8894                    }
8895                }
8896            }
8897        }
8898        return cpr != null ? cpr.newHolder(conn) : null;
8899    }
8900
8901    @Override
8902    public final ContentProviderHolder getContentProvider(
8903            IApplicationThread caller, String name, int userId, boolean stable) {
8904        enforceNotIsolatedCaller("getContentProvider");
8905        if (caller == null) {
8906            String msg = "null IApplicationThread when getting content provider "
8907                    + name;
8908            Slog.w(TAG, msg);
8909            throw new SecurityException(msg);
8910        }
8911        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8912        // with cross-user grant.
8913        return getContentProviderImpl(caller, name, null, stable, userId);
8914    }
8915
8916    public ContentProviderHolder getContentProviderExternal(
8917            String name, int userId, IBinder token) {
8918        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8919            "Do not have permission in call getContentProviderExternal()");
8920        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8921                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8922        return getContentProviderExternalUnchecked(name, token, userId);
8923    }
8924
8925    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8926            IBinder token, int userId) {
8927        return getContentProviderImpl(null, name, token, true, userId);
8928    }
8929
8930    /**
8931     * Drop a content provider from a ProcessRecord's bookkeeping
8932     */
8933    public void removeContentProvider(IBinder connection, boolean stable) {
8934        enforceNotIsolatedCaller("removeContentProvider");
8935        long ident = Binder.clearCallingIdentity();
8936        try {
8937            synchronized (this) {
8938                ContentProviderConnection conn;
8939                try {
8940                    conn = (ContentProviderConnection)connection;
8941                } catch (ClassCastException e) {
8942                    String msg ="removeContentProvider: " + connection
8943                            + " not a ContentProviderConnection";
8944                    Slog.w(TAG, msg);
8945                    throw new IllegalArgumentException(msg);
8946                }
8947                if (conn == null) {
8948                    throw new NullPointerException("connection is null");
8949                }
8950                if (decProviderCountLocked(conn, null, null, stable)) {
8951                    updateOomAdjLocked();
8952                }
8953            }
8954        } finally {
8955            Binder.restoreCallingIdentity(ident);
8956        }
8957    }
8958
8959    public void removeContentProviderExternal(String name, IBinder token) {
8960        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8961            "Do not have permission in call removeContentProviderExternal()");
8962        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8963    }
8964
8965    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8966        synchronized (this) {
8967            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8968            if(cpr == null) {
8969                //remove from mProvidersByClass
8970                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8971                return;
8972            }
8973
8974            //update content provider record entry info
8975            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8976            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8977            if (localCpr.hasExternalProcessHandles()) {
8978                if (localCpr.removeExternalProcessHandleLocked(token)) {
8979                    updateOomAdjLocked();
8980                } else {
8981                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8982                            + " with no external reference for token: "
8983                            + token + ".");
8984                }
8985            } else {
8986                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8987                        + " with no external references.");
8988            }
8989        }
8990    }
8991
8992    public final void publishContentProviders(IApplicationThread caller,
8993            List<ContentProviderHolder> providers) {
8994        if (providers == null) {
8995            return;
8996        }
8997
8998        enforceNotIsolatedCaller("publishContentProviders");
8999        synchronized (this) {
9000            final ProcessRecord r = getRecordForAppLocked(caller);
9001            if (DEBUG_MU)
9002                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9003            if (r == null) {
9004                throw new SecurityException(
9005                        "Unable to find app for caller " + caller
9006                      + " (pid=" + Binder.getCallingPid()
9007                      + ") when publishing content providers");
9008            }
9009
9010            final long origId = Binder.clearCallingIdentity();
9011
9012            final int N = providers.size();
9013            for (int i=0; i<N; i++) {
9014                ContentProviderHolder src = providers.get(i);
9015                if (src == null || src.info == null || src.provider == null) {
9016                    continue;
9017                }
9018                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9019                if (DEBUG_MU)
9020                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9021                if (dst != null) {
9022                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9023                    mProviderMap.putProviderByClass(comp, dst);
9024                    String names[] = dst.info.authority.split(";");
9025                    for (int j = 0; j < names.length; j++) {
9026                        mProviderMap.putProviderByName(names[j], dst);
9027                    }
9028
9029                    int NL = mLaunchingProviders.size();
9030                    int j;
9031                    for (j=0; j<NL; j++) {
9032                        if (mLaunchingProviders.get(j) == dst) {
9033                            mLaunchingProviders.remove(j);
9034                            j--;
9035                            NL--;
9036                        }
9037                    }
9038                    synchronized (dst) {
9039                        dst.provider = src.provider;
9040                        dst.proc = r;
9041                        dst.notifyAll();
9042                    }
9043                    updateOomAdjLocked(r);
9044                }
9045            }
9046
9047            Binder.restoreCallingIdentity(origId);
9048        }
9049    }
9050
9051    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9052        ContentProviderConnection conn;
9053        try {
9054            conn = (ContentProviderConnection)connection;
9055        } catch (ClassCastException e) {
9056            String msg ="refContentProvider: " + connection
9057                    + " not a ContentProviderConnection";
9058            Slog.w(TAG, msg);
9059            throw new IllegalArgumentException(msg);
9060        }
9061        if (conn == null) {
9062            throw new NullPointerException("connection is null");
9063        }
9064
9065        synchronized (this) {
9066            if (stable > 0) {
9067                conn.numStableIncs += stable;
9068            }
9069            stable = conn.stableCount + stable;
9070            if (stable < 0) {
9071                throw new IllegalStateException("stableCount < 0: " + stable);
9072            }
9073
9074            if (unstable > 0) {
9075                conn.numUnstableIncs += unstable;
9076            }
9077            unstable = conn.unstableCount + unstable;
9078            if (unstable < 0) {
9079                throw new IllegalStateException("unstableCount < 0: " + unstable);
9080            }
9081
9082            if ((stable+unstable) <= 0) {
9083                throw new IllegalStateException("ref counts can't go to zero here: stable="
9084                        + stable + " unstable=" + unstable);
9085            }
9086            conn.stableCount = stable;
9087            conn.unstableCount = unstable;
9088            return !conn.dead;
9089        }
9090    }
9091
9092    public void unstableProviderDied(IBinder connection) {
9093        ContentProviderConnection conn;
9094        try {
9095            conn = (ContentProviderConnection)connection;
9096        } catch (ClassCastException e) {
9097            String msg ="refContentProvider: " + connection
9098                    + " not a ContentProviderConnection";
9099            Slog.w(TAG, msg);
9100            throw new IllegalArgumentException(msg);
9101        }
9102        if (conn == null) {
9103            throw new NullPointerException("connection is null");
9104        }
9105
9106        // Safely retrieve the content provider associated with the connection.
9107        IContentProvider provider;
9108        synchronized (this) {
9109            provider = conn.provider.provider;
9110        }
9111
9112        if (provider == null) {
9113            // Um, yeah, we're way ahead of you.
9114            return;
9115        }
9116
9117        // Make sure the caller is being honest with us.
9118        if (provider.asBinder().pingBinder()) {
9119            // Er, no, still looks good to us.
9120            synchronized (this) {
9121                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9122                        + " says " + conn + " died, but we don't agree");
9123                return;
9124            }
9125        }
9126
9127        // Well look at that!  It's dead!
9128        synchronized (this) {
9129            if (conn.provider.provider != provider) {
9130                // But something changed...  good enough.
9131                return;
9132            }
9133
9134            ProcessRecord proc = conn.provider.proc;
9135            if (proc == null || proc.thread == null) {
9136                // Seems like the process is already cleaned up.
9137                return;
9138            }
9139
9140            // As far as we're concerned, this is just like receiving a
9141            // death notification...  just a bit prematurely.
9142            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9143                    + ") early provider death");
9144            final long ident = Binder.clearCallingIdentity();
9145            try {
9146                appDiedLocked(proc);
9147            } finally {
9148                Binder.restoreCallingIdentity(ident);
9149            }
9150        }
9151    }
9152
9153    @Override
9154    public void appNotRespondingViaProvider(IBinder connection) {
9155        enforceCallingPermission(
9156                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9157
9158        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9159        if (conn == null) {
9160            Slog.w(TAG, "ContentProviderConnection is null");
9161            return;
9162        }
9163
9164        final ProcessRecord host = conn.provider.proc;
9165        if (host == null) {
9166            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9167            return;
9168        }
9169
9170        final long token = Binder.clearCallingIdentity();
9171        try {
9172            appNotResponding(host, null, null, false, "ContentProvider not responding");
9173        } finally {
9174            Binder.restoreCallingIdentity(token);
9175        }
9176    }
9177
9178    public final void installSystemProviders() {
9179        List<ProviderInfo> providers;
9180        synchronized (this) {
9181            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9182            providers = generateApplicationProvidersLocked(app);
9183            if (providers != null) {
9184                for (int i=providers.size()-1; i>=0; i--) {
9185                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9186                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9187                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9188                                + ": not system .apk");
9189                        providers.remove(i);
9190                    }
9191                }
9192            }
9193        }
9194        if (providers != null) {
9195            mSystemThread.installSystemProviders(providers);
9196        }
9197
9198        mCoreSettingsObserver = new CoreSettingsObserver(this);
9199
9200        //mUsageStatsService.monitorPackages();
9201    }
9202
9203    /**
9204     * Allows apps to retrieve the MIME type of a URI.
9205     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9206     * users, then it does not need permission to access the ContentProvider.
9207     * Either, it needs cross-user uri grants.
9208     *
9209     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9210     *
9211     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9212     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9213     */
9214    public String getProviderMimeType(Uri uri, int userId) {
9215        enforceNotIsolatedCaller("getProviderMimeType");
9216        final String name = uri.getAuthority();
9217        int callingUid = Binder.getCallingUid();
9218        int callingPid = Binder.getCallingPid();
9219        long ident = 0;
9220        boolean clearedIdentity = false;
9221        userId = unsafeConvertIncomingUser(userId);
9222        if (UserHandle.getUserId(callingUid) != userId) {
9223            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9224                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9225                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9226                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9227                clearedIdentity = true;
9228                ident = Binder.clearCallingIdentity();
9229            }
9230        }
9231        ContentProviderHolder holder = null;
9232        try {
9233            holder = getContentProviderExternalUnchecked(name, null, userId);
9234            if (holder != null) {
9235                return holder.provider.getType(uri);
9236            }
9237        } catch (RemoteException e) {
9238            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9239            return null;
9240        } finally {
9241            // We need to clear the identity to call removeContentProviderExternalUnchecked
9242            if (!clearedIdentity) {
9243                ident = Binder.clearCallingIdentity();
9244            }
9245            try {
9246                if (holder != null) {
9247                    removeContentProviderExternalUnchecked(name, null, userId);
9248                }
9249            } finally {
9250                Binder.restoreCallingIdentity(ident);
9251            }
9252        }
9253
9254        return null;
9255    }
9256
9257    // =========================================================
9258    // GLOBAL MANAGEMENT
9259    // =========================================================
9260
9261    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9262            boolean isolated, int isolatedUid) {
9263        String proc = customProcess != null ? customProcess : info.processName;
9264        BatteryStatsImpl.Uid.Proc ps = null;
9265        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9266        int uid = info.uid;
9267        if (isolated) {
9268            if (isolatedUid == 0) {
9269                int userId = UserHandle.getUserId(uid);
9270                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9271                while (true) {
9272                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9273                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9274                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9275                    }
9276                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9277                    mNextIsolatedProcessUid++;
9278                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9279                        // No process for this uid, use it.
9280                        break;
9281                    }
9282                    stepsLeft--;
9283                    if (stepsLeft <= 0) {
9284                        return null;
9285                    }
9286                }
9287            } else {
9288                // Special case for startIsolatedProcess (internal only), where
9289                // the uid of the isolated process is specified by the caller.
9290                uid = isolatedUid;
9291            }
9292        }
9293        return new ProcessRecord(stats, info, proc, uid);
9294    }
9295
9296    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9297            String abiOverride) {
9298        ProcessRecord app;
9299        if (!isolated) {
9300            app = getProcessRecordLocked(info.processName, info.uid, true);
9301        } else {
9302            app = null;
9303        }
9304
9305        if (app == null) {
9306            app = newProcessRecordLocked(info, null, isolated, 0);
9307            mProcessNames.put(info.processName, app.uid, app);
9308            if (isolated) {
9309                mIsolatedProcesses.put(app.uid, app);
9310            }
9311            updateLruProcessLocked(app, false, null);
9312            updateOomAdjLocked();
9313        }
9314
9315        // This package really, really can not be stopped.
9316        try {
9317            AppGlobals.getPackageManager().setPackageStoppedState(
9318                    info.packageName, false, UserHandle.getUserId(app.uid));
9319        } catch (RemoteException e) {
9320        } catch (IllegalArgumentException e) {
9321            Slog.w(TAG, "Failed trying to unstop package "
9322                    + info.packageName + ": " + e);
9323        }
9324
9325        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9326                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9327            app.persistent = true;
9328            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9329        }
9330        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9331            mPersistentStartingProcesses.add(app);
9332            startProcessLocked(app, "added application", app.processName, abiOverride,
9333                    null /* entryPoint */, null /* entryPointArgs */);
9334        }
9335
9336        return app;
9337    }
9338
9339    public void unhandledBack() {
9340        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9341                "unhandledBack()");
9342
9343        synchronized(this) {
9344            final long origId = Binder.clearCallingIdentity();
9345            try {
9346                getFocusedStack().unhandledBackLocked();
9347            } finally {
9348                Binder.restoreCallingIdentity(origId);
9349            }
9350        }
9351    }
9352
9353    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9354        enforceNotIsolatedCaller("openContentUri");
9355        final int userId = UserHandle.getCallingUserId();
9356        String name = uri.getAuthority();
9357        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9358        ParcelFileDescriptor pfd = null;
9359        if (cph != null) {
9360            // We record the binder invoker's uid in thread-local storage before
9361            // going to the content provider to open the file.  Later, in the code
9362            // that handles all permissions checks, we look for this uid and use
9363            // that rather than the Activity Manager's own uid.  The effect is that
9364            // we do the check against the caller's permissions even though it looks
9365            // to the content provider like the Activity Manager itself is making
9366            // the request.
9367            sCallerIdentity.set(new Identity(
9368                    Binder.getCallingPid(), Binder.getCallingUid()));
9369            try {
9370                pfd = cph.provider.openFile(null, uri, "r", null);
9371            } catch (FileNotFoundException e) {
9372                // do nothing; pfd will be returned null
9373            } finally {
9374                // Ensure that whatever happens, we clean up the identity state
9375                sCallerIdentity.remove();
9376            }
9377
9378            // We've got the fd now, so we're done with the provider.
9379            removeContentProviderExternalUnchecked(name, null, userId);
9380        } else {
9381            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9382        }
9383        return pfd;
9384    }
9385
9386    // Actually is sleeping or shutting down or whatever else in the future
9387    // is an inactive state.
9388    public boolean isSleepingOrShuttingDown() {
9389        return mSleeping || mShuttingDown;
9390    }
9391
9392    public boolean isSleeping() {
9393        return mSleeping;
9394    }
9395
9396    void goingToSleep() {
9397        synchronized(this) {
9398            mWentToSleep = true;
9399            updateEventDispatchingLocked();
9400            goToSleepIfNeededLocked();
9401        }
9402    }
9403
9404    void finishRunningVoiceLocked() {
9405        if (mRunningVoice) {
9406            mRunningVoice = false;
9407            goToSleepIfNeededLocked();
9408        }
9409    }
9410
9411    void goToSleepIfNeededLocked() {
9412        if (mWentToSleep && !mRunningVoice) {
9413            if (!mSleeping) {
9414                mSleeping = true;
9415                mStackSupervisor.goingToSleepLocked();
9416
9417                // Initialize the wake times of all processes.
9418                checkExcessivePowerUsageLocked(false);
9419                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9420                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9421                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9422            }
9423        }
9424    }
9425
9426    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9427        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9428            // Never persist the home stack.
9429            return;
9430        }
9431        mTaskPersister.wakeup(task, flush);
9432    }
9433
9434    @Override
9435    public boolean shutdown(int timeout) {
9436        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9437                != PackageManager.PERMISSION_GRANTED) {
9438            throw new SecurityException("Requires permission "
9439                    + android.Manifest.permission.SHUTDOWN);
9440        }
9441
9442        boolean timedout = false;
9443
9444        synchronized(this) {
9445            mShuttingDown = true;
9446            updateEventDispatchingLocked();
9447            timedout = mStackSupervisor.shutdownLocked(timeout);
9448        }
9449
9450        mAppOpsService.shutdown();
9451        if (mUsageStatsService != null) {
9452            mUsageStatsService.prepareShutdown();
9453        }
9454        mBatteryStatsService.shutdown();
9455        synchronized (this) {
9456            mProcessStats.shutdownLocked();
9457        }
9458        notifyTaskPersisterLocked(null, true);
9459
9460        return timedout;
9461    }
9462
9463    public final void activitySlept(IBinder token) {
9464        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9465
9466        final long origId = Binder.clearCallingIdentity();
9467
9468        synchronized (this) {
9469            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9470            if (r != null) {
9471                mStackSupervisor.activitySleptLocked(r);
9472            }
9473        }
9474
9475        Binder.restoreCallingIdentity(origId);
9476    }
9477
9478    void logLockScreen(String msg) {
9479        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9480                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9481                mWentToSleep + " mSleeping=" + mSleeping);
9482    }
9483
9484    private void comeOutOfSleepIfNeededLocked() {
9485        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9486            if (mSleeping) {
9487                mSleeping = false;
9488                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9489            }
9490        }
9491    }
9492
9493    void wakingUp() {
9494        synchronized(this) {
9495            mWentToSleep = false;
9496            updateEventDispatchingLocked();
9497            comeOutOfSleepIfNeededLocked();
9498        }
9499    }
9500
9501    void startRunningVoiceLocked() {
9502        if (!mRunningVoice) {
9503            mRunningVoice = true;
9504            comeOutOfSleepIfNeededLocked();
9505        }
9506    }
9507
9508    private void updateEventDispatchingLocked() {
9509        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9510    }
9511
9512    public void setLockScreenShown(boolean shown) {
9513        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9514                != PackageManager.PERMISSION_GRANTED) {
9515            throw new SecurityException("Requires permission "
9516                    + android.Manifest.permission.DEVICE_POWER);
9517        }
9518
9519        synchronized(this) {
9520            long ident = Binder.clearCallingIdentity();
9521            try {
9522                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9523                mLockScreenShown = shown;
9524                comeOutOfSleepIfNeededLocked();
9525            } finally {
9526                Binder.restoreCallingIdentity(ident);
9527            }
9528        }
9529    }
9530
9531    @Override
9532    public void stopAppSwitches() {
9533        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9534                != PackageManager.PERMISSION_GRANTED) {
9535            throw new SecurityException("Requires permission "
9536                    + android.Manifest.permission.STOP_APP_SWITCHES);
9537        }
9538
9539        synchronized(this) {
9540            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9541                    + APP_SWITCH_DELAY_TIME;
9542            mDidAppSwitch = false;
9543            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9544            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9545            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9546        }
9547    }
9548
9549    public void resumeAppSwitches() {
9550        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9551                != PackageManager.PERMISSION_GRANTED) {
9552            throw new SecurityException("Requires permission "
9553                    + android.Manifest.permission.STOP_APP_SWITCHES);
9554        }
9555
9556        synchronized(this) {
9557            // Note that we don't execute any pending app switches... we will
9558            // let those wait until either the timeout, or the next start
9559            // activity request.
9560            mAppSwitchesAllowedTime = 0;
9561        }
9562    }
9563
9564    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9565            String name) {
9566        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9567            return true;
9568        }
9569
9570        final int perm = checkComponentPermission(
9571                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9572                callingUid, -1, true);
9573        if (perm == PackageManager.PERMISSION_GRANTED) {
9574            return true;
9575        }
9576
9577        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9578        return false;
9579    }
9580
9581    public void setDebugApp(String packageName, boolean waitForDebugger,
9582            boolean persistent) {
9583        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9584                "setDebugApp()");
9585
9586        long ident = Binder.clearCallingIdentity();
9587        try {
9588            // Note that this is not really thread safe if there are multiple
9589            // callers into it at the same time, but that's not a situation we
9590            // care about.
9591            if (persistent) {
9592                final ContentResolver resolver = mContext.getContentResolver();
9593                Settings.Global.putString(
9594                    resolver, Settings.Global.DEBUG_APP,
9595                    packageName);
9596                Settings.Global.putInt(
9597                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9598                    waitForDebugger ? 1 : 0);
9599            }
9600
9601            synchronized (this) {
9602                if (!persistent) {
9603                    mOrigDebugApp = mDebugApp;
9604                    mOrigWaitForDebugger = mWaitForDebugger;
9605                }
9606                mDebugApp = packageName;
9607                mWaitForDebugger = waitForDebugger;
9608                mDebugTransient = !persistent;
9609                if (packageName != null) {
9610                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9611                            false, UserHandle.USER_ALL, "set debug app");
9612                }
9613            }
9614        } finally {
9615            Binder.restoreCallingIdentity(ident);
9616        }
9617    }
9618
9619    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9620        synchronized (this) {
9621            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9622            if (!isDebuggable) {
9623                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9624                    throw new SecurityException("Process not debuggable: " + app.packageName);
9625                }
9626            }
9627
9628            mOpenGlTraceApp = processName;
9629        }
9630    }
9631
9632    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9633            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9634        synchronized (this) {
9635            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9636            if (!isDebuggable) {
9637                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9638                    throw new SecurityException("Process not debuggable: " + app.packageName);
9639                }
9640            }
9641            mProfileApp = processName;
9642            mProfileFile = profileFile;
9643            if (mProfileFd != null) {
9644                try {
9645                    mProfileFd.close();
9646                } catch (IOException e) {
9647                }
9648                mProfileFd = null;
9649            }
9650            mProfileFd = profileFd;
9651            mProfileType = 0;
9652            mAutoStopProfiler = autoStopProfiler;
9653        }
9654    }
9655
9656    @Override
9657    public void setAlwaysFinish(boolean enabled) {
9658        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9659                "setAlwaysFinish()");
9660
9661        Settings.Global.putInt(
9662                mContext.getContentResolver(),
9663                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9664
9665        synchronized (this) {
9666            mAlwaysFinishActivities = enabled;
9667        }
9668    }
9669
9670    @Override
9671    public void setActivityController(IActivityController controller) {
9672        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9673                "setActivityController()");
9674        synchronized (this) {
9675            mController = controller;
9676            Watchdog.getInstance().setActivityController(controller);
9677        }
9678    }
9679
9680    @Override
9681    public void setUserIsMonkey(boolean userIsMonkey) {
9682        synchronized (this) {
9683            synchronized (mPidsSelfLocked) {
9684                final int callingPid = Binder.getCallingPid();
9685                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9686                if (precessRecord == null) {
9687                    throw new SecurityException("Unknown process: " + callingPid);
9688                }
9689                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9690                    throw new SecurityException("Only an instrumentation process "
9691                            + "with a UiAutomation can call setUserIsMonkey");
9692                }
9693            }
9694            mUserIsMonkey = userIsMonkey;
9695        }
9696    }
9697
9698    @Override
9699    public boolean isUserAMonkey() {
9700        synchronized (this) {
9701            // If there is a controller also implies the user is a monkey.
9702            return (mUserIsMonkey || mController != null);
9703        }
9704    }
9705
9706    public void requestBugReport() {
9707        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9708        SystemProperties.set("ctl.start", "bugreport");
9709    }
9710
9711    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9712        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9713    }
9714
9715    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9716        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9717            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9718        }
9719        return KEY_DISPATCHING_TIMEOUT;
9720    }
9721
9722    @Override
9723    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9724        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9725                != PackageManager.PERMISSION_GRANTED) {
9726            throw new SecurityException("Requires permission "
9727                    + android.Manifest.permission.FILTER_EVENTS);
9728        }
9729        ProcessRecord proc;
9730        long timeout;
9731        synchronized (this) {
9732            synchronized (mPidsSelfLocked) {
9733                proc = mPidsSelfLocked.get(pid);
9734            }
9735            timeout = getInputDispatchingTimeoutLocked(proc);
9736        }
9737
9738        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9739            return -1;
9740        }
9741
9742        return timeout;
9743    }
9744
9745    /**
9746     * Handle input dispatching timeouts.
9747     * Returns whether input dispatching should be aborted or not.
9748     */
9749    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9750            final ActivityRecord activity, final ActivityRecord parent,
9751            final boolean aboveSystem, String reason) {
9752        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9753                != PackageManager.PERMISSION_GRANTED) {
9754            throw new SecurityException("Requires permission "
9755                    + android.Manifest.permission.FILTER_EVENTS);
9756        }
9757
9758        final String annotation;
9759        if (reason == null) {
9760            annotation = "Input dispatching timed out";
9761        } else {
9762            annotation = "Input dispatching timed out (" + reason + ")";
9763        }
9764
9765        if (proc != null) {
9766            synchronized (this) {
9767                if (proc.debugging) {
9768                    return false;
9769                }
9770
9771                if (mDidDexOpt) {
9772                    // Give more time since we were dexopting.
9773                    mDidDexOpt = false;
9774                    return false;
9775                }
9776
9777                if (proc.instrumentationClass != null) {
9778                    Bundle info = new Bundle();
9779                    info.putString("shortMsg", "keyDispatchingTimedOut");
9780                    info.putString("longMsg", annotation);
9781                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9782                    return true;
9783                }
9784            }
9785            mHandler.post(new Runnable() {
9786                @Override
9787                public void run() {
9788                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9789                }
9790            });
9791        }
9792
9793        return true;
9794    }
9795
9796    public Bundle getAssistContextExtras(int requestType) {
9797        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9798                "getAssistContextExtras()");
9799        PendingAssistExtras pae;
9800        Bundle extras = new Bundle();
9801        synchronized (this) {
9802            ActivityRecord activity = getFocusedStack().mResumedActivity;
9803            if (activity == null) {
9804                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9805                return null;
9806            }
9807            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9808            if (activity.app == null || activity.app.thread == null) {
9809                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9810                return extras;
9811            }
9812            if (activity.app.pid == Binder.getCallingPid()) {
9813                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9814                return extras;
9815            }
9816            pae = new PendingAssistExtras(activity);
9817            try {
9818                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9819                        requestType);
9820                mPendingAssistExtras.add(pae);
9821                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9822            } catch (RemoteException e) {
9823                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9824                return extras;
9825            }
9826        }
9827        synchronized (pae) {
9828            while (!pae.haveResult) {
9829                try {
9830                    pae.wait();
9831                } catch (InterruptedException e) {
9832                }
9833            }
9834            if (pae.result != null) {
9835                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9836            }
9837        }
9838        synchronized (this) {
9839            mPendingAssistExtras.remove(pae);
9840            mHandler.removeCallbacks(pae);
9841        }
9842        return extras;
9843    }
9844
9845    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9846        PendingAssistExtras pae = (PendingAssistExtras)token;
9847        synchronized (pae) {
9848            pae.result = extras;
9849            pae.haveResult = true;
9850            pae.notifyAll();
9851        }
9852    }
9853
9854    public void registerProcessObserver(IProcessObserver observer) {
9855        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9856                "registerProcessObserver()");
9857        synchronized (this) {
9858            mProcessObservers.register(observer);
9859        }
9860    }
9861
9862    @Override
9863    public void unregisterProcessObserver(IProcessObserver observer) {
9864        synchronized (this) {
9865            mProcessObservers.unregister(observer);
9866        }
9867    }
9868
9869    @Override
9870    public boolean convertFromTranslucent(IBinder token) {
9871        final long origId = Binder.clearCallingIdentity();
9872        try {
9873            synchronized (this) {
9874                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9875                if (r == null) {
9876                    return false;
9877                }
9878                if (r.changeWindowTranslucency(true)) {
9879                    mWindowManager.setAppFullscreen(token, true);
9880                    r.task.stack.releaseBackgroundResources();
9881                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9882                    return true;
9883                }
9884                return false;
9885            }
9886        } finally {
9887            Binder.restoreCallingIdentity(origId);
9888        }
9889    }
9890
9891    @Override
9892    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9893        final long origId = Binder.clearCallingIdentity();
9894        try {
9895            synchronized (this) {
9896                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9897                if (r == null) {
9898                    return false;
9899                }
9900                int index = r.task.mActivities.lastIndexOf(r);
9901                if (index > 0) {
9902                    ActivityRecord under = r.task.mActivities.get(index - 1);
9903                    under.returningOptions = options;
9904                }
9905                if (r.changeWindowTranslucency(false)) {
9906                    r.task.stack.convertToTranslucent(r);
9907                    mWindowManager.setAppFullscreen(token, false);
9908                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9909                    return true;
9910                } else {
9911                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9912                    return false;
9913                }
9914            }
9915        } finally {
9916            Binder.restoreCallingIdentity(origId);
9917        }
9918    }
9919
9920    @Override
9921    public boolean requestVisibleBehind(IBinder token, boolean visible) {
9922        final long origId = Binder.clearCallingIdentity();
9923        try {
9924            synchronized (this) {
9925                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9926                if (r != null) {
9927                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
9928                }
9929            }
9930            return false;
9931        } finally {
9932            Binder.restoreCallingIdentity(origId);
9933        }
9934    }
9935
9936    @Override
9937    public boolean isBackgroundVisibleBehind(IBinder token) {
9938        final long origId = Binder.clearCallingIdentity();
9939        try {
9940            synchronized (this) {
9941                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9942                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
9943                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
9944                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
9945                return visible;
9946            }
9947        } finally {
9948            Binder.restoreCallingIdentity(origId);
9949        }
9950    }
9951
9952    @Override
9953    public ActivityOptions getActivityOptions(IBinder token) {
9954        final long origId = Binder.clearCallingIdentity();
9955        try {
9956            synchronized (this) {
9957                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9958                if (r != null) {
9959                    final ActivityOptions activityOptions = r.pendingOptions;
9960                    r.pendingOptions = null;
9961                    return activityOptions;
9962                }
9963                return null;
9964            }
9965        } finally {
9966            Binder.restoreCallingIdentity(origId);
9967        }
9968    }
9969
9970    @Override
9971    public void setImmersive(IBinder token, boolean immersive) {
9972        synchronized(this) {
9973            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9974            if (r == null) {
9975                throw new IllegalArgumentException();
9976            }
9977            r.immersive = immersive;
9978
9979            // update associated state if we're frontmost
9980            if (r == mFocusedActivity) {
9981                if (DEBUG_IMMERSIVE) {
9982                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9983                }
9984                applyUpdateLockStateLocked(r);
9985            }
9986        }
9987    }
9988
9989    @Override
9990    public boolean isImmersive(IBinder token) {
9991        synchronized (this) {
9992            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9993            if (r == null) {
9994                throw new IllegalArgumentException();
9995            }
9996            return r.immersive;
9997        }
9998    }
9999
10000    public boolean isTopActivityImmersive() {
10001        enforceNotIsolatedCaller("startActivity");
10002        synchronized (this) {
10003            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10004            return (r != null) ? r.immersive : false;
10005        }
10006    }
10007
10008    @Override
10009    public boolean isTopOfTask(IBinder token) {
10010        synchronized (this) {
10011            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10012            if (r == null) {
10013                throw new IllegalArgumentException();
10014            }
10015            return r.task.getTopActivity() == r;
10016        }
10017    }
10018
10019    public final void enterSafeMode() {
10020        synchronized(this) {
10021            // It only makes sense to do this before the system is ready
10022            // and started launching other packages.
10023            if (!mSystemReady) {
10024                try {
10025                    AppGlobals.getPackageManager().enterSafeMode();
10026                } catch (RemoteException e) {
10027                }
10028            }
10029
10030            mSafeMode = true;
10031        }
10032    }
10033
10034    public final void showSafeModeOverlay() {
10035        View v = LayoutInflater.from(mContext).inflate(
10036                com.android.internal.R.layout.safe_mode, null);
10037        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10038        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10039        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10040        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10041        lp.gravity = Gravity.BOTTOM | Gravity.START;
10042        lp.format = v.getBackground().getOpacity();
10043        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10044                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10045        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10046        ((WindowManager)mContext.getSystemService(
10047                Context.WINDOW_SERVICE)).addView(v, lp);
10048    }
10049
10050    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10051        if (!(sender instanceof PendingIntentRecord)) {
10052            return;
10053        }
10054        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10055        synchronized (stats) {
10056            if (mBatteryStatsService.isOnBattery()) {
10057                mBatteryStatsService.enforceCallingPermission();
10058                PendingIntentRecord rec = (PendingIntentRecord)sender;
10059                int MY_UID = Binder.getCallingUid();
10060                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10061                BatteryStatsImpl.Uid.Pkg pkg =
10062                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10063                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10064                pkg.incWakeupsLocked();
10065            }
10066        }
10067    }
10068
10069    public boolean killPids(int[] pids, String pReason, boolean secure) {
10070        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10071            throw new SecurityException("killPids only available to the system");
10072        }
10073        String reason = (pReason == null) ? "Unknown" : pReason;
10074        // XXX Note: don't acquire main activity lock here, because the window
10075        // manager calls in with its locks held.
10076
10077        boolean killed = false;
10078        synchronized (mPidsSelfLocked) {
10079            int[] types = new int[pids.length];
10080            int worstType = 0;
10081            for (int i=0; i<pids.length; i++) {
10082                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10083                if (proc != null) {
10084                    int type = proc.setAdj;
10085                    types[i] = type;
10086                    if (type > worstType) {
10087                        worstType = type;
10088                    }
10089                }
10090            }
10091
10092            // If the worst oom_adj is somewhere in the cached proc LRU range,
10093            // then constrain it so we will kill all cached procs.
10094            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10095                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10096                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10097            }
10098
10099            // If this is not a secure call, don't let it kill processes that
10100            // are important.
10101            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10102                worstType = ProcessList.SERVICE_ADJ;
10103            }
10104
10105            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10106            for (int i=0; i<pids.length; i++) {
10107                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10108                if (proc == null) {
10109                    continue;
10110                }
10111                int adj = proc.setAdj;
10112                if (adj >= worstType && !proc.killedByAm) {
10113                    killUnneededProcessLocked(proc, reason);
10114                    killed = true;
10115                }
10116            }
10117        }
10118        return killed;
10119    }
10120
10121    @Override
10122    public void killUid(int uid, String reason) {
10123        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10124            throw new SecurityException("killUid only available to the system");
10125        }
10126        synchronized (this) {
10127            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10128                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10129                    reason != null ? reason : "kill uid");
10130        }
10131    }
10132
10133    @Override
10134    public boolean killProcessesBelowForeground(String reason) {
10135        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10136            throw new SecurityException("killProcessesBelowForeground() only available to system");
10137        }
10138
10139        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10140    }
10141
10142    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10143        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10144            throw new SecurityException("killProcessesBelowAdj() only available to system");
10145        }
10146
10147        boolean killed = false;
10148        synchronized (mPidsSelfLocked) {
10149            final int size = mPidsSelfLocked.size();
10150            for (int i = 0; i < size; i++) {
10151                final int pid = mPidsSelfLocked.keyAt(i);
10152                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10153                if (proc == null) continue;
10154
10155                final int adj = proc.setAdj;
10156                if (adj > belowAdj && !proc.killedByAm) {
10157                    killUnneededProcessLocked(proc, reason);
10158                    killed = true;
10159                }
10160            }
10161        }
10162        return killed;
10163    }
10164
10165    @Override
10166    public void hang(final IBinder who, boolean allowRestart) {
10167        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10168                != PackageManager.PERMISSION_GRANTED) {
10169            throw new SecurityException("Requires permission "
10170                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10171        }
10172
10173        final IBinder.DeathRecipient death = new DeathRecipient() {
10174            @Override
10175            public void binderDied() {
10176                synchronized (this) {
10177                    notifyAll();
10178                }
10179            }
10180        };
10181
10182        try {
10183            who.linkToDeath(death, 0);
10184        } catch (RemoteException e) {
10185            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10186            return;
10187        }
10188
10189        synchronized (this) {
10190            Watchdog.getInstance().setAllowRestart(allowRestart);
10191            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10192            synchronized (death) {
10193                while (who.isBinderAlive()) {
10194                    try {
10195                        death.wait();
10196                    } catch (InterruptedException e) {
10197                    }
10198                }
10199            }
10200            Watchdog.getInstance().setAllowRestart(true);
10201        }
10202    }
10203
10204    @Override
10205    public void restart() {
10206        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10207                != PackageManager.PERMISSION_GRANTED) {
10208            throw new SecurityException("Requires permission "
10209                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10210        }
10211
10212        Log.i(TAG, "Sending shutdown broadcast...");
10213
10214        BroadcastReceiver br = new BroadcastReceiver() {
10215            @Override public void onReceive(Context context, Intent intent) {
10216                // Now the broadcast is done, finish up the low-level shutdown.
10217                Log.i(TAG, "Shutting down activity manager...");
10218                shutdown(10000);
10219                Log.i(TAG, "Shutdown complete, restarting!");
10220                Process.killProcess(Process.myPid());
10221                System.exit(10);
10222            }
10223        };
10224
10225        // First send the high-level shut down broadcast.
10226        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10227        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10228        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10229        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10230        mContext.sendOrderedBroadcastAsUser(intent,
10231                UserHandle.ALL, null, br, mHandler, 0, null, null);
10232        */
10233        br.onReceive(mContext, intent);
10234    }
10235
10236    private long getLowRamTimeSinceIdle(long now) {
10237        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10238    }
10239
10240    @Override
10241    public void performIdleMaintenance() {
10242        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10243                != PackageManager.PERMISSION_GRANTED) {
10244            throw new SecurityException("Requires permission "
10245                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10246        }
10247
10248        synchronized (this) {
10249            final long now = SystemClock.uptimeMillis();
10250            final long timeSinceLastIdle = now - mLastIdleTime;
10251            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10252            mLastIdleTime = now;
10253            mLowRamTimeSinceLastIdle = 0;
10254            if (mLowRamStartTime != 0) {
10255                mLowRamStartTime = now;
10256            }
10257
10258            StringBuilder sb = new StringBuilder(128);
10259            sb.append("Idle maintenance over ");
10260            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10261            sb.append(" low RAM for ");
10262            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10263            Slog.i(TAG, sb.toString());
10264
10265            // If at least 1/3 of our time since the last idle period has been spent
10266            // with RAM low, then we want to kill processes.
10267            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10268
10269            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10270                ProcessRecord proc = mLruProcesses.get(i);
10271                if (proc.notCachedSinceIdle) {
10272                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10273                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10274                        if (doKilling && proc.initialIdlePss != 0
10275                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10276                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10277                                    + " from " + proc.initialIdlePss + ")");
10278                        }
10279                    }
10280                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10281                    proc.notCachedSinceIdle = true;
10282                    proc.initialIdlePss = 0;
10283                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10284                            isSleeping(), now);
10285                }
10286            }
10287
10288            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10289            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10290        }
10291    }
10292
10293    private void retrieveSettings() {
10294        final ContentResolver resolver = mContext.getContentResolver();
10295        String debugApp = Settings.Global.getString(
10296            resolver, Settings.Global.DEBUG_APP);
10297        boolean waitForDebugger = Settings.Global.getInt(
10298            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10299        boolean alwaysFinishActivities = Settings.Global.getInt(
10300            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10301        boolean forceRtl = Settings.Global.getInt(
10302                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10303        // Transfer any global setting for forcing RTL layout, into a System Property
10304        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10305
10306        Configuration configuration = new Configuration();
10307        Settings.System.getConfiguration(resolver, configuration);
10308        if (forceRtl) {
10309            // This will take care of setting the correct layout direction flags
10310            configuration.setLayoutDirection(configuration.locale);
10311        }
10312
10313        synchronized (this) {
10314            mDebugApp = mOrigDebugApp = debugApp;
10315            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10316            mAlwaysFinishActivities = alwaysFinishActivities;
10317            // This happens before any activities are started, so we can
10318            // change mConfiguration in-place.
10319            updateConfigurationLocked(configuration, null, false, true);
10320            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10321        }
10322    }
10323
10324    public boolean testIsSystemReady() {
10325        // no need to synchronize(this) just to read & return the value
10326        return mSystemReady;
10327    }
10328
10329    private static File getCalledPreBootReceiversFile() {
10330        File dataDir = Environment.getDataDirectory();
10331        File systemDir = new File(dataDir, "system");
10332        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10333        return fname;
10334    }
10335
10336    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10337        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10338        File file = getCalledPreBootReceiversFile();
10339        FileInputStream fis = null;
10340        try {
10341            fis = new FileInputStream(file);
10342            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10343            int fvers = dis.readInt();
10344            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10345                String vers = dis.readUTF();
10346                String codename = dis.readUTF();
10347                String build = dis.readUTF();
10348                if (android.os.Build.VERSION.RELEASE.equals(vers)
10349                        && android.os.Build.VERSION.CODENAME.equals(codename)
10350                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10351                    int num = dis.readInt();
10352                    while (num > 0) {
10353                        num--;
10354                        String pkg = dis.readUTF();
10355                        String cls = dis.readUTF();
10356                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10357                    }
10358                }
10359            }
10360        } catch (FileNotFoundException e) {
10361        } catch (IOException e) {
10362            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10363        } finally {
10364            if (fis != null) {
10365                try {
10366                    fis.close();
10367                } catch (IOException e) {
10368                }
10369            }
10370        }
10371        return lastDoneReceivers;
10372    }
10373
10374    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10375        File file = getCalledPreBootReceiversFile();
10376        FileOutputStream fos = null;
10377        DataOutputStream dos = null;
10378        try {
10379            fos = new FileOutputStream(file);
10380            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10381            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10382            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10383            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10384            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10385            dos.writeInt(list.size());
10386            for (int i=0; i<list.size(); i++) {
10387                dos.writeUTF(list.get(i).getPackageName());
10388                dos.writeUTF(list.get(i).getClassName());
10389            }
10390        } catch (IOException e) {
10391            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10392            file.delete();
10393        } finally {
10394            FileUtils.sync(fos);
10395            if (dos != null) {
10396                try {
10397                    dos.close();
10398                } catch (IOException e) {
10399                    // TODO Auto-generated catch block
10400                    e.printStackTrace();
10401                }
10402            }
10403        }
10404    }
10405
10406    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10407            ArrayList<ComponentName> doneReceivers, int userId) {
10408        boolean waitingUpdate = false;
10409        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10410        List<ResolveInfo> ris = null;
10411        try {
10412            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10413                    intent, null, 0, userId);
10414        } catch (RemoteException e) {
10415        }
10416        if (ris != null) {
10417            for (int i=ris.size()-1; i>=0; i--) {
10418                if ((ris.get(i).activityInfo.applicationInfo.flags
10419                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10420                    ris.remove(i);
10421                }
10422            }
10423            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10424
10425            // For User 0, load the version number. When delivering to a new user, deliver
10426            // to all receivers.
10427            if (userId == UserHandle.USER_OWNER) {
10428                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10429                for (int i=0; i<ris.size(); i++) {
10430                    ActivityInfo ai = ris.get(i).activityInfo;
10431                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10432                    if (lastDoneReceivers.contains(comp)) {
10433                        // We already did the pre boot receiver for this app with the current
10434                        // platform version, so don't do it again...
10435                        ris.remove(i);
10436                        i--;
10437                        // ...however, do keep it as one that has been done, so we don't
10438                        // forget about it when rewriting the file of last done receivers.
10439                        doneReceivers.add(comp);
10440                    }
10441                }
10442            }
10443
10444            // If primary user, send broadcast to all available users, else just to userId
10445            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10446                    : new int[] { userId };
10447            for (int i = 0; i < ris.size(); i++) {
10448                ActivityInfo ai = ris.get(i).activityInfo;
10449                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10450                doneReceivers.add(comp);
10451                intent.setComponent(comp);
10452                for (int j=0; j<users.length; j++) {
10453                    IIntentReceiver finisher = null;
10454                    // On last receiver and user, set up a completion callback
10455                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10456                        finisher = new IIntentReceiver.Stub() {
10457                            public void performReceive(Intent intent, int resultCode,
10458                                    String data, Bundle extras, boolean ordered,
10459                                    boolean sticky, int sendingUser) {
10460                                // The raw IIntentReceiver interface is called
10461                                // with the AM lock held, so redispatch to
10462                                // execute our code without the lock.
10463                                mHandler.post(onFinishCallback);
10464                            }
10465                        };
10466                    }
10467                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10468                            + " for user " + users[j]);
10469                    broadcastIntentLocked(null, null, intent, null, finisher,
10470                            0, null, null, null, AppOpsManager.OP_NONE,
10471                            true, false, MY_PID, Process.SYSTEM_UID,
10472                            users[j]);
10473                    if (finisher != null) {
10474                        waitingUpdate = true;
10475                    }
10476                }
10477            }
10478        }
10479
10480        return waitingUpdate;
10481    }
10482
10483    public void systemReady(final Runnable goingCallback) {
10484        synchronized(this) {
10485            if (mSystemReady) {
10486                // If we're done calling all the receivers, run the next "boot phase" passed in
10487                // by the SystemServer
10488                if (goingCallback != null) {
10489                    goingCallback.run();
10490                }
10491                return;
10492            }
10493
10494            // Make sure we have the current profile info, since it is needed for
10495            // security checks.
10496            updateCurrentProfileIdsLocked();
10497
10498            if (mRecentTasks == null) {
10499                mRecentTasks = mTaskPersister.restoreTasksLocked();
10500                if (!mRecentTasks.isEmpty()) {
10501                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10502                }
10503                mTaskPersister.startPersisting();
10504            }
10505
10506            // Check to see if there are any update receivers to run.
10507            if (!mDidUpdate) {
10508                if (mWaitingUpdate) {
10509                    return;
10510                }
10511                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10512                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10513                    public void run() {
10514                        synchronized (ActivityManagerService.this) {
10515                            mDidUpdate = true;
10516                        }
10517                        writeLastDonePreBootReceivers(doneReceivers);
10518                        showBootMessage(mContext.getText(
10519                                R.string.android_upgrading_complete),
10520                                false);
10521                        systemReady(goingCallback);
10522                    }
10523                }, doneReceivers, UserHandle.USER_OWNER);
10524
10525                if (mWaitingUpdate) {
10526                    return;
10527                }
10528                mDidUpdate = true;
10529            }
10530
10531            mAppOpsService.systemReady();
10532            mSystemReady = true;
10533        }
10534
10535        ArrayList<ProcessRecord> procsToKill = null;
10536        synchronized(mPidsSelfLocked) {
10537            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10538                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10539                if (!isAllowedWhileBooting(proc.info)){
10540                    if (procsToKill == null) {
10541                        procsToKill = new ArrayList<ProcessRecord>();
10542                    }
10543                    procsToKill.add(proc);
10544                }
10545            }
10546        }
10547
10548        synchronized(this) {
10549            if (procsToKill != null) {
10550                for (int i=procsToKill.size()-1; i>=0; i--) {
10551                    ProcessRecord proc = procsToKill.get(i);
10552                    Slog.i(TAG, "Removing system update proc: " + proc);
10553                    removeProcessLocked(proc, true, false, "system update done");
10554                }
10555            }
10556
10557            // Now that we have cleaned up any update processes, we
10558            // are ready to start launching real processes and know that
10559            // we won't trample on them any more.
10560            mProcessesReady = true;
10561        }
10562
10563        Slog.i(TAG, "System now ready");
10564        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10565            SystemClock.uptimeMillis());
10566
10567        synchronized(this) {
10568            // Make sure we have no pre-ready processes sitting around.
10569
10570            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10571                ResolveInfo ri = mContext.getPackageManager()
10572                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10573                                STOCK_PM_FLAGS);
10574                CharSequence errorMsg = null;
10575                if (ri != null) {
10576                    ActivityInfo ai = ri.activityInfo;
10577                    ApplicationInfo app = ai.applicationInfo;
10578                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10579                        mTopAction = Intent.ACTION_FACTORY_TEST;
10580                        mTopData = null;
10581                        mTopComponent = new ComponentName(app.packageName,
10582                                ai.name);
10583                    } else {
10584                        errorMsg = mContext.getResources().getText(
10585                                com.android.internal.R.string.factorytest_not_system);
10586                    }
10587                } else {
10588                    errorMsg = mContext.getResources().getText(
10589                            com.android.internal.R.string.factorytest_no_action);
10590                }
10591                if (errorMsg != null) {
10592                    mTopAction = null;
10593                    mTopData = null;
10594                    mTopComponent = null;
10595                    Message msg = Message.obtain();
10596                    msg.what = SHOW_FACTORY_ERROR_MSG;
10597                    msg.getData().putCharSequence("msg", errorMsg);
10598                    mHandler.sendMessage(msg);
10599                }
10600            }
10601        }
10602
10603        retrieveSettings();
10604
10605        synchronized (this) {
10606            readGrantedUriPermissionsLocked();
10607        }
10608
10609        if (goingCallback != null) goingCallback.run();
10610
10611        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10612                Integer.toString(mCurrentUserId), mCurrentUserId);
10613        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10614                Integer.toString(mCurrentUserId), mCurrentUserId);
10615        mSystemServiceManager.startUser(mCurrentUserId);
10616
10617        synchronized (this) {
10618            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10619                try {
10620                    List apps = AppGlobals.getPackageManager().
10621                        getPersistentApplications(STOCK_PM_FLAGS);
10622                    if (apps != null) {
10623                        int N = apps.size();
10624                        int i;
10625                        for (i=0; i<N; i++) {
10626                            ApplicationInfo info
10627                                = (ApplicationInfo)apps.get(i);
10628                            if (info != null &&
10629                                    !info.packageName.equals("android")) {
10630                                addAppLocked(info, false, null /* ABI override */);
10631                            }
10632                        }
10633                    }
10634                } catch (RemoteException ex) {
10635                    // pm is in same process, this will never happen.
10636                }
10637            }
10638
10639            // Start up initial activity.
10640            mBooting = true;
10641
10642            try {
10643                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10644                    Message msg = Message.obtain();
10645                    msg.what = SHOW_UID_ERROR_MSG;
10646                    mHandler.sendMessage(msg);
10647                }
10648            } catch (RemoteException e) {
10649            }
10650
10651            long ident = Binder.clearCallingIdentity();
10652            try {
10653                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10654                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10655                        | Intent.FLAG_RECEIVER_FOREGROUND);
10656                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10657                broadcastIntentLocked(null, null, intent,
10658                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10659                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10660                intent = new Intent(Intent.ACTION_USER_STARTING);
10661                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10662                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10663                broadcastIntentLocked(null, null, intent,
10664                        null, new IIntentReceiver.Stub() {
10665                            @Override
10666                            public void performReceive(Intent intent, int resultCode, String data,
10667                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10668                                    throws RemoteException {
10669                            }
10670                        }, 0, null, null,
10671                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10672                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10673            } catch (Throwable t) {
10674                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10675            } finally {
10676                Binder.restoreCallingIdentity(ident);
10677            }
10678            mStackSupervisor.resumeTopActivitiesLocked();
10679            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10680        }
10681    }
10682
10683    private boolean makeAppCrashingLocked(ProcessRecord app,
10684            String shortMsg, String longMsg, String stackTrace) {
10685        app.crashing = true;
10686        app.crashingReport = generateProcessError(app,
10687                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10688        startAppProblemLocked(app);
10689        app.stopFreezingAllLocked();
10690        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10691    }
10692
10693    private void makeAppNotRespondingLocked(ProcessRecord app,
10694            String activity, String shortMsg, String longMsg) {
10695        app.notResponding = true;
10696        app.notRespondingReport = generateProcessError(app,
10697                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10698                activity, shortMsg, longMsg, null);
10699        startAppProblemLocked(app);
10700        app.stopFreezingAllLocked();
10701    }
10702
10703    /**
10704     * Generate a process error record, suitable for attachment to a ProcessRecord.
10705     *
10706     * @param app The ProcessRecord in which the error occurred.
10707     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10708     *                      ActivityManager.AppErrorStateInfo
10709     * @param activity The activity associated with the crash, if known.
10710     * @param shortMsg Short message describing the crash.
10711     * @param longMsg Long message describing the crash.
10712     * @param stackTrace Full crash stack trace, may be null.
10713     *
10714     * @return Returns a fully-formed AppErrorStateInfo record.
10715     */
10716    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10717            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10718        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10719
10720        report.condition = condition;
10721        report.processName = app.processName;
10722        report.pid = app.pid;
10723        report.uid = app.info.uid;
10724        report.tag = activity;
10725        report.shortMsg = shortMsg;
10726        report.longMsg = longMsg;
10727        report.stackTrace = stackTrace;
10728
10729        return report;
10730    }
10731
10732    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10733        synchronized (this) {
10734            app.crashing = false;
10735            app.crashingReport = null;
10736            app.notResponding = false;
10737            app.notRespondingReport = null;
10738            if (app.anrDialog == fromDialog) {
10739                app.anrDialog = null;
10740            }
10741            if (app.waitDialog == fromDialog) {
10742                app.waitDialog = null;
10743            }
10744            if (app.pid > 0 && app.pid != MY_PID) {
10745                handleAppCrashLocked(app, null, null, null);
10746                killUnneededProcessLocked(app, "user request after error");
10747            }
10748        }
10749    }
10750
10751    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10752            String stackTrace) {
10753        long now = SystemClock.uptimeMillis();
10754
10755        Long crashTime;
10756        if (!app.isolated) {
10757            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10758        } else {
10759            crashTime = null;
10760        }
10761        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10762            // This process loses!
10763            Slog.w(TAG, "Process " + app.info.processName
10764                    + " has crashed too many times: killing!");
10765            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10766                    app.userId, app.info.processName, app.uid);
10767            mStackSupervisor.handleAppCrashLocked(app);
10768            if (!app.persistent) {
10769                // We don't want to start this process again until the user
10770                // explicitly does so...  but for persistent process, we really
10771                // need to keep it running.  If a persistent process is actually
10772                // repeatedly crashing, then badness for everyone.
10773                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10774                        app.info.processName);
10775                if (!app.isolated) {
10776                    // XXX We don't have a way to mark isolated processes
10777                    // as bad, since they don't have a peristent identity.
10778                    mBadProcesses.put(app.info.processName, app.uid,
10779                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10780                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10781                }
10782                app.bad = true;
10783                app.removed = true;
10784                // Don't let services in this process be restarted and potentially
10785                // annoy the user repeatedly.  Unless it is persistent, since those
10786                // processes run critical code.
10787                removeProcessLocked(app, false, false, "crash");
10788                mStackSupervisor.resumeTopActivitiesLocked();
10789                return false;
10790            }
10791            mStackSupervisor.resumeTopActivitiesLocked();
10792        } else {
10793            mStackSupervisor.finishTopRunningActivityLocked(app);
10794        }
10795
10796        // Bump up the crash count of any services currently running in the proc.
10797        for (int i=app.services.size()-1; i>=0; i--) {
10798            // Any services running in the application need to be placed
10799            // back in the pending list.
10800            ServiceRecord sr = app.services.valueAt(i);
10801            sr.crashCount++;
10802        }
10803
10804        // If the crashing process is what we consider to be the "home process" and it has been
10805        // replaced by a third-party app, clear the package preferred activities from packages
10806        // with a home activity running in the process to prevent a repeatedly crashing app
10807        // from blocking the user to manually clear the list.
10808        final ArrayList<ActivityRecord> activities = app.activities;
10809        if (app == mHomeProcess && activities.size() > 0
10810                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10811            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10812                final ActivityRecord r = activities.get(activityNdx);
10813                if (r.isHomeActivity()) {
10814                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10815                    try {
10816                        ActivityThread.getPackageManager()
10817                                .clearPackagePreferredActivities(r.packageName);
10818                    } catch (RemoteException c) {
10819                        // pm is in same process, this will never happen.
10820                    }
10821                }
10822            }
10823        }
10824
10825        if (!app.isolated) {
10826            // XXX Can't keep track of crash times for isolated processes,
10827            // because they don't have a perisistent identity.
10828            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10829        }
10830
10831        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10832        return true;
10833    }
10834
10835    void startAppProblemLocked(ProcessRecord app) {
10836        // If this app is not running under the current user, then we
10837        // can't give it a report button because that would require
10838        // launching the report UI under a different user.
10839        app.errorReportReceiver = null;
10840
10841        for (int userId : mCurrentProfileIds) {
10842            if (app.userId == userId) {
10843                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10844                        mContext, app.info.packageName, app.info.flags);
10845            }
10846        }
10847        skipCurrentReceiverLocked(app);
10848    }
10849
10850    void skipCurrentReceiverLocked(ProcessRecord app) {
10851        for (BroadcastQueue queue : mBroadcastQueues) {
10852            queue.skipCurrentReceiverLocked(app);
10853        }
10854    }
10855
10856    /**
10857     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10858     * The application process will exit immediately after this call returns.
10859     * @param app object of the crashing app, null for the system server
10860     * @param crashInfo describing the exception
10861     */
10862    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10863        ProcessRecord r = findAppProcess(app, "Crash");
10864        final String processName = app == null ? "system_server"
10865                : (r == null ? "unknown" : r.processName);
10866
10867        handleApplicationCrashInner("crash", r, processName, crashInfo);
10868    }
10869
10870    /* Native crash reporting uses this inner version because it needs to be somewhat
10871     * decoupled from the AM-managed cleanup lifecycle
10872     */
10873    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10874            ApplicationErrorReport.CrashInfo crashInfo) {
10875        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10876                UserHandle.getUserId(Binder.getCallingUid()), processName,
10877                r == null ? -1 : r.info.flags,
10878                crashInfo.exceptionClassName,
10879                crashInfo.exceptionMessage,
10880                crashInfo.throwFileName,
10881                crashInfo.throwLineNumber);
10882
10883        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10884
10885        crashApplication(r, crashInfo);
10886    }
10887
10888    public void handleApplicationStrictModeViolation(
10889            IBinder app,
10890            int violationMask,
10891            StrictMode.ViolationInfo info) {
10892        ProcessRecord r = findAppProcess(app, "StrictMode");
10893        if (r == null) {
10894            return;
10895        }
10896
10897        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10898            Integer stackFingerprint = info.hashCode();
10899            boolean logIt = true;
10900            synchronized (mAlreadyLoggedViolatedStacks) {
10901                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10902                    logIt = false;
10903                    // TODO: sub-sample into EventLog for these, with
10904                    // the info.durationMillis?  Then we'd get
10905                    // the relative pain numbers, without logging all
10906                    // the stack traces repeatedly.  We'd want to do
10907                    // likewise in the client code, which also does
10908                    // dup suppression, before the Binder call.
10909                } else {
10910                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10911                        mAlreadyLoggedViolatedStacks.clear();
10912                    }
10913                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10914                }
10915            }
10916            if (logIt) {
10917                logStrictModeViolationToDropBox(r, info);
10918            }
10919        }
10920
10921        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10922            AppErrorResult result = new AppErrorResult();
10923            synchronized (this) {
10924                final long origId = Binder.clearCallingIdentity();
10925
10926                Message msg = Message.obtain();
10927                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10928                HashMap<String, Object> data = new HashMap<String, Object>();
10929                data.put("result", result);
10930                data.put("app", r);
10931                data.put("violationMask", violationMask);
10932                data.put("info", info);
10933                msg.obj = data;
10934                mHandler.sendMessage(msg);
10935
10936                Binder.restoreCallingIdentity(origId);
10937            }
10938            int res = result.get();
10939            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10940        }
10941    }
10942
10943    // Depending on the policy in effect, there could be a bunch of
10944    // these in quick succession so we try to batch these together to
10945    // minimize disk writes, number of dropbox entries, and maximize
10946    // compression, by having more fewer, larger records.
10947    private void logStrictModeViolationToDropBox(
10948            ProcessRecord process,
10949            StrictMode.ViolationInfo info) {
10950        if (info == null) {
10951            return;
10952        }
10953        final boolean isSystemApp = process == null ||
10954                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10955                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10956        final String processName = process == null ? "unknown" : process.processName;
10957        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10958        final DropBoxManager dbox = (DropBoxManager)
10959                mContext.getSystemService(Context.DROPBOX_SERVICE);
10960
10961        // Exit early if the dropbox isn't configured to accept this report type.
10962        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10963
10964        boolean bufferWasEmpty;
10965        boolean needsFlush;
10966        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10967        synchronized (sb) {
10968            bufferWasEmpty = sb.length() == 0;
10969            appendDropBoxProcessHeaders(process, processName, sb);
10970            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10971            sb.append("System-App: ").append(isSystemApp).append("\n");
10972            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10973            if (info.violationNumThisLoop != 0) {
10974                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10975            }
10976            if (info.numAnimationsRunning != 0) {
10977                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10978            }
10979            if (info.broadcastIntentAction != null) {
10980                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10981            }
10982            if (info.durationMillis != -1) {
10983                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10984            }
10985            if (info.numInstances != -1) {
10986                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10987            }
10988            if (info.tags != null) {
10989                for (String tag : info.tags) {
10990                    sb.append("Span-Tag: ").append(tag).append("\n");
10991                }
10992            }
10993            sb.append("\n");
10994            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10995                sb.append(info.crashInfo.stackTrace);
10996            }
10997            sb.append("\n");
10998
10999            // Only buffer up to ~64k.  Various logging bits truncate
11000            // things at 128k.
11001            needsFlush = (sb.length() > 64 * 1024);
11002        }
11003
11004        // Flush immediately if the buffer's grown too large, or this
11005        // is a non-system app.  Non-system apps are isolated with a
11006        // different tag & policy and not batched.
11007        //
11008        // Batching is useful during internal testing with
11009        // StrictMode settings turned up high.  Without batching,
11010        // thousands of separate files could be created on boot.
11011        if (!isSystemApp || needsFlush) {
11012            new Thread("Error dump: " + dropboxTag) {
11013                @Override
11014                public void run() {
11015                    String report;
11016                    synchronized (sb) {
11017                        report = sb.toString();
11018                        sb.delete(0, sb.length());
11019                        sb.trimToSize();
11020                    }
11021                    if (report.length() != 0) {
11022                        dbox.addText(dropboxTag, report);
11023                    }
11024                }
11025            }.start();
11026            return;
11027        }
11028
11029        // System app batching:
11030        if (!bufferWasEmpty) {
11031            // An existing dropbox-writing thread is outstanding, so
11032            // we don't need to start it up.  The existing thread will
11033            // catch the buffer appends we just did.
11034            return;
11035        }
11036
11037        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11038        // (After this point, we shouldn't access AMS internal data structures.)
11039        new Thread("Error dump: " + dropboxTag) {
11040            @Override
11041            public void run() {
11042                // 5 second sleep to let stacks arrive and be batched together
11043                try {
11044                    Thread.sleep(5000);  // 5 seconds
11045                } catch (InterruptedException e) {}
11046
11047                String errorReport;
11048                synchronized (mStrictModeBuffer) {
11049                    errorReport = mStrictModeBuffer.toString();
11050                    if (errorReport.length() == 0) {
11051                        return;
11052                    }
11053                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11054                    mStrictModeBuffer.trimToSize();
11055                }
11056                dbox.addText(dropboxTag, errorReport);
11057            }
11058        }.start();
11059    }
11060
11061    /**
11062     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11063     * @param app object of the crashing app, null for the system server
11064     * @param tag reported by the caller
11065     * @param crashInfo describing the context of the error
11066     * @return true if the process should exit immediately (WTF is fatal)
11067     */
11068    public boolean handleApplicationWtf(IBinder app, String tag,
11069            ApplicationErrorReport.CrashInfo crashInfo) {
11070        ProcessRecord r = findAppProcess(app, "WTF");
11071        final String processName = app == null ? "system_server"
11072                : (r == null ? "unknown" : r.processName);
11073
11074        EventLog.writeEvent(EventLogTags.AM_WTF,
11075                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11076                processName,
11077                r == null ? -1 : r.info.flags,
11078                tag, crashInfo.exceptionMessage);
11079
11080        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11081
11082        if (r != null && r.pid != Process.myPid() &&
11083                Settings.Global.getInt(mContext.getContentResolver(),
11084                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11085            crashApplication(r, crashInfo);
11086            return true;
11087        } else {
11088            return false;
11089        }
11090    }
11091
11092    /**
11093     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11094     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11095     */
11096    private ProcessRecord findAppProcess(IBinder app, String reason) {
11097        if (app == null) {
11098            return null;
11099        }
11100
11101        synchronized (this) {
11102            final int NP = mProcessNames.getMap().size();
11103            for (int ip=0; ip<NP; ip++) {
11104                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11105                final int NA = apps.size();
11106                for (int ia=0; ia<NA; ia++) {
11107                    ProcessRecord p = apps.valueAt(ia);
11108                    if (p.thread != null && p.thread.asBinder() == app) {
11109                        return p;
11110                    }
11111                }
11112            }
11113
11114            Slog.w(TAG, "Can't find mystery application for " + reason
11115                    + " from pid=" + Binder.getCallingPid()
11116                    + " uid=" + Binder.getCallingUid() + ": " + app);
11117            return null;
11118        }
11119    }
11120
11121    /**
11122     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11123     * to append various headers to the dropbox log text.
11124     */
11125    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11126            StringBuilder sb) {
11127        // Watchdog thread ends up invoking this function (with
11128        // a null ProcessRecord) to add the stack file to dropbox.
11129        // Do not acquire a lock on this (am) in such cases, as it
11130        // could cause a potential deadlock, if and when watchdog
11131        // is invoked due to unavailability of lock on am and it
11132        // would prevent watchdog from killing system_server.
11133        if (process == null) {
11134            sb.append("Process: ").append(processName).append("\n");
11135            return;
11136        }
11137        // Note: ProcessRecord 'process' is guarded by the service
11138        // instance.  (notably process.pkgList, which could otherwise change
11139        // concurrently during execution of this method)
11140        synchronized (this) {
11141            sb.append("Process: ").append(processName).append("\n");
11142            int flags = process.info.flags;
11143            IPackageManager pm = AppGlobals.getPackageManager();
11144            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11145            for (int ip=0; ip<process.pkgList.size(); ip++) {
11146                String pkg = process.pkgList.keyAt(ip);
11147                sb.append("Package: ").append(pkg);
11148                try {
11149                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11150                    if (pi != null) {
11151                        sb.append(" v").append(pi.versionCode);
11152                        if (pi.versionName != null) {
11153                            sb.append(" (").append(pi.versionName).append(")");
11154                        }
11155                    }
11156                } catch (RemoteException e) {
11157                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11158                }
11159                sb.append("\n");
11160            }
11161        }
11162    }
11163
11164    private static String processClass(ProcessRecord process) {
11165        if (process == null || process.pid == MY_PID) {
11166            return "system_server";
11167        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11168            return "system_app";
11169        } else {
11170            return "data_app";
11171        }
11172    }
11173
11174    /**
11175     * Write a description of an error (crash, WTF, ANR) to the drop box.
11176     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11177     * @param process which caused the error, null means the system server
11178     * @param activity which triggered the error, null if unknown
11179     * @param parent activity related to the error, null if unknown
11180     * @param subject line related to the error, null if absent
11181     * @param report in long form describing the error, null if absent
11182     * @param logFile to include in the report, null if none
11183     * @param crashInfo giving an application stack trace, null if absent
11184     */
11185    public void addErrorToDropBox(String eventType,
11186            ProcessRecord process, String processName, ActivityRecord activity,
11187            ActivityRecord parent, String subject,
11188            final String report, final File logFile,
11189            final ApplicationErrorReport.CrashInfo crashInfo) {
11190        // NOTE -- this must never acquire the ActivityManagerService lock,
11191        // otherwise the watchdog may be prevented from resetting the system.
11192
11193        final String dropboxTag = processClass(process) + "_" + eventType;
11194        final DropBoxManager dbox = (DropBoxManager)
11195                mContext.getSystemService(Context.DROPBOX_SERVICE);
11196
11197        // Exit early if the dropbox isn't configured to accept this report type.
11198        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11199
11200        final StringBuilder sb = new StringBuilder(1024);
11201        appendDropBoxProcessHeaders(process, processName, sb);
11202        if (activity != null) {
11203            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11204        }
11205        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11206            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11207        }
11208        if (parent != null && parent != activity) {
11209            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11210        }
11211        if (subject != null) {
11212            sb.append("Subject: ").append(subject).append("\n");
11213        }
11214        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11215        if (Debug.isDebuggerConnected()) {
11216            sb.append("Debugger: Connected\n");
11217        }
11218        sb.append("\n");
11219
11220        // Do the rest in a worker thread to avoid blocking the caller on I/O
11221        // (After this point, we shouldn't access AMS internal data structures.)
11222        Thread worker = new Thread("Error dump: " + dropboxTag) {
11223            @Override
11224            public void run() {
11225                if (report != null) {
11226                    sb.append(report);
11227                }
11228                if (logFile != null) {
11229                    try {
11230                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11231                                    "\n\n[[TRUNCATED]]"));
11232                    } catch (IOException e) {
11233                        Slog.e(TAG, "Error reading " + logFile, e);
11234                    }
11235                }
11236                if (crashInfo != null && crashInfo.stackTrace != null) {
11237                    sb.append(crashInfo.stackTrace);
11238                }
11239
11240                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11241                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11242                if (lines > 0) {
11243                    sb.append("\n");
11244
11245                    // Merge several logcat streams, and take the last N lines
11246                    InputStreamReader input = null;
11247                    try {
11248                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11249                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11250                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11251
11252                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11253                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11254                        input = new InputStreamReader(logcat.getInputStream());
11255
11256                        int num;
11257                        char[] buf = new char[8192];
11258                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11259                    } catch (IOException e) {
11260                        Slog.e(TAG, "Error running logcat", e);
11261                    } finally {
11262                        if (input != null) try { input.close(); } catch (IOException e) {}
11263                    }
11264                }
11265
11266                dbox.addText(dropboxTag, sb.toString());
11267            }
11268        };
11269
11270        if (process == null) {
11271            // If process is null, we are being called from some internal code
11272            // and may be about to die -- run this synchronously.
11273            worker.run();
11274        } else {
11275            worker.start();
11276        }
11277    }
11278
11279    /**
11280     * Bring up the "unexpected error" dialog box for a crashing app.
11281     * Deal with edge cases (intercepts from instrumented applications,
11282     * ActivityController, error intent receivers, that sort of thing).
11283     * @param r the application crashing
11284     * @param crashInfo describing the failure
11285     */
11286    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11287        long timeMillis = System.currentTimeMillis();
11288        String shortMsg = crashInfo.exceptionClassName;
11289        String longMsg = crashInfo.exceptionMessage;
11290        String stackTrace = crashInfo.stackTrace;
11291        if (shortMsg != null && longMsg != null) {
11292            longMsg = shortMsg + ": " + longMsg;
11293        } else if (shortMsg != null) {
11294            longMsg = shortMsg;
11295        }
11296
11297        AppErrorResult result = new AppErrorResult();
11298        synchronized (this) {
11299            if (mController != null) {
11300                try {
11301                    String name = r != null ? r.processName : null;
11302                    int pid = r != null ? r.pid : Binder.getCallingPid();
11303                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11304                    if (!mController.appCrashed(name, pid,
11305                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11306                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11307                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11308                            Slog.w(TAG, "Skip killing native crashed app " + name
11309                                    + "(" + pid + ") during testing");
11310                        } else {
11311                            Slog.w(TAG, "Force-killing crashed app " + name
11312                                    + " at watcher's request");
11313                            Process.killProcess(pid);
11314                            if (r != null) {
11315                                Process.killProcessGroup(uid, pid);
11316                            }
11317                        }
11318                        return;
11319                    }
11320                } catch (RemoteException e) {
11321                    mController = null;
11322                    Watchdog.getInstance().setActivityController(null);
11323                }
11324            }
11325
11326            final long origId = Binder.clearCallingIdentity();
11327
11328            // If this process is running instrumentation, finish it.
11329            if (r != null && r.instrumentationClass != null) {
11330                Slog.w(TAG, "Error in app " + r.processName
11331                      + " running instrumentation " + r.instrumentationClass + ":");
11332                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11333                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11334                Bundle info = new Bundle();
11335                info.putString("shortMsg", shortMsg);
11336                info.putString("longMsg", longMsg);
11337                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11338                Binder.restoreCallingIdentity(origId);
11339                return;
11340            }
11341
11342            // If we can't identify the process or it's already exceeded its crash quota,
11343            // quit right away without showing a crash dialog.
11344            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11345                Binder.restoreCallingIdentity(origId);
11346                return;
11347            }
11348
11349            Message msg = Message.obtain();
11350            msg.what = SHOW_ERROR_MSG;
11351            HashMap data = new HashMap();
11352            data.put("result", result);
11353            data.put("app", r);
11354            msg.obj = data;
11355            mHandler.sendMessage(msg);
11356
11357            Binder.restoreCallingIdentity(origId);
11358        }
11359
11360        int res = result.get();
11361
11362        Intent appErrorIntent = null;
11363        synchronized (this) {
11364            if (r != null && !r.isolated) {
11365                // XXX Can't keep track of crash time for isolated processes,
11366                // since they don't have a persistent identity.
11367                mProcessCrashTimes.put(r.info.processName, r.uid,
11368                        SystemClock.uptimeMillis());
11369            }
11370            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11371                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11372            }
11373        }
11374
11375        if (appErrorIntent != null) {
11376            try {
11377                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11378            } catch (ActivityNotFoundException e) {
11379                Slog.w(TAG, "bug report receiver dissappeared", e);
11380            }
11381        }
11382    }
11383
11384    Intent createAppErrorIntentLocked(ProcessRecord r,
11385            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11386        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11387        if (report == null) {
11388            return null;
11389        }
11390        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11391        result.setComponent(r.errorReportReceiver);
11392        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11393        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11394        return result;
11395    }
11396
11397    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11398            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11399        if (r.errorReportReceiver == null) {
11400            return null;
11401        }
11402
11403        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11404            return null;
11405        }
11406
11407        ApplicationErrorReport report = new ApplicationErrorReport();
11408        report.packageName = r.info.packageName;
11409        report.installerPackageName = r.errorReportReceiver.getPackageName();
11410        report.processName = r.processName;
11411        report.time = timeMillis;
11412        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11413
11414        if (r.crashing || r.forceCrashReport) {
11415            report.type = ApplicationErrorReport.TYPE_CRASH;
11416            report.crashInfo = crashInfo;
11417        } else if (r.notResponding) {
11418            report.type = ApplicationErrorReport.TYPE_ANR;
11419            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11420
11421            report.anrInfo.activity = r.notRespondingReport.tag;
11422            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11423            report.anrInfo.info = r.notRespondingReport.longMsg;
11424        }
11425
11426        return report;
11427    }
11428
11429    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11430        enforceNotIsolatedCaller("getProcessesInErrorState");
11431        // assume our apps are happy - lazy create the list
11432        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11433
11434        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11435                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11436        int userId = UserHandle.getUserId(Binder.getCallingUid());
11437
11438        synchronized (this) {
11439
11440            // iterate across all processes
11441            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11442                ProcessRecord app = mLruProcesses.get(i);
11443                if (!allUsers && app.userId != userId) {
11444                    continue;
11445                }
11446                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11447                    // This one's in trouble, so we'll generate a report for it
11448                    // crashes are higher priority (in case there's a crash *and* an anr)
11449                    ActivityManager.ProcessErrorStateInfo report = null;
11450                    if (app.crashing) {
11451                        report = app.crashingReport;
11452                    } else if (app.notResponding) {
11453                        report = app.notRespondingReport;
11454                    }
11455
11456                    if (report != null) {
11457                        if (errList == null) {
11458                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11459                        }
11460                        errList.add(report);
11461                    } else {
11462                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11463                                " crashing = " + app.crashing +
11464                                " notResponding = " + app.notResponding);
11465                    }
11466                }
11467            }
11468        }
11469
11470        return errList;
11471    }
11472
11473    static int procStateToImportance(int procState, int memAdj,
11474            ActivityManager.RunningAppProcessInfo currApp) {
11475        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11476        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11477            currApp.lru = memAdj;
11478        } else {
11479            currApp.lru = 0;
11480        }
11481        return imp;
11482    }
11483
11484    private void fillInProcMemInfo(ProcessRecord app,
11485            ActivityManager.RunningAppProcessInfo outInfo) {
11486        outInfo.pid = app.pid;
11487        outInfo.uid = app.info.uid;
11488        if (mHeavyWeightProcess == app) {
11489            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11490        }
11491        if (app.persistent) {
11492            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11493        }
11494        if (app.activities.size() > 0) {
11495            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11496        }
11497        outInfo.lastTrimLevel = app.trimMemoryLevel;
11498        int adj = app.curAdj;
11499        int procState = app.curProcState;
11500        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11501        outInfo.importanceReasonCode = app.adjTypeCode;
11502        outInfo.processState = app.curProcState;
11503    }
11504
11505    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11506        enforceNotIsolatedCaller("getRunningAppProcesses");
11507        // Lazy instantiation of list
11508        List<ActivityManager.RunningAppProcessInfo> runList = null;
11509        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11510                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11511        int userId = UserHandle.getUserId(Binder.getCallingUid());
11512        synchronized (this) {
11513            // Iterate across all processes
11514            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11515                ProcessRecord app = mLruProcesses.get(i);
11516                if (!allUsers && app.userId != userId) {
11517                    continue;
11518                }
11519                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11520                    // Generate process state info for running application
11521                    ActivityManager.RunningAppProcessInfo currApp =
11522                        new ActivityManager.RunningAppProcessInfo(app.processName,
11523                                app.pid, app.getPackageList());
11524                    fillInProcMemInfo(app, currApp);
11525                    if (app.adjSource instanceof ProcessRecord) {
11526                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11527                        currApp.importanceReasonImportance =
11528                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11529                                        app.adjSourceProcState);
11530                    } else if (app.adjSource instanceof ActivityRecord) {
11531                        ActivityRecord r = (ActivityRecord)app.adjSource;
11532                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11533                    }
11534                    if (app.adjTarget instanceof ComponentName) {
11535                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11536                    }
11537                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11538                    //        + " lru=" + currApp.lru);
11539                    if (runList == null) {
11540                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11541                    }
11542                    runList.add(currApp);
11543                }
11544            }
11545        }
11546        return runList;
11547    }
11548
11549    public List<ApplicationInfo> getRunningExternalApplications() {
11550        enforceNotIsolatedCaller("getRunningExternalApplications");
11551        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11552        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11553        if (runningApps != null && runningApps.size() > 0) {
11554            Set<String> extList = new HashSet<String>();
11555            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11556                if (app.pkgList != null) {
11557                    for (String pkg : app.pkgList) {
11558                        extList.add(pkg);
11559                    }
11560                }
11561            }
11562            IPackageManager pm = AppGlobals.getPackageManager();
11563            for (String pkg : extList) {
11564                try {
11565                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11566                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11567                        retList.add(info);
11568                    }
11569                } catch (RemoteException e) {
11570                }
11571            }
11572        }
11573        return retList;
11574    }
11575
11576    @Override
11577    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11578        enforceNotIsolatedCaller("getMyMemoryState");
11579        synchronized (this) {
11580            ProcessRecord proc;
11581            synchronized (mPidsSelfLocked) {
11582                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11583            }
11584            fillInProcMemInfo(proc, outInfo);
11585        }
11586    }
11587
11588    @Override
11589    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11590        if (checkCallingPermission(android.Manifest.permission.DUMP)
11591                != PackageManager.PERMISSION_GRANTED) {
11592            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11593                    + Binder.getCallingPid()
11594                    + ", uid=" + Binder.getCallingUid()
11595                    + " without permission "
11596                    + android.Manifest.permission.DUMP);
11597            return;
11598        }
11599
11600        boolean dumpAll = false;
11601        boolean dumpClient = false;
11602        String dumpPackage = null;
11603
11604        int opti = 0;
11605        while (opti < args.length) {
11606            String opt = args[opti];
11607            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11608                break;
11609            }
11610            opti++;
11611            if ("-a".equals(opt)) {
11612                dumpAll = true;
11613            } else if ("-c".equals(opt)) {
11614                dumpClient = true;
11615            } else if ("-h".equals(opt)) {
11616                pw.println("Activity manager dump options:");
11617                pw.println("  [-a] [-c] [-h] [cmd] ...");
11618                pw.println("  cmd may be one of:");
11619                pw.println("    a[ctivities]: activity stack state");
11620                pw.println("    r[recents]: recent activities state");
11621                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11622                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11623                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11624                pw.println("    o[om]: out of memory management");
11625                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11626                pw.println("    provider [COMP_SPEC]: provider client-side state");
11627                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11628                pw.println("    service [COMP_SPEC]: service client-side state");
11629                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11630                pw.println("    all: dump all activities");
11631                pw.println("    top: dump the top activity");
11632                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11633                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11634                pw.println("    a partial substring in a component name, a");
11635                pw.println("    hex object identifier.");
11636                pw.println("  -a: include all available server state.");
11637                pw.println("  -c: include client state.");
11638                return;
11639            } else {
11640                pw.println("Unknown argument: " + opt + "; use -h for help");
11641            }
11642        }
11643
11644        long origId = Binder.clearCallingIdentity();
11645        boolean more = false;
11646        // Is the caller requesting to dump a particular piece of data?
11647        if (opti < args.length) {
11648            String cmd = args[opti];
11649            opti++;
11650            if ("activities".equals(cmd) || "a".equals(cmd)) {
11651                synchronized (this) {
11652                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11653                }
11654            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11655                synchronized (this) {
11656                    dumpRecentsLocked(fd, pw, args, opti, true, null);
11657                }
11658            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11659                String[] newArgs;
11660                String name;
11661                if (opti >= args.length) {
11662                    name = null;
11663                    newArgs = EMPTY_STRING_ARRAY;
11664                } else {
11665                    name = args[opti];
11666                    opti++;
11667                    newArgs = new String[args.length - opti];
11668                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11669                            args.length - opti);
11670                }
11671                synchronized (this) {
11672                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11673                }
11674            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11675                String[] newArgs;
11676                String name;
11677                if (opti >= args.length) {
11678                    name = null;
11679                    newArgs = EMPTY_STRING_ARRAY;
11680                } else {
11681                    name = args[opti];
11682                    opti++;
11683                    newArgs = new String[args.length - opti];
11684                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11685                            args.length - opti);
11686                }
11687                synchronized (this) {
11688                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11689                }
11690            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11691                String[] newArgs;
11692                String name;
11693                if (opti >= args.length) {
11694                    name = null;
11695                    newArgs = EMPTY_STRING_ARRAY;
11696                } else {
11697                    name = args[opti];
11698                    opti++;
11699                    newArgs = new String[args.length - opti];
11700                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11701                            args.length - opti);
11702                }
11703                synchronized (this) {
11704                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11705                }
11706            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11707                synchronized (this) {
11708                    dumpOomLocked(fd, pw, args, opti, true);
11709                }
11710            } else if ("provider".equals(cmd)) {
11711                String[] newArgs;
11712                String name;
11713                if (opti >= args.length) {
11714                    name = null;
11715                    newArgs = EMPTY_STRING_ARRAY;
11716                } else {
11717                    name = args[opti];
11718                    opti++;
11719                    newArgs = new String[args.length - opti];
11720                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11721                }
11722                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11723                    pw.println("No providers match: " + name);
11724                    pw.println("Use -h for help.");
11725                }
11726            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11727                synchronized (this) {
11728                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11729                }
11730            } else if ("service".equals(cmd)) {
11731                String[] newArgs;
11732                String name;
11733                if (opti >= args.length) {
11734                    name = null;
11735                    newArgs = EMPTY_STRING_ARRAY;
11736                } else {
11737                    name = args[opti];
11738                    opti++;
11739                    newArgs = new String[args.length - opti];
11740                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11741                            args.length - opti);
11742                }
11743                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11744                    pw.println("No services match: " + name);
11745                    pw.println("Use -h for help.");
11746                }
11747            } else if ("package".equals(cmd)) {
11748                String[] newArgs;
11749                if (opti >= args.length) {
11750                    pw.println("package: no package name specified");
11751                    pw.println("Use -h for help.");
11752                } else {
11753                    dumpPackage = args[opti];
11754                    opti++;
11755                    newArgs = new String[args.length - opti];
11756                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11757                            args.length - opti);
11758                    args = newArgs;
11759                    opti = 0;
11760                    more = true;
11761                }
11762            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11763                synchronized (this) {
11764                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11765                }
11766            } else {
11767                // Dumping a single activity?
11768                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11769                    pw.println("Bad activity command, or no activities match: " + cmd);
11770                    pw.println("Use -h for help.");
11771                }
11772            }
11773            if (!more) {
11774                Binder.restoreCallingIdentity(origId);
11775                return;
11776            }
11777        }
11778
11779        // No piece of data specified, dump everything.
11780        synchronized (this) {
11781            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11782            pw.println();
11783            if (dumpAll) {
11784                pw.println("-------------------------------------------------------------------------------");
11785            }
11786            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11787            pw.println();
11788            if (dumpAll) {
11789                pw.println("-------------------------------------------------------------------------------");
11790            }
11791            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11792            pw.println();
11793            if (dumpAll) {
11794                pw.println("-------------------------------------------------------------------------------");
11795            }
11796            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11797            pw.println();
11798            if (dumpAll) {
11799                pw.println("-------------------------------------------------------------------------------");
11800            }
11801            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11802            pw.println();
11803            if (dumpAll) {
11804                pw.println("-------------------------------------------------------------------------------");
11805            }
11806            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11807            pw.println();
11808            if (dumpAll) {
11809                pw.println("-------------------------------------------------------------------------------");
11810            }
11811            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11812        }
11813        Binder.restoreCallingIdentity(origId);
11814    }
11815
11816    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11817            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11818        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11819
11820        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11821                dumpPackage);
11822        boolean needSep = printedAnything;
11823
11824        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11825                dumpPackage, needSep, "  mFocusedActivity: ");
11826        if (printed) {
11827            printedAnything = true;
11828            needSep = false;
11829        }
11830
11831        if (dumpPackage == null) {
11832            if (needSep) {
11833                pw.println();
11834            }
11835            needSep = true;
11836            printedAnything = true;
11837            mStackSupervisor.dump(pw, "  ");
11838        }
11839
11840        if (!printedAnything) {
11841            pw.println("  (nothing)");
11842        }
11843    }
11844
11845    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11846            int opti, boolean dumpAll, String dumpPackage) {
11847        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
11848
11849        boolean printedAnything = false;
11850
11851        if (mRecentTasks.size() > 0) {
11852            boolean printedHeader = false;
11853
11854            final int N = mRecentTasks.size();
11855            for (int i=0; i<N; i++) {
11856                TaskRecord tr = mRecentTasks.get(i);
11857                if (dumpPackage != null) {
11858                    if (tr.realActivity == null ||
11859                            !dumpPackage.equals(tr.realActivity)) {
11860                        continue;
11861                    }
11862                }
11863                if (!printedHeader) {
11864                    pw.println("  Recent tasks:");
11865                    printedHeader = true;
11866                    printedAnything = true;
11867                }
11868                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11869                        pw.println(tr);
11870                if (dumpAll) {
11871                    mRecentTasks.get(i).dump(pw, "    ");
11872                }
11873            }
11874        }
11875
11876        if (!printedAnything) {
11877            pw.println("  (nothing)");
11878        }
11879    }
11880
11881    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11882            int opti, boolean dumpAll, String dumpPackage) {
11883        boolean needSep = false;
11884        boolean printedAnything = false;
11885        int numPers = 0;
11886
11887        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11888
11889        if (dumpAll) {
11890            final int NP = mProcessNames.getMap().size();
11891            for (int ip=0; ip<NP; ip++) {
11892                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11893                final int NA = procs.size();
11894                for (int ia=0; ia<NA; ia++) {
11895                    ProcessRecord r = procs.valueAt(ia);
11896                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11897                        continue;
11898                    }
11899                    if (!needSep) {
11900                        pw.println("  All known processes:");
11901                        needSep = true;
11902                        printedAnything = true;
11903                    }
11904                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11905                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11906                        pw.print(" "); pw.println(r);
11907                    r.dump(pw, "    ");
11908                    if (r.persistent) {
11909                        numPers++;
11910                    }
11911                }
11912            }
11913        }
11914
11915        if (mIsolatedProcesses.size() > 0) {
11916            boolean printed = false;
11917            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11918                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11919                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11920                    continue;
11921                }
11922                if (!printed) {
11923                    if (needSep) {
11924                        pw.println();
11925                    }
11926                    pw.println("  Isolated process list (sorted by uid):");
11927                    printedAnything = true;
11928                    printed = true;
11929                    needSep = true;
11930                }
11931                pw.println(String.format("%sIsolated #%2d: %s",
11932                        "    ", i, r.toString()));
11933            }
11934        }
11935
11936        if (mLruProcesses.size() > 0) {
11937            if (needSep) {
11938                pw.println();
11939            }
11940            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11941                    pw.print(" total, non-act at ");
11942                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11943                    pw.print(", non-svc at ");
11944                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11945                    pw.println("):");
11946            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11947            needSep = true;
11948            printedAnything = true;
11949        }
11950
11951        if (dumpAll || dumpPackage != null) {
11952            synchronized (mPidsSelfLocked) {
11953                boolean printed = false;
11954                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11955                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11956                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11957                        continue;
11958                    }
11959                    if (!printed) {
11960                        if (needSep) pw.println();
11961                        needSep = true;
11962                        pw.println("  PID mappings:");
11963                        printed = true;
11964                        printedAnything = true;
11965                    }
11966                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11967                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11968                }
11969            }
11970        }
11971
11972        if (mForegroundProcesses.size() > 0) {
11973            synchronized (mPidsSelfLocked) {
11974                boolean printed = false;
11975                for (int i=0; i<mForegroundProcesses.size(); i++) {
11976                    ProcessRecord r = mPidsSelfLocked.get(
11977                            mForegroundProcesses.valueAt(i).pid);
11978                    if (dumpPackage != null && (r == null
11979                            || !r.pkgList.containsKey(dumpPackage))) {
11980                        continue;
11981                    }
11982                    if (!printed) {
11983                        if (needSep) pw.println();
11984                        needSep = true;
11985                        pw.println("  Foreground Processes:");
11986                        printed = true;
11987                        printedAnything = true;
11988                    }
11989                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11990                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11991                }
11992            }
11993        }
11994
11995        if (mPersistentStartingProcesses.size() > 0) {
11996            if (needSep) pw.println();
11997            needSep = true;
11998            printedAnything = true;
11999            pw.println("  Persisent processes that are starting:");
12000            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12001                    "Starting Norm", "Restarting PERS", dumpPackage);
12002        }
12003
12004        if (mRemovedProcesses.size() > 0) {
12005            if (needSep) pw.println();
12006            needSep = true;
12007            printedAnything = true;
12008            pw.println("  Processes that are being removed:");
12009            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12010                    "Removed Norm", "Removed PERS", dumpPackage);
12011        }
12012
12013        if (mProcessesOnHold.size() > 0) {
12014            if (needSep) pw.println();
12015            needSep = true;
12016            printedAnything = true;
12017            pw.println("  Processes that are on old until the system is ready:");
12018            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12019                    "OnHold Norm", "OnHold PERS", dumpPackage);
12020        }
12021
12022        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12023
12024        if (mProcessCrashTimes.getMap().size() > 0) {
12025            boolean printed = false;
12026            long now = SystemClock.uptimeMillis();
12027            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12028            final int NP = pmap.size();
12029            for (int ip=0; ip<NP; ip++) {
12030                String pname = pmap.keyAt(ip);
12031                SparseArray<Long> uids = pmap.valueAt(ip);
12032                final int N = uids.size();
12033                for (int i=0; i<N; i++) {
12034                    int puid = uids.keyAt(i);
12035                    ProcessRecord r = mProcessNames.get(pname, puid);
12036                    if (dumpPackage != null && (r == null
12037                            || !r.pkgList.containsKey(dumpPackage))) {
12038                        continue;
12039                    }
12040                    if (!printed) {
12041                        if (needSep) pw.println();
12042                        needSep = true;
12043                        pw.println("  Time since processes crashed:");
12044                        printed = true;
12045                        printedAnything = true;
12046                    }
12047                    pw.print("    Process "); pw.print(pname);
12048                            pw.print(" uid "); pw.print(puid);
12049                            pw.print(": last crashed ");
12050                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12051                            pw.println(" ago");
12052                }
12053            }
12054        }
12055
12056        if (mBadProcesses.getMap().size() > 0) {
12057            boolean printed = false;
12058            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12059            final int NP = pmap.size();
12060            for (int ip=0; ip<NP; ip++) {
12061                String pname = pmap.keyAt(ip);
12062                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12063                final int N = uids.size();
12064                for (int i=0; i<N; i++) {
12065                    int puid = uids.keyAt(i);
12066                    ProcessRecord r = mProcessNames.get(pname, puid);
12067                    if (dumpPackage != null && (r == null
12068                            || !r.pkgList.containsKey(dumpPackage))) {
12069                        continue;
12070                    }
12071                    if (!printed) {
12072                        if (needSep) pw.println();
12073                        needSep = true;
12074                        pw.println("  Bad processes:");
12075                        printedAnything = true;
12076                    }
12077                    BadProcessInfo info = uids.valueAt(i);
12078                    pw.print("    Bad process "); pw.print(pname);
12079                            pw.print(" uid "); pw.print(puid);
12080                            pw.print(": crashed at time "); pw.println(info.time);
12081                    if (info.shortMsg != null) {
12082                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12083                    }
12084                    if (info.longMsg != null) {
12085                        pw.print("      Long msg: "); pw.println(info.longMsg);
12086                    }
12087                    if (info.stack != null) {
12088                        pw.println("      Stack:");
12089                        int lastPos = 0;
12090                        for (int pos=0; pos<info.stack.length(); pos++) {
12091                            if (info.stack.charAt(pos) == '\n') {
12092                                pw.print("        ");
12093                                pw.write(info.stack, lastPos, pos-lastPos);
12094                                pw.println();
12095                                lastPos = pos+1;
12096                            }
12097                        }
12098                        if (lastPos < info.stack.length()) {
12099                            pw.print("        ");
12100                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12101                            pw.println();
12102                        }
12103                    }
12104                }
12105            }
12106        }
12107
12108        if (dumpPackage == null) {
12109            pw.println();
12110            needSep = false;
12111            pw.println("  mStartedUsers:");
12112            for (int i=0; i<mStartedUsers.size(); i++) {
12113                UserStartedState uss = mStartedUsers.valueAt(i);
12114                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12115                        pw.print(": "); uss.dump("", pw);
12116            }
12117            pw.print("  mStartedUserArray: [");
12118            for (int i=0; i<mStartedUserArray.length; i++) {
12119                if (i > 0) pw.print(", ");
12120                pw.print(mStartedUserArray[i]);
12121            }
12122            pw.println("]");
12123            pw.print("  mUserLru: [");
12124            for (int i=0; i<mUserLru.size(); i++) {
12125                if (i > 0) pw.print(", ");
12126                pw.print(mUserLru.get(i));
12127            }
12128            pw.println("]");
12129            if (dumpAll) {
12130                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12131            }
12132            synchronized (mUserProfileGroupIdsSelfLocked) {
12133                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12134                    pw.println("  mUserProfileGroupIds:");
12135                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12136                        pw.print("    User #");
12137                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12138                        pw.print(" -> profile #");
12139                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12140                    }
12141                }
12142            }
12143        }
12144        if (mHomeProcess != null && (dumpPackage == null
12145                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12146            if (needSep) {
12147                pw.println();
12148                needSep = false;
12149            }
12150            pw.println("  mHomeProcess: " + mHomeProcess);
12151        }
12152        if (mPreviousProcess != null && (dumpPackage == null
12153                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12154            if (needSep) {
12155                pw.println();
12156                needSep = false;
12157            }
12158            pw.println("  mPreviousProcess: " + mPreviousProcess);
12159        }
12160        if (dumpAll) {
12161            StringBuilder sb = new StringBuilder(128);
12162            sb.append("  mPreviousProcessVisibleTime: ");
12163            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12164            pw.println(sb);
12165        }
12166        if (mHeavyWeightProcess != null && (dumpPackage == null
12167                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12168            if (needSep) {
12169                pw.println();
12170                needSep = false;
12171            }
12172            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12173        }
12174        if (dumpPackage == null) {
12175            pw.println("  mConfiguration: " + mConfiguration);
12176        }
12177        if (dumpAll) {
12178            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12179            if (mCompatModePackages.getPackages().size() > 0) {
12180                boolean printed = false;
12181                for (Map.Entry<String, Integer> entry
12182                        : mCompatModePackages.getPackages().entrySet()) {
12183                    String pkg = entry.getKey();
12184                    int mode = entry.getValue();
12185                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12186                        continue;
12187                    }
12188                    if (!printed) {
12189                        pw.println("  mScreenCompatPackages:");
12190                        printed = true;
12191                    }
12192                    pw.print("    "); pw.print(pkg); pw.print(": ");
12193                            pw.print(mode); pw.println();
12194                }
12195            }
12196        }
12197        if (dumpPackage == null) {
12198            if (mSleeping || mWentToSleep || mLockScreenShown) {
12199                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12200                        + " mLockScreenShown " + mLockScreenShown);
12201            }
12202            if (mShuttingDown || mRunningVoice) {
12203                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12204            }
12205        }
12206        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12207                || mOrigWaitForDebugger) {
12208            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12209                    || dumpPackage.equals(mOrigDebugApp)) {
12210                if (needSep) {
12211                    pw.println();
12212                    needSep = false;
12213                }
12214                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12215                        + " mDebugTransient=" + mDebugTransient
12216                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12217            }
12218        }
12219        if (mOpenGlTraceApp != null) {
12220            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12221                if (needSep) {
12222                    pw.println();
12223                    needSep = false;
12224                }
12225                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12226            }
12227        }
12228        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12229                || mProfileFd != null) {
12230            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12231                if (needSep) {
12232                    pw.println();
12233                    needSep = false;
12234                }
12235                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12236                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12237                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12238                        + mAutoStopProfiler);
12239            }
12240        }
12241        if (dumpPackage == null) {
12242            if (mAlwaysFinishActivities || mController != null) {
12243                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12244                        + " mController=" + mController);
12245            }
12246            if (dumpAll) {
12247                pw.println("  Total persistent processes: " + numPers);
12248                pw.println("  mProcessesReady=" + mProcessesReady
12249                        + " mSystemReady=" + mSystemReady);
12250                pw.println("  mBooting=" + mBooting
12251                        + " mBooted=" + mBooted
12252                        + " mFactoryTest=" + mFactoryTest);
12253                pw.print("  mLastPowerCheckRealtime=");
12254                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12255                        pw.println("");
12256                pw.print("  mLastPowerCheckUptime=");
12257                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12258                        pw.println("");
12259                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12260                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12261                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12262                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12263                        + " (" + mLruProcesses.size() + " total)"
12264                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12265                        + " mNumServiceProcs=" + mNumServiceProcs
12266                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12267                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12268                        + " mLastMemoryLevel" + mLastMemoryLevel
12269                        + " mLastNumProcesses" + mLastNumProcesses);
12270                long now = SystemClock.uptimeMillis();
12271                pw.print("  mLastIdleTime=");
12272                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12273                        pw.print(" mLowRamSinceLastIdle=");
12274                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12275                        pw.println();
12276            }
12277        }
12278
12279        if (!printedAnything) {
12280            pw.println("  (nothing)");
12281        }
12282    }
12283
12284    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12285            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12286        if (mProcessesToGc.size() > 0) {
12287            boolean printed = false;
12288            long now = SystemClock.uptimeMillis();
12289            for (int i=0; i<mProcessesToGc.size(); i++) {
12290                ProcessRecord proc = mProcessesToGc.get(i);
12291                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12292                    continue;
12293                }
12294                if (!printed) {
12295                    if (needSep) pw.println();
12296                    needSep = true;
12297                    pw.println("  Processes that are waiting to GC:");
12298                    printed = true;
12299                }
12300                pw.print("    Process "); pw.println(proc);
12301                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12302                        pw.print(", last gced=");
12303                        pw.print(now-proc.lastRequestedGc);
12304                        pw.print(" ms ago, last lowMem=");
12305                        pw.print(now-proc.lastLowMemory);
12306                        pw.println(" ms ago");
12307
12308            }
12309        }
12310        return needSep;
12311    }
12312
12313    void printOomLevel(PrintWriter pw, String name, int adj) {
12314        pw.print("    ");
12315        if (adj >= 0) {
12316            pw.print(' ');
12317            if (adj < 10) pw.print(' ');
12318        } else {
12319            if (adj > -10) pw.print(' ');
12320        }
12321        pw.print(adj);
12322        pw.print(": ");
12323        pw.print(name);
12324        pw.print(" (");
12325        pw.print(mProcessList.getMemLevel(adj)/1024);
12326        pw.println(" kB)");
12327    }
12328
12329    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12330            int opti, boolean dumpAll) {
12331        boolean needSep = false;
12332
12333        if (mLruProcesses.size() > 0) {
12334            if (needSep) pw.println();
12335            needSep = true;
12336            pw.println("  OOM levels:");
12337            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12338            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12339            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12340            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12341            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12342            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12343            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12344            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12345            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12346            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12347            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12348            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12349            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12350
12351            if (needSep) pw.println();
12352            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12353                    pw.print(" total, non-act at ");
12354                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12355                    pw.print(", non-svc at ");
12356                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12357                    pw.println("):");
12358            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12359            needSep = true;
12360        }
12361
12362        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12363
12364        pw.println();
12365        pw.println("  mHomeProcess: " + mHomeProcess);
12366        pw.println("  mPreviousProcess: " + mPreviousProcess);
12367        if (mHeavyWeightProcess != null) {
12368            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12369        }
12370
12371        return true;
12372    }
12373
12374    /**
12375     * There are three ways to call this:
12376     *  - no provider specified: dump all the providers
12377     *  - a flattened component name that matched an existing provider was specified as the
12378     *    first arg: dump that one provider
12379     *  - the first arg isn't the flattened component name of an existing provider:
12380     *    dump all providers whose component contains the first arg as a substring
12381     */
12382    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12383            int opti, boolean dumpAll) {
12384        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12385    }
12386
12387    static class ItemMatcher {
12388        ArrayList<ComponentName> components;
12389        ArrayList<String> strings;
12390        ArrayList<Integer> objects;
12391        boolean all;
12392
12393        ItemMatcher() {
12394            all = true;
12395        }
12396
12397        void build(String name) {
12398            ComponentName componentName = ComponentName.unflattenFromString(name);
12399            if (componentName != null) {
12400                if (components == null) {
12401                    components = new ArrayList<ComponentName>();
12402                }
12403                components.add(componentName);
12404                all = false;
12405            } else {
12406                int objectId = 0;
12407                // Not a '/' separated full component name; maybe an object ID?
12408                try {
12409                    objectId = Integer.parseInt(name, 16);
12410                    if (objects == null) {
12411                        objects = new ArrayList<Integer>();
12412                    }
12413                    objects.add(objectId);
12414                    all = false;
12415                } catch (RuntimeException e) {
12416                    // Not an integer; just do string match.
12417                    if (strings == null) {
12418                        strings = new ArrayList<String>();
12419                    }
12420                    strings.add(name);
12421                    all = false;
12422                }
12423            }
12424        }
12425
12426        int build(String[] args, int opti) {
12427            for (; opti<args.length; opti++) {
12428                String name = args[opti];
12429                if ("--".equals(name)) {
12430                    return opti+1;
12431                }
12432                build(name);
12433            }
12434            return opti;
12435        }
12436
12437        boolean match(Object object, ComponentName comp) {
12438            if (all) {
12439                return true;
12440            }
12441            if (components != null) {
12442                for (int i=0; i<components.size(); i++) {
12443                    if (components.get(i).equals(comp)) {
12444                        return true;
12445                    }
12446                }
12447            }
12448            if (objects != null) {
12449                for (int i=0; i<objects.size(); i++) {
12450                    if (System.identityHashCode(object) == objects.get(i)) {
12451                        return true;
12452                    }
12453                }
12454            }
12455            if (strings != null) {
12456                String flat = comp.flattenToString();
12457                for (int i=0; i<strings.size(); i++) {
12458                    if (flat.contains(strings.get(i))) {
12459                        return true;
12460                    }
12461                }
12462            }
12463            return false;
12464        }
12465    }
12466
12467    /**
12468     * There are three things that cmd can be:
12469     *  - a flattened component name that matches an existing activity
12470     *  - the cmd arg isn't the flattened component name of an existing activity:
12471     *    dump all activity whose component contains the cmd as a substring
12472     *  - A hex number of the ActivityRecord object instance.
12473     */
12474    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12475            int opti, boolean dumpAll) {
12476        ArrayList<ActivityRecord> activities;
12477
12478        synchronized (this) {
12479            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12480        }
12481
12482        if (activities.size() <= 0) {
12483            return false;
12484        }
12485
12486        String[] newArgs = new String[args.length - opti];
12487        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12488
12489        TaskRecord lastTask = null;
12490        boolean needSep = false;
12491        for (int i=activities.size()-1; i>=0; i--) {
12492            ActivityRecord r = activities.get(i);
12493            if (needSep) {
12494                pw.println();
12495            }
12496            needSep = true;
12497            synchronized (this) {
12498                if (lastTask != r.task) {
12499                    lastTask = r.task;
12500                    pw.print("TASK "); pw.print(lastTask.affinity);
12501                            pw.print(" id="); pw.println(lastTask.taskId);
12502                    if (dumpAll) {
12503                        lastTask.dump(pw, "  ");
12504                    }
12505                }
12506            }
12507            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12508        }
12509        return true;
12510    }
12511
12512    /**
12513     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12514     * there is a thread associated with the activity.
12515     */
12516    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12517            final ActivityRecord r, String[] args, boolean dumpAll) {
12518        String innerPrefix = prefix + "  ";
12519        synchronized (this) {
12520            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12521                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12522                    pw.print(" pid=");
12523                    if (r.app != null) pw.println(r.app.pid);
12524                    else pw.println("(not running)");
12525            if (dumpAll) {
12526                r.dump(pw, innerPrefix);
12527            }
12528        }
12529        if (r.app != null && r.app.thread != null) {
12530            // flush anything that is already in the PrintWriter since the thread is going
12531            // to write to the file descriptor directly
12532            pw.flush();
12533            try {
12534                TransferPipe tp = new TransferPipe();
12535                try {
12536                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12537                            r.appToken, innerPrefix, args);
12538                    tp.go(fd);
12539                } finally {
12540                    tp.kill();
12541                }
12542            } catch (IOException e) {
12543                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12544            } catch (RemoteException e) {
12545                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12546            }
12547        }
12548    }
12549
12550    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12551            int opti, boolean dumpAll, String dumpPackage) {
12552        boolean needSep = false;
12553        boolean onlyHistory = false;
12554        boolean printedAnything = false;
12555
12556        if ("history".equals(dumpPackage)) {
12557            if (opti < args.length && "-s".equals(args[opti])) {
12558                dumpAll = false;
12559            }
12560            onlyHistory = true;
12561            dumpPackage = null;
12562        }
12563
12564        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12565        if (!onlyHistory && dumpAll) {
12566            if (mRegisteredReceivers.size() > 0) {
12567                boolean printed = false;
12568                Iterator it = mRegisteredReceivers.values().iterator();
12569                while (it.hasNext()) {
12570                    ReceiverList r = (ReceiverList)it.next();
12571                    if (dumpPackage != null && (r.app == null ||
12572                            !dumpPackage.equals(r.app.info.packageName))) {
12573                        continue;
12574                    }
12575                    if (!printed) {
12576                        pw.println("  Registered Receivers:");
12577                        needSep = true;
12578                        printed = true;
12579                        printedAnything = true;
12580                    }
12581                    pw.print("  * "); pw.println(r);
12582                    r.dump(pw, "    ");
12583                }
12584            }
12585
12586            if (mReceiverResolver.dump(pw, needSep ?
12587                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12588                    "    ", dumpPackage, false)) {
12589                needSep = true;
12590                printedAnything = true;
12591            }
12592        }
12593
12594        for (BroadcastQueue q : mBroadcastQueues) {
12595            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12596            printedAnything |= needSep;
12597        }
12598
12599        needSep = true;
12600
12601        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12602            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12603                if (needSep) {
12604                    pw.println();
12605                }
12606                needSep = true;
12607                printedAnything = true;
12608                pw.print("  Sticky broadcasts for user ");
12609                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12610                StringBuilder sb = new StringBuilder(128);
12611                for (Map.Entry<String, ArrayList<Intent>> ent
12612                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12613                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12614                    if (dumpAll) {
12615                        pw.println(":");
12616                        ArrayList<Intent> intents = ent.getValue();
12617                        final int N = intents.size();
12618                        for (int i=0; i<N; i++) {
12619                            sb.setLength(0);
12620                            sb.append("    Intent: ");
12621                            intents.get(i).toShortString(sb, false, true, false, false);
12622                            pw.println(sb.toString());
12623                            Bundle bundle = intents.get(i).getExtras();
12624                            if (bundle != null) {
12625                                pw.print("      ");
12626                                pw.println(bundle.toString());
12627                            }
12628                        }
12629                    } else {
12630                        pw.println("");
12631                    }
12632                }
12633            }
12634        }
12635
12636        if (!onlyHistory && dumpAll) {
12637            pw.println();
12638            for (BroadcastQueue queue : mBroadcastQueues) {
12639                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12640                        + queue.mBroadcastsScheduled);
12641            }
12642            pw.println("  mHandler:");
12643            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12644            needSep = true;
12645            printedAnything = true;
12646        }
12647
12648        if (!printedAnything) {
12649            pw.println("  (nothing)");
12650        }
12651    }
12652
12653    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12654            int opti, boolean dumpAll, String dumpPackage) {
12655        boolean needSep;
12656        boolean printedAnything = false;
12657
12658        ItemMatcher matcher = new ItemMatcher();
12659        matcher.build(args, opti);
12660
12661        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12662
12663        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12664        printedAnything |= needSep;
12665
12666        if (mLaunchingProviders.size() > 0) {
12667            boolean printed = false;
12668            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12669                ContentProviderRecord r = mLaunchingProviders.get(i);
12670                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12671                    continue;
12672                }
12673                if (!printed) {
12674                    if (needSep) pw.println();
12675                    needSep = true;
12676                    pw.println("  Launching content providers:");
12677                    printed = true;
12678                    printedAnything = true;
12679                }
12680                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12681                        pw.println(r);
12682            }
12683        }
12684
12685        if (mGrantedUriPermissions.size() > 0) {
12686            boolean printed = false;
12687            int dumpUid = -2;
12688            if (dumpPackage != null) {
12689                try {
12690                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12691                } catch (NameNotFoundException e) {
12692                    dumpUid = -1;
12693                }
12694            }
12695            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12696                int uid = mGrantedUriPermissions.keyAt(i);
12697                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12698                    continue;
12699                }
12700                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12701                if (!printed) {
12702                    if (needSep) pw.println();
12703                    needSep = true;
12704                    pw.println("  Granted Uri Permissions:");
12705                    printed = true;
12706                    printedAnything = true;
12707                }
12708                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12709                for (UriPermission perm : perms.values()) {
12710                    pw.print("    "); pw.println(perm);
12711                    if (dumpAll) {
12712                        perm.dump(pw, "      ");
12713                    }
12714                }
12715            }
12716        }
12717
12718        if (!printedAnything) {
12719            pw.println("  (nothing)");
12720        }
12721    }
12722
12723    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12724            int opti, boolean dumpAll, String dumpPackage) {
12725        boolean printed = false;
12726
12727        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12728
12729        if (mIntentSenderRecords.size() > 0) {
12730            Iterator<WeakReference<PendingIntentRecord>> it
12731                    = mIntentSenderRecords.values().iterator();
12732            while (it.hasNext()) {
12733                WeakReference<PendingIntentRecord> ref = it.next();
12734                PendingIntentRecord rec = ref != null ? ref.get(): null;
12735                if (dumpPackage != null && (rec == null
12736                        || !dumpPackage.equals(rec.key.packageName))) {
12737                    continue;
12738                }
12739                printed = true;
12740                if (rec != null) {
12741                    pw.print("  * "); pw.println(rec);
12742                    if (dumpAll) {
12743                        rec.dump(pw, "    ");
12744                    }
12745                } else {
12746                    pw.print("  * "); pw.println(ref);
12747                }
12748            }
12749        }
12750
12751        if (!printed) {
12752            pw.println("  (nothing)");
12753        }
12754    }
12755
12756    private static final int dumpProcessList(PrintWriter pw,
12757            ActivityManagerService service, List list,
12758            String prefix, String normalLabel, String persistentLabel,
12759            String dumpPackage) {
12760        int numPers = 0;
12761        final int N = list.size()-1;
12762        for (int i=N; i>=0; i--) {
12763            ProcessRecord r = (ProcessRecord)list.get(i);
12764            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12765                continue;
12766            }
12767            pw.println(String.format("%s%s #%2d: %s",
12768                    prefix, (r.persistent ? persistentLabel : normalLabel),
12769                    i, r.toString()));
12770            if (r.persistent) {
12771                numPers++;
12772            }
12773        }
12774        return numPers;
12775    }
12776
12777    private static final boolean dumpProcessOomList(PrintWriter pw,
12778            ActivityManagerService service, List<ProcessRecord> origList,
12779            String prefix, String normalLabel, String persistentLabel,
12780            boolean inclDetails, String dumpPackage) {
12781
12782        ArrayList<Pair<ProcessRecord, Integer>> list
12783                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12784        for (int i=0; i<origList.size(); i++) {
12785            ProcessRecord r = origList.get(i);
12786            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12787                continue;
12788            }
12789            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12790        }
12791
12792        if (list.size() <= 0) {
12793            return false;
12794        }
12795
12796        Comparator<Pair<ProcessRecord, Integer>> comparator
12797                = new Comparator<Pair<ProcessRecord, Integer>>() {
12798            @Override
12799            public int compare(Pair<ProcessRecord, Integer> object1,
12800                    Pair<ProcessRecord, Integer> object2) {
12801                if (object1.first.setAdj != object2.first.setAdj) {
12802                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12803                }
12804                if (object1.second.intValue() != object2.second.intValue()) {
12805                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12806                }
12807                return 0;
12808            }
12809        };
12810
12811        Collections.sort(list, comparator);
12812
12813        final long curRealtime = SystemClock.elapsedRealtime();
12814        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12815        final long curUptime = SystemClock.uptimeMillis();
12816        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12817
12818        for (int i=list.size()-1; i>=0; i--) {
12819            ProcessRecord r = list.get(i).first;
12820            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12821            char schedGroup;
12822            switch (r.setSchedGroup) {
12823                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12824                    schedGroup = 'B';
12825                    break;
12826                case Process.THREAD_GROUP_DEFAULT:
12827                    schedGroup = 'F';
12828                    break;
12829                default:
12830                    schedGroup = '?';
12831                    break;
12832            }
12833            char foreground;
12834            if (r.foregroundActivities) {
12835                foreground = 'A';
12836            } else if (r.foregroundServices) {
12837                foreground = 'S';
12838            } else {
12839                foreground = ' ';
12840            }
12841            String procState = ProcessList.makeProcStateString(r.curProcState);
12842            pw.print(prefix);
12843            pw.print(r.persistent ? persistentLabel : normalLabel);
12844            pw.print(" #");
12845            int num = (origList.size()-1)-list.get(i).second;
12846            if (num < 10) pw.print(' ');
12847            pw.print(num);
12848            pw.print(": ");
12849            pw.print(oomAdj);
12850            pw.print(' ');
12851            pw.print(schedGroup);
12852            pw.print('/');
12853            pw.print(foreground);
12854            pw.print('/');
12855            pw.print(procState);
12856            pw.print(" trm:");
12857            if (r.trimMemoryLevel < 10) pw.print(' ');
12858            pw.print(r.trimMemoryLevel);
12859            pw.print(' ');
12860            pw.print(r.toShortString());
12861            pw.print(" (");
12862            pw.print(r.adjType);
12863            pw.println(')');
12864            if (r.adjSource != null || r.adjTarget != null) {
12865                pw.print(prefix);
12866                pw.print("    ");
12867                if (r.adjTarget instanceof ComponentName) {
12868                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12869                } else if (r.adjTarget != null) {
12870                    pw.print(r.adjTarget.toString());
12871                } else {
12872                    pw.print("{null}");
12873                }
12874                pw.print("<=");
12875                if (r.adjSource instanceof ProcessRecord) {
12876                    pw.print("Proc{");
12877                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12878                    pw.println("}");
12879                } else if (r.adjSource != null) {
12880                    pw.println(r.adjSource.toString());
12881                } else {
12882                    pw.println("{null}");
12883                }
12884            }
12885            if (inclDetails) {
12886                pw.print(prefix);
12887                pw.print("    ");
12888                pw.print("oom: max="); pw.print(r.maxAdj);
12889                pw.print(" curRaw="); pw.print(r.curRawAdj);
12890                pw.print(" setRaw="); pw.print(r.setRawAdj);
12891                pw.print(" cur="); pw.print(r.curAdj);
12892                pw.print(" set="); pw.println(r.setAdj);
12893                pw.print(prefix);
12894                pw.print("    ");
12895                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12896                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12897                pw.print(" lastPss="); pw.print(r.lastPss);
12898                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12899                pw.print(prefix);
12900                pw.print("    ");
12901                pw.print("cached="); pw.print(r.cached);
12902                pw.print(" empty="); pw.print(r.empty);
12903                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12904
12905                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12906                    if (r.lastWakeTime != 0) {
12907                        long wtime;
12908                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12909                        synchronized (stats) {
12910                            wtime = stats.getProcessWakeTime(r.info.uid,
12911                                    r.pid, curRealtime);
12912                        }
12913                        long timeUsed = wtime - r.lastWakeTime;
12914                        pw.print(prefix);
12915                        pw.print("    ");
12916                        pw.print("keep awake over ");
12917                        TimeUtils.formatDuration(realtimeSince, pw);
12918                        pw.print(" used ");
12919                        TimeUtils.formatDuration(timeUsed, pw);
12920                        pw.print(" (");
12921                        pw.print((timeUsed*100)/realtimeSince);
12922                        pw.println("%)");
12923                    }
12924                    if (r.lastCpuTime != 0) {
12925                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12926                        pw.print(prefix);
12927                        pw.print("    ");
12928                        pw.print("run cpu over ");
12929                        TimeUtils.formatDuration(uptimeSince, pw);
12930                        pw.print(" used ");
12931                        TimeUtils.formatDuration(timeUsed, pw);
12932                        pw.print(" (");
12933                        pw.print((timeUsed*100)/uptimeSince);
12934                        pw.println("%)");
12935                    }
12936                }
12937            }
12938        }
12939        return true;
12940    }
12941
12942    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12943        ArrayList<ProcessRecord> procs;
12944        synchronized (this) {
12945            if (args != null && args.length > start
12946                    && args[start].charAt(0) != '-') {
12947                procs = new ArrayList<ProcessRecord>();
12948                int pid = -1;
12949                try {
12950                    pid = Integer.parseInt(args[start]);
12951                } catch (NumberFormatException e) {
12952                }
12953                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12954                    ProcessRecord proc = mLruProcesses.get(i);
12955                    if (proc.pid == pid) {
12956                        procs.add(proc);
12957                    } else if (proc.processName.equals(args[start])) {
12958                        procs.add(proc);
12959                    }
12960                }
12961                if (procs.size() <= 0) {
12962                    return null;
12963                }
12964            } else {
12965                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12966            }
12967        }
12968        return procs;
12969    }
12970
12971    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12972            PrintWriter pw, String[] args) {
12973        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12974        if (procs == null) {
12975            pw.println("No process found for: " + args[0]);
12976            return;
12977        }
12978
12979        long uptime = SystemClock.uptimeMillis();
12980        long realtime = SystemClock.elapsedRealtime();
12981        pw.println("Applications Graphics Acceleration Info:");
12982        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12983
12984        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12985            ProcessRecord r = procs.get(i);
12986            if (r.thread != null) {
12987                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12988                pw.flush();
12989                try {
12990                    TransferPipe tp = new TransferPipe();
12991                    try {
12992                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12993                        tp.go(fd);
12994                    } finally {
12995                        tp.kill();
12996                    }
12997                } catch (IOException e) {
12998                    pw.println("Failure while dumping the app: " + r);
12999                    pw.flush();
13000                } catch (RemoteException e) {
13001                    pw.println("Got a RemoteException while dumping the app " + r);
13002                    pw.flush();
13003                }
13004            }
13005        }
13006    }
13007
13008    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13009        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13010        if (procs == null) {
13011            pw.println("No process found for: " + args[0]);
13012            return;
13013        }
13014
13015        pw.println("Applications Database Info:");
13016
13017        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13018            ProcessRecord r = procs.get(i);
13019            if (r.thread != null) {
13020                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13021                pw.flush();
13022                try {
13023                    TransferPipe tp = new TransferPipe();
13024                    try {
13025                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13026                        tp.go(fd);
13027                    } finally {
13028                        tp.kill();
13029                    }
13030                } catch (IOException e) {
13031                    pw.println("Failure while dumping the app: " + r);
13032                    pw.flush();
13033                } catch (RemoteException e) {
13034                    pw.println("Got a RemoteException while dumping the app " + r);
13035                    pw.flush();
13036                }
13037            }
13038        }
13039    }
13040
13041    final static class MemItem {
13042        final boolean isProc;
13043        final String label;
13044        final String shortLabel;
13045        final long pss;
13046        final int id;
13047        final boolean hasActivities;
13048        ArrayList<MemItem> subitems;
13049
13050        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13051                boolean _hasActivities) {
13052            isProc = true;
13053            label = _label;
13054            shortLabel = _shortLabel;
13055            pss = _pss;
13056            id = _id;
13057            hasActivities = _hasActivities;
13058        }
13059
13060        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13061            isProc = false;
13062            label = _label;
13063            shortLabel = _shortLabel;
13064            pss = _pss;
13065            id = _id;
13066            hasActivities = false;
13067        }
13068    }
13069
13070    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13071            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13072        if (sort && !isCompact) {
13073            Collections.sort(items, new Comparator<MemItem>() {
13074                @Override
13075                public int compare(MemItem lhs, MemItem rhs) {
13076                    if (lhs.pss < rhs.pss) {
13077                        return 1;
13078                    } else if (lhs.pss > rhs.pss) {
13079                        return -1;
13080                    }
13081                    return 0;
13082                }
13083            });
13084        }
13085
13086        for (int i=0; i<items.size(); i++) {
13087            MemItem mi = items.get(i);
13088            if (!isCompact) {
13089                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13090            } else if (mi.isProc) {
13091                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13092                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13093                pw.println(mi.hasActivities ? ",a" : ",e");
13094            } else {
13095                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13096                pw.println(mi.pss);
13097            }
13098            if (mi.subitems != null) {
13099                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13100                        true, isCompact);
13101            }
13102        }
13103    }
13104
13105    // These are in KB.
13106    static final long[] DUMP_MEM_BUCKETS = new long[] {
13107        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13108        120*1024, 160*1024, 200*1024,
13109        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13110        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13111    };
13112
13113    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13114            boolean stackLike) {
13115        int start = label.lastIndexOf('.');
13116        if (start >= 0) start++;
13117        else start = 0;
13118        int end = label.length();
13119        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13120            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13121                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13122                out.append(bucket);
13123                out.append(stackLike ? "MB." : "MB ");
13124                out.append(label, start, end);
13125                return;
13126            }
13127        }
13128        out.append(memKB/1024);
13129        out.append(stackLike ? "MB." : "MB ");
13130        out.append(label, start, end);
13131    }
13132
13133    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13134            ProcessList.NATIVE_ADJ,
13135            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13136            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13137            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13138            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13139            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13140    };
13141    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13142            "Native",
13143            "System", "Persistent", "Foreground",
13144            "Visible", "Perceptible",
13145            "Heavy Weight", "Backup",
13146            "A Services", "Home",
13147            "Previous", "B Services", "Cached"
13148    };
13149    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13150            "native",
13151            "sys", "pers", "fore",
13152            "vis", "percept",
13153            "heavy", "backup",
13154            "servicea", "home",
13155            "prev", "serviceb", "cached"
13156    };
13157
13158    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13159            long realtime, boolean isCheckinRequest, boolean isCompact) {
13160        if (isCheckinRequest || isCompact) {
13161            // short checkin version
13162            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13163        } else {
13164            pw.println("Applications Memory Usage (kB):");
13165            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13166        }
13167    }
13168
13169    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13170            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13171        boolean dumpDetails = false;
13172        boolean dumpFullDetails = false;
13173        boolean dumpDalvik = false;
13174        boolean oomOnly = false;
13175        boolean isCompact = false;
13176        boolean localOnly = false;
13177
13178        int opti = 0;
13179        while (opti < args.length) {
13180            String opt = args[opti];
13181            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13182                break;
13183            }
13184            opti++;
13185            if ("-a".equals(opt)) {
13186                dumpDetails = true;
13187                dumpFullDetails = true;
13188                dumpDalvik = true;
13189            } else if ("-d".equals(opt)) {
13190                dumpDalvik = true;
13191            } else if ("-c".equals(opt)) {
13192                isCompact = true;
13193            } else if ("--oom".equals(opt)) {
13194                oomOnly = true;
13195            } else if ("--local".equals(opt)) {
13196                localOnly = true;
13197            } else if ("-h".equals(opt)) {
13198                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13199                pw.println("  -a: include all available information for each process.");
13200                pw.println("  -d: include dalvik details when dumping process details.");
13201                pw.println("  -c: dump in a compact machine-parseable representation.");
13202                pw.println("  --oom: only show processes organized by oom adj.");
13203                pw.println("  --local: only collect details locally, don't call process.");
13204                pw.println("If [process] is specified it can be the name or ");
13205                pw.println("pid of a specific process to dump.");
13206                return;
13207            } else {
13208                pw.println("Unknown argument: " + opt + "; use -h for help");
13209            }
13210        }
13211
13212        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13213        long uptime = SystemClock.uptimeMillis();
13214        long realtime = SystemClock.elapsedRealtime();
13215        final long[] tmpLong = new long[1];
13216
13217        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13218        if (procs == null) {
13219            // No Java processes.  Maybe they want to print a native process.
13220            if (args != null && args.length > opti
13221                    && args[opti].charAt(0) != '-') {
13222                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13223                        = new ArrayList<ProcessCpuTracker.Stats>();
13224                updateCpuStatsNow();
13225                int findPid = -1;
13226                try {
13227                    findPid = Integer.parseInt(args[opti]);
13228                } catch (NumberFormatException e) {
13229                }
13230                synchronized (mProcessCpuThread) {
13231                    final int N = mProcessCpuTracker.countStats();
13232                    for (int i=0; i<N; i++) {
13233                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13234                        if (st.pid == findPid || (st.baseName != null
13235                                && st.baseName.equals(args[opti]))) {
13236                            nativeProcs.add(st);
13237                        }
13238                    }
13239                }
13240                if (nativeProcs.size() > 0) {
13241                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13242                            isCompact);
13243                    Debug.MemoryInfo mi = null;
13244                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13245                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13246                        final int pid = r.pid;
13247                        if (!isCheckinRequest && dumpDetails) {
13248                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13249                        }
13250                        if (mi == null) {
13251                            mi = new Debug.MemoryInfo();
13252                        }
13253                        if (dumpDetails || (!brief && !oomOnly)) {
13254                            Debug.getMemoryInfo(pid, mi);
13255                        } else {
13256                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13257                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13258                        }
13259                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13260                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13261                        if (isCheckinRequest) {
13262                            pw.println();
13263                        }
13264                    }
13265                    return;
13266                }
13267            }
13268            pw.println("No process found for: " + args[opti]);
13269            return;
13270        }
13271
13272        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13273            dumpDetails = true;
13274        }
13275
13276        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13277
13278        String[] innerArgs = new String[args.length-opti];
13279        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13280
13281        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13282        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13283        long nativePss=0, dalvikPss=0, otherPss=0;
13284        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13285
13286        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13287        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13288                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13289
13290        long totalPss = 0;
13291        long cachedPss = 0;
13292
13293        Debug.MemoryInfo mi = null;
13294        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13295            final ProcessRecord r = procs.get(i);
13296            final IApplicationThread thread;
13297            final int pid;
13298            final int oomAdj;
13299            final boolean hasActivities;
13300            synchronized (this) {
13301                thread = r.thread;
13302                pid = r.pid;
13303                oomAdj = r.getSetAdjWithServices();
13304                hasActivities = r.activities.size() > 0;
13305            }
13306            if (thread != null) {
13307                if (!isCheckinRequest && dumpDetails) {
13308                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13309                }
13310                if (mi == null) {
13311                    mi = new Debug.MemoryInfo();
13312                }
13313                if (dumpDetails || (!brief && !oomOnly)) {
13314                    Debug.getMemoryInfo(pid, mi);
13315                } else {
13316                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13317                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13318                }
13319                if (dumpDetails) {
13320                    if (localOnly) {
13321                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13322                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13323                        if (isCheckinRequest) {
13324                            pw.println();
13325                        }
13326                    } else {
13327                        try {
13328                            pw.flush();
13329                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13330                                    dumpDalvik, innerArgs);
13331                        } catch (RemoteException e) {
13332                            if (!isCheckinRequest) {
13333                                pw.println("Got RemoteException!");
13334                                pw.flush();
13335                            }
13336                        }
13337                    }
13338                }
13339
13340                final long myTotalPss = mi.getTotalPss();
13341                final long myTotalUss = mi.getTotalUss();
13342
13343                synchronized (this) {
13344                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13345                        // Record this for posterity if the process has been stable.
13346                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13347                    }
13348                }
13349
13350                if (!isCheckinRequest && mi != null) {
13351                    totalPss += myTotalPss;
13352                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13353                            (hasActivities ? " / activities)" : ")"),
13354                            r.processName, myTotalPss, pid, hasActivities);
13355                    procMems.add(pssItem);
13356                    procMemsMap.put(pid, pssItem);
13357
13358                    nativePss += mi.nativePss;
13359                    dalvikPss += mi.dalvikPss;
13360                    otherPss += mi.otherPss;
13361                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13362                        long mem = mi.getOtherPss(j);
13363                        miscPss[j] += mem;
13364                        otherPss -= mem;
13365                    }
13366
13367                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13368                        cachedPss += myTotalPss;
13369                    }
13370
13371                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13372                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13373                                || oomIndex == (oomPss.length-1)) {
13374                            oomPss[oomIndex] += myTotalPss;
13375                            if (oomProcs[oomIndex] == null) {
13376                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13377                            }
13378                            oomProcs[oomIndex].add(pssItem);
13379                            break;
13380                        }
13381                    }
13382                }
13383            }
13384        }
13385
13386        long nativeProcTotalPss = 0;
13387
13388        if (!isCheckinRequest && procs.size() > 1) {
13389            // If we are showing aggregations, also look for native processes to
13390            // include so that our aggregations are more accurate.
13391            updateCpuStatsNow();
13392            synchronized (mProcessCpuThread) {
13393                final int N = mProcessCpuTracker.countStats();
13394                for (int i=0; i<N; i++) {
13395                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13396                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13397                        if (mi == null) {
13398                            mi = new Debug.MemoryInfo();
13399                        }
13400                        if (!brief && !oomOnly) {
13401                            Debug.getMemoryInfo(st.pid, mi);
13402                        } else {
13403                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13404                            mi.nativePrivateDirty = (int)tmpLong[0];
13405                        }
13406
13407                        final long myTotalPss = mi.getTotalPss();
13408                        totalPss += myTotalPss;
13409                        nativeProcTotalPss += myTotalPss;
13410
13411                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13412                                st.name, myTotalPss, st.pid, false);
13413                        procMems.add(pssItem);
13414
13415                        nativePss += mi.nativePss;
13416                        dalvikPss += mi.dalvikPss;
13417                        otherPss += mi.otherPss;
13418                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13419                            long mem = mi.getOtherPss(j);
13420                            miscPss[j] += mem;
13421                            otherPss -= mem;
13422                        }
13423                        oomPss[0] += myTotalPss;
13424                        if (oomProcs[0] == null) {
13425                            oomProcs[0] = new ArrayList<MemItem>();
13426                        }
13427                        oomProcs[0].add(pssItem);
13428                    }
13429                }
13430            }
13431
13432            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13433
13434            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13435            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13436            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13437            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13438                String label = Debug.MemoryInfo.getOtherLabel(j);
13439                catMems.add(new MemItem(label, label, miscPss[j], j));
13440            }
13441
13442            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13443            for (int j=0; j<oomPss.length; j++) {
13444                if (oomPss[j] != 0) {
13445                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13446                            : DUMP_MEM_OOM_LABEL[j];
13447                    MemItem item = new MemItem(label, label, oomPss[j],
13448                            DUMP_MEM_OOM_ADJ[j]);
13449                    item.subitems = oomProcs[j];
13450                    oomMems.add(item);
13451                }
13452            }
13453
13454            if (!brief && !oomOnly && !isCompact) {
13455                pw.println();
13456                pw.println("Total PSS by process:");
13457                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13458                pw.println();
13459            }
13460            if (!isCompact) {
13461                pw.println("Total PSS by OOM adjustment:");
13462            }
13463            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13464            if (!brief && !oomOnly) {
13465                PrintWriter out = categoryPw != null ? categoryPw : pw;
13466                if (!isCompact) {
13467                    out.println();
13468                    out.println("Total PSS by category:");
13469                }
13470                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13471            }
13472            if (!isCompact) {
13473                pw.println();
13474            }
13475            MemInfoReader memInfo = new MemInfoReader();
13476            memInfo.readMemInfo();
13477            if (nativeProcTotalPss > 0) {
13478                synchronized (this) {
13479                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13480                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13481                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13482                            nativeProcTotalPss);
13483                }
13484            }
13485            if (!brief) {
13486                if (!isCompact) {
13487                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13488                    pw.print(" kB (status ");
13489                    switch (mLastMemoryLevel) {
13490                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13491                            pw.println("normal)");
13492                            break;
13493                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13494                            pw.println("moderate)");
13495                            break;
13496                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13497                            pw.println("low)");
13498                            break;
13499                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13500                            pw.println("critical)");
13501                            break;
13502                        default:
13503                            pw.print(mLastMemoryLevel);
13504                            pw.println(")");
13505                            break;
13506                    }
13507                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13508                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13509                            pw.print(cachedPss); pw.print(" cached pss + ");
13510                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13511                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13512                } else {
13513                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13514                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13515                            + memInfo.getFreeSizeKb()); pw.print(",");
13516                    pw.println(totalPss - cachedPss);
13517                }
13518            }
13519            if (!isCompact) {
13520                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13521                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13522                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13523                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13524                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13525                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13526                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13527                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13528                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13529                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13530                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13531            }
13532            if (!brief) {
13533                if (memInfo.getZramTotalSizeKb() != 0) {
13534                    if (!isCompact) {
13535                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13536                                pw.print(" kB physical used for ");
13537                                pw.print(memInfo.getSwapTotalSizeKb()
13538                                        - memInfo.getSwapFreeSizeKb());
13539                                pw.print(" kB in swap (");
13540                                pw.print(memInfo.getSwapTotalSizeKb());
13541                                pw.println(" kB total swap)");
13542                    } else {
13543                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13544                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13545                                pw.println(memInfo.getSwapFreeSizeKb());
13546                    }
13547                }
13548                final int[] SINGLE_LONG_FORMAT = new int[] {
13549                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13550                };
13551                long[] longOut = new long[1];
13552                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13553                        SINGLE_LONG_FORMAT, null, longOut, null);
13554                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13555                longOut[0] = 0;
13556                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13557                        SINGLE_LONG_FORMAT, null, longOut, null);
13558                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13559                longOut[0] = 0;
13560                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13561                        SINGLE_LONG_FORMAT, null, longOut, null);
13562                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13563                longOut[0] = 0;
13564                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13565                        SINGLE_LONG_FORMAT, null, longOut, null);
13566                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13567                if (!isCompact) {
13568                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13569                        pw.print("      KSM: "); pw.print(sharing);
13570                                pw.print(" kB saved from shared ");
13571                                pw.print(shared); pw.println(" kB");
13572                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13573                                pw.print(voltile); pw.println(" kB volatile");
13574                    }
13575                    pw.print("   Tuning: ");
13576                    pw.print(ActivityManager.staticGetMemoryClass());
13577                    pw.print(" (large ");
13578                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13579                    pw.print("), oom ");
13580                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13581                    pw.print(" kB");
13582                    pw.print(", restore limit ");
13583                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13584                    pw.print(" kB");
13585                    if (ActivityManager.isLowRamDeviceStatic()) {
13586                        pw.print(" (low-ram)");
13587                    }
13588                    if (ActivityManager.isHighEndGfx()) {
13589                        pw.print(" (high-end-gfx)");
13590                    }
13591                    pw.println();
13592                } else {
13593                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13594                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13595                    pw.println(voltile);
13596                    pw.print("tuning,");
13597                    pw.print(ActivityManager.staticGetMemoryClass());
13598                    pw.print(',');
13599                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13600                    pw.print(',');
13601                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13602                    if (ActivityManager.isLowRamDeviceStatic()) {
13603                        pw.print(",low-ram");
13604                    }
13605                    if (ActivityManager.isHighEndGfx()) {
13606                        pw.print(",high-end-gfx");
13607                    }
13608                    pw.println();
13609                }
13610            }
13611        }
13612    }
13613
13614    /**
13615     * Searches array of arguments for the specified string
13616     * @param args array of argument strings
13617     * @param value value to search for
13618     * @return true if the value is contained in the array
13619     */
13620    private static boolean scanArgs(String[] args, String value) {
13621        if (args != null) {
13622            for (String arg : args) {
13623                if (value.equals(arg)) {
13624                    return true;
13625                }
13626            }
13627        }
13628        return false;
13629    }
13630
13631    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13632            ContentProviderRecord cpr, boolean always) {
13633        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13634
13635        if (!inLaunching || always) {
13636            synchronized (cpr) {
13637                cpr.launchingApp = null;
13638                cpr.notifyAll();
13639            }
13640            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13641            String names[] = cpr.info.authority.split(";");
13642            for (int j = 0; j < names.length; j++) {
13643                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13644            }
13645        }
13646
13647        for (int i=0; i<cpr.connections.size(); i++) {
13648            ContentProviderConnection conn = cpr.connections.get(i);
13649            if (conn.waiting) {
13650                // If this connection is waiting for the provider, then we don't
13651                // need to mess with its process unless we are always removing
13652                // or for some reason the provider is not currently launching.
13653                if (inLaunching && !always) {
13654                    continue;
13655                }
13656            }
13657            ProcessRecord capp = conn.client;
13658            conn.dead = true;
13659            if (conn.stableCount > 0) {
13660                if (!capp.persistent && capp.thread != null
13661                        && capp.pid != 0
13662                        && capp.pid != MY_PID) {
13663                    killUnneededProcessLocked(capp, "depends on provider "
13664                            + cpr.name.flattenToShortString()
13665                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13666                }
13667            } else if (capp.thread != null && conn.provider.provider != null) {
13668                try {
13669                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13670                } catch (RemoteException e) {
13671                }
13672                // In the protocol here, we don't expect the client to correctly
13673                // clean up this connection, we'll just remove it.
13674                cpr.connections.remove(i);
13675                conn.client.conProviders.remove(conn);
13676            }
13677        }
13678
13679        if (inLaunching && always) {
13680            mLaunchingProviders.remove(cpr);
13681        }
13682        return inLaunching;
13683    }
13684
13685    /**
13686     * Main code for cleaning up a process when it has gone away.  This is
13687     * called both as a result of the process dying, or directly when stopping
13688     * a process when running in single process mode.
13689     */
13690    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13691            boolean restarting, boolean allowRestart, int index) {
13692        if (index >= 0) {
13693            removeLruProcessLocked(app);
13694            ProcessList.remove(app.pid);
13695        }
13696
13697        mProcessesToGc.remove(app);
13698        mPendingPssProcesses.remove(app);
13699
13700        // Dismiss any open dialogs.
13701        if (app.crashDialog != null && !app.forceCrashReport) {
13702            app.crashDialog.dismiss();
13703            app.crashDialog = null;
13704        }
13705        if (app.anrDialog != null) {
13706            app.anrDialog.dismiss();
13707            app.anrDialog = null;
13708        }
13709        if (app.waitDialog != null) {
13710            app.waitDialog.dismiss();
13711            app.waitDialog = null;
13712        }
13713
13714        app.crashing = false;
13715        app.notResponding = false;
13716
13717        app.resetPackageList(mProcessStats);
13718        app.unlinkDeathRecipient();
13719        app.makeInactive(mProcessStats);
13720        app.waitingToKill = null;
13721        app.forcingToForeground = null;
13722        updateProcessForegroundLocked(app, false, false);
13723        app.foregroundActivities = false;
13724        app.hasShownUi = false;
13725        app.treatLikeActivity = false;
13726        app.hasAboveClient = false;
13727        app.hasClientActivities = false;
13728
13729        mServices.killServicesLocked(app, allowRestart);
13730
13731        boolean restart = false;
13732
13733        // Remove published content providers.
13734        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13735            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13736            final boolean always = app.bad || !allowRestart;
13737            if (removeDyingProviderLocked(app, cpr, always) || always) {
13738                // We left the provider in the launching list, need to
13739                // restart it.
13740                restart = true;
13741            }
13742
13743            cpr.provider = null;
13744            cpr.proc = null;
13745        }
13746        app.pubProviders.clear();
13747
13748        // Take care of any launching providers waiting for this process.
13749        if (checkAppInLaunchingProvidersLocked(app, false)) {
13750            restart = true;
13751        }
13752
13753        // Unregister from connected content providers.
13754        if (!app.conProviders.isEmpty()) {
13755            for (int i=0; i<app.conProviders.size(); i++) {
13756                ContentProviderConnection conn = app.conProviders.get(i);
13757                conn.provider.connections.remove(conn);
13758            }
13759            app.conProviders.clear();
13760        }
13761
13762        // At this point there may be remaining entries in mLaunchingProviders
13763        // where we were the only one waiting, so they are no longer of use.
13764        // Look for these and clean up if found.
13765        // XXX Commented out for now.  Trying to figure out a way to reproduce
13766        // the actual situation to identify what is actually going on.
13767        if (false) {
13768            for (int i=0; i<mLaunchingProviders.size(); i++) {
13769                ContentProviderRecord cpr = (ContentProviderRecord)
13770                        mLaunchingProviders.get(i);
13771                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13772                    synchronized (cpr) {
13773                        cpr.launchingApp = null;
13774                        cpr.notifyAll();
13775                    }
13776                }
13777            }
13778        }
13779
13780        skipCurrentReceiverLocked(app);
13781
13782        // Unregister any receivers.
13783        for (int i=app.receivers.size()-1; i>=0; i--) {
13784            removeReceiverLocked(app.receivers.valueAt(i));
13785        }
13786        app.receivers.clear();
13787
13788        // If the app is undergoing backup, tell the backup manager about it
13789        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13790            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13791                    + mBackupTarget.appInfo + " died during backup");
13792            try {
13793                IBackupManager bm = IBackupManager.Stub.asInterface(
13794                        ServiceManager.getService(Context.BACKUP_SERVICE));
13795                bm.agentDisconnected(app.info.packageName);
13796            } catch (RemoteException e) {
13797                // can't happen; backup manager is local
13798            }
13799        }
13800
13801        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13802            ProcessChangeItem item = mPendingProcessChanges.get(i);
13803            if (item.pid == app.pid) {
13804                mPendingProcessChanges.remove(i);
13805                mAvailProcessChanges.add(item);
13806            }
13807        }
13808        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13809
13810        // If the caller is restarting this app, then leave it in its
13811        // current lists and let the caller take care of it.
13812        if (restarting) {
13813            return;
13814        }
13815
13816        if (!app.persistent || app.isolated) {
13817            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13818                    "Removing non-persistent process during cleanup: " + app);
13819            mProcessNames.remove(app.processName, app.uid);
13820            mIsolatedProcesses.remove(app.uid);
13821            if (mHeavyWeightProcess == app) {
13822                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13823                        mHeavyWeightProcess.userId, 0));
13824                mHeavyWeightProcess = null;
13825            }
13826        } else if (!app.removed) {
13827            // This app is persistent, so we need to keep its record around.
13828            // If it is not already on the pending app list, add it there
13829            // and start a new process for it.
13830            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13831                mPersistentStartingProcesses.add(app);
13832                restart = true;
13833            }
13834        }
13835        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13836                "Clean-up removing on hold: " + app);
13837        mProcessesOnHold.remove(app);
13838
13839        if (app == mHomeProcess) {
13840            mHomeProcess = null;
13841        }
13842        if (app == mPreviousProcess) {
13843            mPreviousProcess = null;
13844        }
13845
13846        if (restart && !app.isolated) {
13847            // We have components that still need to be running in the
13848            // process, so re-launch it.
13849            mProcessNames.put(app.processName, app.uid, app);
13850            startProcessLocked(app, "restart", app.processName);
13851        } else if (app.pid > 0 && app.pid != MY_PID) {
13852            // Goodbye!
13853            boolean removed;
13854            synchronized (mPidsSelfLocked) {
13855                mPidsSelfLocked.remove(app.pid);
13856                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13857            }
13858            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13859            if (app.isolated) {
13860                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13861            }
13862            app.setPid(0);
13863        }
13864    }
13865
13866    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13867        // Look through the content providers we are waiting to have launched,
13868        // and if any run in this process then either schedule a restart of
13869        // the process or kill the client waiting for it if this process has
13870        // gone bad.
13871        int NL = mLaunchingProviders.size();
13872        boolean restart = false;
13873        for (int i=0; i<NL; i++) {
13874            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13875            if (cpr.launchingApp == app) {
13876                if (!alwaysBad && !app.bad) {
13877                    restart = true;
13878                } else {
13879                    removeDyingProviderLocked(app, cpr, true);
13880                    // cpr should have been removed from mLaunchingProviders
13881                    NL = mLaunchingProviders.size();
13882                    i--;
13883                }
13884            }
13885        }
13886        return restart;
13887    }
13888
13889    // =========================================================
13890    // SERVICES
13891    // =========================================================
13892
13893    @Override
13894    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13895            int flags) {
13896        enforceNotIsolatedCaller("getServices");
13897        synchronized (this) {
13898            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13899        }
13900    }
13901
13902    @Override
13903    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13904        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13905        synchronized (this) {
13906            return mServices.getRunningServiceControlPanelLocked(name);
13907        }
13908    }
13909
13910    @Override
13911    public ComponentName startService(IApplicationThread caller, Intent service,
13912            String resolvedType, int userId) {
13913        enforceNotIsolatedCaller("startService");
13914        // Refuse possible leaked file descriptors
13915        if (service != null && service.hasFileDescriptors() == true) {
13916            throw new IllegalArgumentException("File descriptors passed in Intent");
13917        }
13918
13919        if (DEBUG_SERVICE)
13920            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13921        synchronized(this) {
13922            final int callingPid = Binder.getCallingPid();
13923            final int callingUid = Binder.getCallingUid();
13924            final long origId = Binder.clearCallingIdentity();
13925            ComponentName res = mServices.startServiceLocked(caller, service,
13926                    resolvedType, callingPid, callingUid, userId);
13927            Binder.restoreCallingIdentity(origId);
13928            return res;
13929        }
13930    }
13931
13932    ComponentName startServiceInPackage(int uid,
13933            Intent service, String resolvedType, int userId) {
13934        synchronized(this) {
13935            if (DEBUG_SERVICE)
13936                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13937            final long origId = Binder.clearCallingIdentity();
13938            ComponentName res = mServices.startServiceLocked(null, service,
13939                    resolvedType, -1, uid, userId);
13940            Binder.restoreCallingIdentity(origId);
13941            return res;
13942        }
13943    }
13944
13945    @Override
13946    public int stopService(IApplicationThread caller, Intent service,
13947            String resolvedType, int userId) {
13948        enforceNotIsolatedCaller("stopService");
13949        // Refuse possible leaked file descriptors
13950        if (service != null && service.hasFileDescriptors() == true) {
13951            throw new IllegalArgumentException("File descriptors passed in Intent");
13952        }
13953
13954        synchronized(this) {
13955            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13956        }
13957    }
13958
13959    @Override
13960    public IBinder peekService(Intent service, String resolvedType) {
13961        enforceNotIsolatedCaller("peekService");
13962        // Refuse possible leaked file descriptors
13963        if (service != null && service.hasFileDescriptors() == true) {
13964            throw new IllegalArgumentException("File descriptors passed in Intent");
13965        }
13966        synchronized(this) {
13967            return mServices.peekServiceLocked(service, resolvedType);
13968        }
13969    }
13970
13971    @Override
13972    public boolean stopServiceToken(ComponentName className, IBinder token,
13973            int startId) {
13974        synchronized(this) {
13975            return mServices.stopServiceTokenLocked(className, token, startId);
13976        }
13977    }
13978
13979    @Override
13980    public void setServiceForeground(ComponentName className, IBinder token,
13981            int id, Notification notification, boolean removeNotification) {
13982        synchronized(this) {
13983            mServices.setServiceForegroundLocked(className, token, id, notification,
13984                    removeNotification);
13985        }
13986    }
13987
13988    @Override
13989    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13990            boolean requireFull, String name, String callerPackage) {
13991        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13992                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13993    }
13994
13995    int unsafeConvertIncomingUser(int userId) {
13996        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13997                ? mCurrentUserId : userId;
13998    }
13999
14000    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14001            int allowMode, String name, String callerPackage) {
14002        final int callingUserId = UserHandle.getUserId(callingUid);
14003        if (callingUserId == userId) {
14004            return userId;
14005        }
14006
14007        // Note that we may be accessing mCurrentUserId outside of a lock...
14008        // shouldn't be a big deal, if this is being called outside
14009        // of a locked context there is intrinsically a race with
14010        // the value the caller will receive and someone else changing it.
14011        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14012        // we will switch to the calling user if access to the current user fails.
14013        int targetUserId = unsafeConvertIncomingUser(userId);
14014
14015        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14016            final boolean allow;
14017            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14018                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14019                // If the caller has this permission, they always pass go.  And collect $200.
14020                allow = true;
14021            } else if (allowMode == ALLOW_FULL_ONLY) {
14022                // We require full access, sucks to be you.
14023                allow = false;
14024            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14025                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14026                // If the caller does not have either permission, they are always doomed.
14027                allow = false;
14028            } else if (allowMode == ALLOW_NON_FULL) {
14029                // We are blanket allowing non-full access, you lucky caller!
14030                allow = true;
14031            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14032                // We may or may not allow this depending on whether the two users are
14033                // in the same profile.
14034                synchronized (mUserProfileGroupIdsSelfLocked) {
14035                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14036                            UserInfo.NO_PROFILE_GROUP_ID);
14037                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14038                            UserInfo.NO_PROFILE_GROUP_ID);
14039                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14040                            && callingProfile == targetProfile;
14041                }
14042            } else {
14043                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14044            }
14045            if (!allow) {
14046                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14047                    // In this case, they would like to just execute as their
14048                    // owner user instead of failing.
14049                    targetUserId = callingUserId;
14050                } else {
14051                    StringBuilder builder = new StringBuilder(128);
14052                    builder.append("Permission Denial: ");
14053                    builder.append(name);
14054                    if (callerPackage != null) {
14055                        builder.append(" from ");
14056                        builder.append(callerPackage);
14057                    }
14058                    builder.append(" asks to run as user ");
14059                    builder.append(userId);
14060                    builder.append(" but is calling from user ");
14061                    builder.append(UserHandle.getUserId(callingUid));
14062                    builder.append("; this requires ");
14063                    builder.append(INTERACT_ACROSS_USERS_FULL);
14064                    if (allowMode != ALLOW_FULL_ONLY) {
14065                        builder.append(" or ");
14066                        builder.append(INTERACT_ACROSS_USERS);
14067                    }
14068                    String msg = builder.toString();
14069                    Slog.w(TAG, msg);
14070                    throw new SecurityException(msg);
14071                }
14072            }
14073        }
14074        if (!allowAll && targetUserId < 0) {
14075            throw new IllegalArgumentException(
14076                    "Call does not support special user #" + targetUserId);
14077        }
14078        return targetUserId;
14079    }
14080
14081    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14082            String className, int flags) {
14083        boolean result = false;
14084        // For apps that don't have pre-defined UIDs, check for permission
14085        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14086            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14087                if (ActivityManager.checkUidPermission(
14088                        INTERACT_ACROSS_USERS,
14089                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14090                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14091                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14092                            + " requests FLAG_SINGLE_USER, but app does not hold "
14093                            + INTERACT_ACROSS_USERS;
14094                    Slog.w(TAG, msg);
14095                    throw new SecurityException(msg);
14096                }
14097                // Permission passed
14098                result = true;
14099            }
14100        } else if ("system".equals(componentProcessName)) {
14101            result = true;
14102        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14103                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14104            // Phone app is allowed to export singleuser providers.
14105            result = true;
14106        } else {
14107            // App with pre-defined UID, check if it's a persistent app
14108            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14109        }
14110        if (DEBUG_MU) {
14111            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14112                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14113        }
14114        return result;
14115    }
14116
14117    /**
14118     * Checks to see if the caller is in the same app as the singleton
14119     * component, or the component is in a special app. It allows special apps
14120     * to export singleton components but prevents exporting singleton
14121     * components for regular apps.
14122     */
14123    boolean isValidSingletonCall(int callingUid, int componentUid) {
14124        int componentAppId = UserHandle.getAppId(componentUid);
14125        return UserHandle.isSameApp(callingUid, componentUid)
14126                || componentAppId == Process.SYSTEM_UID
14127                || componentAppId == Process.PHONE_UID
14128                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14129                        == PackageManager.PERMISSION_GRANTED;
14130    }
14131
14132    public int bindService(IApplicationThread caller, IBinder token,
14133            Intent service, String resolvedType,
14134            IServiceConnection connection, int flags, int userId) {
14135        enforceNotIsolatedCaller("bindService");
14136        // Refuse possible leaked file descriptors
14137        if (service != null && service.hasFileDescriptors() == true) {
14138            throw new IllegalArgumentException("File descriptors passed in Intent");
14139        }
14140
14141        synchronized(this) {
14142            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14143                    connection, flags, userId);
14144        }
14145    }
14146
14147    public boolean unbindService(IServiceConnection connection) {
14148        synchronized (this) {
14149            return mServices.unbindServiceLocked(connection);
14150        }
14151    }
14152
14153    public void publishService(IBinder token, Intent intent, IBinder service) {
14154        // Refuse possible leaked file descriptors
14155        if (intent != null && intent.hasFileDescriptors() == true) {
14156            throw new IllegalArgumentException("File descriptors passed in Intent");
14157        }
14158
14159        synchronized(this) {
14160            if (!(token instanceof ServiceRecord)) {
14161                throw new IllegalArgumentException("Invalid service token");
14162            }
14163            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14164        }
14165    }
14166
14167    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14168        // Refuse possible leaked file descriptors
14169        if (intent != null && intent.hasFileDescriptors() == true) {
14170            throw new IllegalArgumentException("File descriptors passed in Intent");
14171        }
14172
14173        synchronized(this) {
14174            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14175        }
14176    }
14177
14178    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14179        synchronized(this) {
14180            if (!(token instanceof ServiceRecord)) {
14181                throw new IllegalArgumentException("Invalid service token");
14182            }
14183            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14184        }
14185    }
14186
14187    // =========================================================
14188    // BACKUP AND RESTORE
14189    // =========================================================
14190
14191    // Cause the target app to be launched if necessary and its backup agent
14192    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14193    // activity manager to announce its creation.
14194    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14195        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14196        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14197
14198        synchronized(this) {
14199            // !!! TODO: currently no check here that we're already bound
14200            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14201            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14202            synchronized (stats) {
14203                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14204            }
14205
14206            // Backup agent is now in use, its package can't be stopped.
14207            try {
14208                AppGlobals.getPackageManager().setPackageStoppedState(
14209                        app.packageName, false, UserHandle.getUserId(app.uid));
14210            } catch (RemoteException e) {
14211            } catch (IllegalArgumentException e) {
14212                Slog.w(TAG, "Failed trying to unstop package "
14213                        + app.packageName + ": " + e);
14214            }
14215
14216            BackupRecord r = new BackupRecord(ss, app, backupMode);
14217            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14218                    ? new ComponentName(app.packageName, app.backupAgentName)
14219                    : new ComponentName("android", "FullBackupAgent");
14220            // startProcessLocked() returns existing proc's record if it's already running
14221            ProcessRecord proc = startProcessLocked(app.processName, app,
14222                    false, 0, "backup", hostingName, false, false, false);
14223            if (proc == null) {
14224                Slog.e(TAG, "Unable to start backup agent process " + r);
14225                return false;
14226            }
14227
14228            r.app = proc;
14229            mBackupTarget = r;
14230            mBackupAppName = app.packageName;
14231
14232            // Try not to kill the process during backup
14233            updateOomAdjLocked(proc);
14234
14235            // If the process is already attached, schedule the creation of the backup agent now.
14236            // If it is not yet live, this will be done when it attaches to the framework.
14237            if (proc.thread != null) {
14238                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14239                try {
14240                    proc.thread.scheduleCreateBackupAgent(app,
14241                            compatibilityInfoForPackageLocked(app), backupMode);
14242                } catch (RemoteException e) {
14243                    // Will time out on the backup manager side
14244                }
14245            } else {
14246                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14247            }
14248            // Invariants: at this point, the target app process exists and the application
14249            // is either already running or in the process of coming up.  mBackupTarget and
14250            // mBackupAppName describe the app, so that when it binds back to the AM we
14251            // know that it's scheduled for a backup-agent operation.
14252        }
14253
14254        return true;
14255    }
14256
14257    @Override
14258    public void clearPendingBackup() {
14259        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14260        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14261
14262        synchronized (this) {
14263            mBackupTarget = null;
14264            mBackupAppName = null;
14265        }
14266    }
14267
14268    // A backup agent has just come up
14269    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14270        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14271                + " = " + agent);
14272
14273        synchronized(this) {
14274            if (!agentPackageName.equals(mBackupAppName)) {
14275                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14276                return;
14277            }
14278        }
14279
14280        long oldIdent = Binder.clearCallingIdentity();
14281        try {
14282            IBackupManager bm = IBackupManager.Stub.asInterface(
14283                    ServiceManager.getService(Context.BACKUP_SERVICE));
14284            bm.agentConnected(agentPackageName, agent);
14285        } catch (RemoteException e) {
14286            // can't happen; the backup manager service is local
14287        } catch (Exception e) {
14288            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14289            e.printStackTrace();
14290        } finally {
14291            Binder.restoreCallingIdentity(oldIdent);
14292        }
14293    }
14294
14295    // done with this agent
14296    public void unbindBackupAgent(ApplicationInfo appInfo) {
14297        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14298        if (appInfo == null) {
14299            Slog.w(TAG, "unbind backup agent for null app");
14300            return;
14301        }
14302
14303        synchronized(this) {
14304            try {
14305                if (mBackupAppName == null) {
14306                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14307                    return;
14308                }
14309
14310                if (!mBackupAppName.equals(appInfo.packageName)) {
14311                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14312                    return;
14313                }
14314
14315                // Not backing this app up any more; reset its OOM adjustment
14316                final ProcessRecord proc = mBackupTarget.app;
14317                updateOomAdjLocked(proc);
14318
14319                // If the app crashed during backup, 'thread' will be null here
14320                if (proc.thread != null) {
14321                    try {
14322                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14323                                compatibilityInfoForPackageLocked(appInfo));
14324                    } catch (Exception e) {
14325                        Slog.e(TAG, "Exception when unbinding backup agent:");
14326                        e.printStackTrace();
14327                    }
14328                }
14329            } finally {
14330                mBackupTarget = null;
14331                mBackupAppName = null;
14332            }
14333        }
14334    }
14335    // =========================================================
14336    // BROADCASTS
14337    // =========================================================
14338
14339    private final List getStickiesLocked(String action, IntentFilter filter,
14340            List cur, int userId) {
14341        final ContentResolver resolver = mContext.getContentResolver();
14342        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14343        if (stickies == null) {
14344            return cur;
14345        }
14346        final ArrayList<Intent> list = stickies.get(action);
14347        if (list == null) {
14348            return cur;
14349        }
14350        int N = list.size();
14351        for (int i=0; i<N; i++) {
14352            Intent intent = list.get(i);
14353            if (filter.match(resolver, intent, true, TAG) >= 0) {
14354                if (cur == null) {
14355                    cur = new ArrayList<Intent>();
14356                }
14357                cur.add(intent);
14358            }
14359        }
14360        return cur;
14361    }
14362
14363    boolean isPendingBroadcastProcessLocked(int pid) {
14364        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14365                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14366    }
14367
14368    void skipPendingBroadcastLocked(int pid) {
14369            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14370            for (BroadcastQueue queue : mBroadcastQueues) {
14371                queue.skipPendingBroadcastLocked(pid);
14372            }
14373    }
14374
14375    // The app just attached; send any pending broadcasts that it should receive
14376    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14377        boolean didSomething = false;
14378        for (BroadcastQueue queue : mBroadcastQueues) {
14379            didSomething |= queue.sendPendingBroadcastsLocked(app);
14380        }
14381        return didSomething;
14382    }
14383
14384    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14385            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14386        enforceNotIsolatedCaller("registerReceiver");
14387        int callingUid;
14388        int callingPid;
14389        synchronized(this) {
14390            ProcessRecord callerApp = null;
14391            if (caller != null) {
14392                callerApp = getRecordForAppLocked(caller);
14393                if (callerApp == null) {
14394                    throw new SecurityException(
14395                            "Unable to find app for caller " + caller
14396                            + " (pid=" + Binder.getCallingPid()
14397                            + ") when registering receiver " + receiver);
14398                }
14399                if (callerApp.info.uid != Process.SYSTEM_UID &&
14400                        !callerApp.pkgList.containsKey(callerPackage) &&
14401                        !"android".equals(callerPackage)) {
14402                    throw new SecurityException("Given caller package " + callerPackage
14403                            + " is not running in process " + callerApp);
14404                }
14405                callingUid = callerApp.info.uid;
14406                callingPid = callerApp.pid;
14407            } else {
14408                callerPackage = null;
14409                callingUid = Binder.getCallingUid();
14410                callingPid = Binder.getCallingPid();
14411            }
14412
14413            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14414                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14415
14416            List allSticky = null;
14417
14418            // Look for any matching sticky broadcasts...
14419            Iterator actions = filter.actionsIterator();
14420            if (actions != null) {
14421                while (actions.hasNext()) {
14422                    String action = (String)actions.next();
14423                    allSticky = getStickiesLocked(action, filter, allSticky,
14424                            UserHandle.USER_ALL);
14425                    allSticky = getStickiesLocked(action, filter, allSticky,
14426                            UserHandle.getUserId(callingUid));
14427                }
14428            } else {
14429                allSticky = getStickiesLocked(null, filter, allSticky,
14430                        UserHandle.USER_ALL);
14431                allSticky = getStickiesLocked(null, filter, allSticky,
14432                        UserHandle.getUserId(callingUid));
14433            }
14434
14435            // The first sticky in the list is returned directly back to
14436            // the client.
14437            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14438
14439            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14440                    + ": " + sticky);
14441
14442            if (receiver == null) {
14443                return sticky;
14444            }
14445
14446            ReceiverList rl
14447                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14448            if (rl == null) {
14449                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14450                        userId, receiver);
14451                if (rl.app != null) {
14452                    rl.app.receivers.add(rl);
14453                } else {
14454                    try {
14455                        receiver.asBinder().linkToDeath(rl, 0);
14456                    } catch (RemoteException e) {
14457                        return sticky;
14458                    }
14459                    rl.linkedToDeath = true;
14460                }
14461                mRegisteredReceivers.put(receiver.asBinder(), rl);
14462            } else if (rl.uid != callingUid) {
14463                throw new IllegalArgumentException(
14464                        "Receiver requested to register for uid " + callingUid
14465                        + " was previously registered for uid " + rl.uid);
14466            } else if (rl.pid != callingPid) {
14467                throw new IllegalArgumentException(
14468                        "Receiver requested to register for pid " + callingPid
14469                        + " was previously registered for pid " + rl.pid);
14470            } else if (rl.userId != userId) {
14471                throw new IllegalArgumentException(
14472                        "Receiver requested to register for user " + userId
14473                        + " was previously registered for user " + rl.userId);
14474            }
14475            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14476                    permission, callingUid, userId);
14477            rl.add(bf);
14478            if (!bf.debugCheck()) {
14479                Slog.w(TAG, "==> For Dynamic broadast");
14480            }
14481            mReceiverResolver.addFilter(bf);
14482
14483            // Enqueue broadcasts for all existing stickies that match
14484            // this filter.
14485            if (allSticky != null) {
14486                ArrayList receivers = new ArrayList();
14487                receivers.add(bf);
14488
14489                int N = allSticky.size();
14490                for (int i=0; i<N; i++) {
14491                    Intent intent = (Intent)allSticky.get(i);
14492                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14493                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14494                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14495                            null, null, false, true, true, -1);
14496                    queue.enqueueParallelBroadcastLocked(r);
14497                    queue.scheduleBroadcastsLocked();
14498                }
14499            }
14500
14501            return sticky;
14502        }
14503    }
14504
14505    public void unregisterReceiver(IIntentReceiver receiver) {
14506        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14507
14508        final long origId = Binder.clearCallingIdentity();
14509        try {
14510            boolean doTrim = false;
14511
14512            synchronized(this) {
14513                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14514                if (rl != null) {
14515                    if (rl.curBroadcast != null) {
14516                        BroadcastRecord r = rl.curBroadcast;
14517                        final boolean doNext = finishReceiverLocked(
14518                                receiver.asBinder(), r.resultCode, r.resultData,
14519                                r.resultExtras, r.resultAbort);
14520                        if (doNext) {
14521                            doTrim = true;
14522                            r.queue.processNextBroadcast(false);
14523                        }
14524                    }
14525
14526                    if (rl.app != null) {
14527                        rl.app.receivers.remove(rl);
14528                    }
14529                    removeReceiverLocked(rl);
14530                    if (rl.linkedToDeath) {
14531                        rl.linkedToDeath = false;
14532                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14533                    }
14534                }
14535            }
14536
14537            // If we actually concluded any broadcasts, we might now be able
14538            // to trim the recipients' apps from our working set
14539            if (doTrim) {
14540                trimApplications();
14541                return;
14542            }
14543
14544        } finally {
14545            Binder.restoreCallingIdentity(origId);
14546        }
14547    }
14548
14549    void removeReceiverLocked(ReceiverList rl) {
14550        mRegisteredReceivers.remove(rl.receiver.asBinder());
14551        int N = rl.size();
14552        for (int i=0; i<N; i++) {
14553            mReceiverResolver.removeFilter(rl.get(i));
14554        }
14555    }
14556
14557    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14558        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14559            ProcessRecord r = mLruProcesses.get(i);
14560            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14561                try {
14562                    r.thread.dispatchPackageBroadcast(cmd, packages);
14563                } catch (RemoteException ex) {
14564                }
14565            }
14566        }
14567    }
14568
14569    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14570            int[] users) {
14571        List<ResolveInfo> receivers = null;
14572        try {
14573            HashSet<ComponentName> singleUserReceivers = null;
14574            boolean scannedFirstReceivers = false;
14575            for (int user : users) {
14576                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14577                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14578                if (user != 0 && newReceivers != null) {
14579                    // If this is not the primary user, we need to check for
14580                    // any receivers that should be filtered out.
14581                    for (int i=0; i<newReceivers.size(); i++) {
14582                        ResolveInfo ri = newReceivers.get(i);
14583                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14584                            newReceivers.remove(i);
14585                            i--;
14586                        }
14587                    }
14588                }
14589                if (newReceivers != null && newReceivers.size() == 0) {
14590                    newReceivers = null;
14591                }
14592                if (receivers == null) {
14593                    receivers = newReceivers;
14594                } else if (newReceivers != null) {
14595                    // We need to concatenate the additional receivers
14596                    // found with what we have do far.  This would be easy,
14597                    // but we also need to de-dup any receivers that are
14598                    // singleUser.
14599                    if (!scannedFirstReceivers) {
14600                        // Collect any single user receivers we had already retrieved.
14601                        scannedFirstReceivers = true;
14602                        for (int i=0; i<receivers.size(); i++) {
14603                            ResolveInfo ri = receivers.get(i);
14604                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14605                                ComponentName cn = new ComponentName(
14606                                        ri.activityInfo.packageName, ri.activityInfo.name);
14607                                if (singleUserReceivers == null) {
14608                                    singleUserReceivers = new HashSet<ComponentName>();
14609                                }
14610                                singleUserReceivers.add(cn);
14611                            }
14612                        }
14613                    }
14614                    // Add the new results to the existing results, tracking
14615                    // and de-dupping single user receivers.
14616                    for (int i=0; i<newReceivers.size(); i++) {
14617                        ResolveInfo ri = newReceivers.get(i);
14618                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14619                            ComponentName cn = new ComponentName(
14620                                    ri.activityInfo.packageName, ri.activityInfo.name);
14621                            if (singleUserReceivers == null) {
14622                                singleUserReceivers = new HashSet<ComponentName>();
14623                            }
14624                            if (!singleUserReceivers.contains(cn)) {
14625                                singleUserReceivers.add(cn);
14626                                receivers.add(ri);
14627                            }
14628                        } else {
14629                            receivers.add(ri);
14630                        }
14631                    }
14632                }
14633            }
14634        } catch (RemoteException ex) {
14635            // pm is in same process, this will never happen.
14636        }
14637        return receivers;
14638    }
14639
14640    private final int broadcastIntentLocked(ProcessRecord callerApp,
14641            String callerPackage, Intent intent, String resolvedType,
14642            IIntentReceiver resultTo, int resultCode, String resultData,
14643            Bundle map, String requiredPermission, int appOp,
14644            boolean ordered, boolean sticky, int callingPid, int callingUid,
14645            int userId) {
14646        intent = new Intent(intent);
14647
14648        // By default broadcasts do not go to stopped apps.
14649        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14650
14651        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14652            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14653            + " ordered=" + ordered + " userid=" + userId);
14654        if ((resultTo != null) && !ordered) {
14655            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14656        }
14657
14658        userId = handleIncomingUser(callingPid, callingUid, userId,
14659                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14660
14661        // Make sure that the user who is receiving this broadcast is started.
14662        // If not, we will just skip it.
14663
14664
14665        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14666            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14667                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14668                Slog.w(TAG, "Skipping broadcast of " + intent
14669                        + ": user " + userId + " is stopped");
14670                return ActivityManager.BROADCAST_SUCCESS;
14671            }
14672        }
14673
14674        /*
14675         * Prevent non-system code (defined here to be non-persistent
14676         * processes) from sending protected broadcasts.
14677         */
14678        int callingAppId = UserHandle.getAppId(callingUid);
14679        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14680            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14681            || callingAppId == Process.NFC_UID || callingUid == 0) {
14682            // Always okay.
14683        } else if (callerApp == null || !callerApp.persistent) {
14684            try {
14685                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14686                        intent.getAction())) {
14687                    String msg = "Permission Denial: not allowed to send broadcast "
14688                            + intent.getAction() + " from pid="
14689                            + callingPid + ", uid=" + callingUid;
14690                    Slog.w(TAG, msg);
14691                    throw new SecurityException(msg);
14692                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14693                    // Special case for compatibility: we don't want apps to send this,
14694                    // but historically it has not been protected and apps may be using it
14695                    // to poke their own app widget.  So, instead of making it protected,
14696                    // just limit it to the caller.
14697                    if (callerApp == null) {
14698                        String msg = "Permission Denial: not allowed to send broadcast "
14699                                + intent.getAction() + " from unknown caller.";
14700                        Slog.w(TAG, msg);
14701                        throw new SecurityException(msg);
14702                    } else if (intent.getComponent() != null) {
14703                        // They are good enough to send to an explicit component...  verify
14704                        // it is being sent to the calling app.
14705                        if (!intent.getComponent().getPackageName().equals(
14706                                callerApp.info.packageName)) {
14707                            String msg = "Permission Denial: not allowed to send broadcast "
14708                                    + intent.getAction() + " to "
14709                                    + intent.getComponent().getPackageName() + " from "
14710                                    + callerApp.info.packageName;
14711                            Slog.w(TAG, msg);
14712                            throw new SecurityException(msg);
14713                        }
14714                    } else {
14715                        // Limit broadcast to their own package.
14716                        intent.setPackage(callerApp.info.packageName);
14717                    }
14718                }
14719            } catch (RemoteException e) {
14720                Slog.w(TAG, "Remote exception", e);
14721                return ActivityManager.BROADCAST_SUCCESS;
14722            }
14723        }
14724
14725        // Handle special intents: if this broadcast is from the package
14726        // manager about a package being removed, we need to remove all of
14727        // its activities from the history stack.
14728        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14729                intent.getAction());
14730        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14731                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14732                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14733                || uidRemoved) {
14734            if (checkComponentPermission(
14735                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14736                    callingPid, callingUid, -1, true)
14737                    == PackageManager.PERMISSION_GRANTED) {
14738                if (uidRemoved) {
14739                    final Bundle intentExtras = intent.getExtras();
14740                    final int uid = intentExtras != null
14741                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14742                    if (uid >= 0) {
14743                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14744                        synchronized (bs) {
14745                            bs.removeUidStatsLocked(uid);
14746                        }
14747                        mAppOpsService.uidRemoved(uid);
14748                    }
14749                } else {
14750                    // If resources are unavailable just force stop all
14751                    // those packages and flush the attribute cache as well.
14752                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14753                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14754                        if (list != null && (list.length > 0)) {
14755                            for (String pkg : list) {
14756                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14757                                        "storage unmount");
14758                            }
14759                            sendPackageBroadcastLocked(
14760                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14761                        }
14762                    } else {
14763                        Uri data = intent.getData();
14764                        String ssp;
14765                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14766                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14767                                    intent.getAction());
14768                            boolean fullUninstall = removed &&
14769                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14770                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14771                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14772                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14773                                        false, fullUninstall, userId,
14774                                        removed ? "pkg removed" : "pkg changed");
14775                            }
14776                            if (removed) {
14777                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14778                                        new String[] {ssp}, userId);
14779                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14780                                    mAppOpsService.packageRemoved(
14781                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14782
14783                                    // Remove all permissions granted from/to this package
14784                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14785                                }
14786                            }
14787                        }
14788                    }
14789                }
14790            } else {
14791                String msg = "Permission Denial: " + intent.getAction()
14792                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14793                        + ", uid=" + callingUid + ")"
14794                        + " requires "
14795                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14796                Slog.w(TAG, msg);
14797                throw new SecurityException(msg);
14798            }
14799
14800        // Special case for adding a package: by default turn on compatibility
14801        // mode.
14802        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14803            Uri data = intent.getData();
14804            String ssp;
14805            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14806                mCompatModePackages.handlePackageAddedLocked(ssp,
14807                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14808            }
14809        }
14810
14811        /*
14812         * If this is the time zone changed action, queue up a message that will reset the timezone
14813         * of all currently running processes. This message will get queued up before the broadcast
14814         * happens.
14815         */
14816        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14817            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14818        }
14819
14820        /*
14821         * If the user set the time, let all running processes know.
14822         */
14823        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14824            final int is24Hour = intent.getBooleanExtra(
14825                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14826            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14827        }
14828
14829        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14830            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14831        }
14832
14833        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14834            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14835            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14836        }
14837
14838        // Add to the sticky list if requested.
14839        if (sticky) {
14840            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14841                    callingPid, callingUid)
14842                    != PackageManager.PERMISSION_GRANTED) {
14843                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14844                        + callingPid + ", uid=" + callingUid
14845                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14846                Slog.w(TAG, msg);
14847                throw new SecurityException(msg);
14848            }
14849            if (requiredPermission != null) {
14850                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14851                        + " and enforce permission " + requiredPermission);
14852                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14853            }
14854            if (intent.getComponent() != null) {
14855                throw new SecurityException(
14856                        "Sticky broadcasts can't target a specific component");
14857            }
14858            // We use userId directly here, since the "all" target is maintained
14859            // as a separate set of sticky broadcasts.
14860            if (userId != UserHandle.USER_ALL) {
14861                // But first, if this is not a broadcast to all users, then
14862                // make sure it doesn't conflict with an existing broadcast to
14863                // all users.
14864                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14865                        UserHandle.USER_ALL);
14866                if (stickies != null) {
14867                    ArrayList<Intent> list = stickies.get(intent.getAction());
14868                    if (list != null) {
14869                        int N = list.size();
14870                        int i;
14871                        for (i=0; i<N; i++) {
14872                            if (intent.filterEquals(list.get(i))) {
14873                                throw new IllegalArgumentException(
14874                                        "Sticky broadcast " + intent + " for user "
14875                                        + userId + " conflicts with existing global broadcast");
14876                            }
14877                        }
14878                    }
14879                }
14880            }
14881            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14882            if (stickies == null) {
14883                stickies = new ArrayMap<String, ArrayList<Intent>>();
14884                mStickyBroadcasts.put(userId, stickies);
14885            }
14886            ArrayList<Intent> list = stickies.get(intent.getAction());
14887            if (list == null) {
14888                list = new ArrayList<Intent>();
14889                stickies.put(intent.getAction(), list);
14890            }
14891            int N = list.size();
14892            int i;
14893            for (i=0; i<N; i++) {
14894                if (intent.filterEquals(list.get(i))) {
14895                    // This sticky already exists, replace it.
14896                    list.set(i, new Intent(intent));
14897                    break;
14898                }
14899            }
14900            if (i >= N) {
14901                list.add(new Intent(intent));
14902            }
14903        }
14904
14905        int[] users;
14906        if (userId == UserHandle.USER_ALL) {
14907            // Caller wants broadcast to go to all started users.
14908            users = mStartedUserArray;
14909        } else {
14910            // Caller wants broadcast to go to one specific user.
14911            users = new int[] {userId};
14912        }
14913
14914        // Figure out who all will receive this broadcast.
14915        List receivers = null;
14916        List<BroadcastFilter> registeredReceivers = null;
14917        // Need to resolve the intent to interested receivers...
14918        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14919                 == 0) {
14920            receivers = collectReceiverComponents(intent, resolvedType, users);
14921        }
14922        if (intent.getComponent() == null) {
14923            registeredReceivers = mReceiverResolver.queryIntent(intent,
14924                    resolvedType, false, userId);
14925        }
14926
14927        final boolean replacePending =
14928                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14929
14930        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14931                + " replacePending=" + replacePending);
14932
14933        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14934        if (!ordered && NR > 0) {
14935            // If we are not serializing this broadcast, then send the
14936            // registered receivers separately so they don't wait for the
14937            // components to be launched.
14938            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14939            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14940                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14941                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14942                    ordered, sticky, false, userId);
14943            if (DEBUG_BROADCAST) Slog.v(
14944                    TAG, "Enqueueing parallel broadcast " + r);
14945            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14946            if (!replaced) {
14947                queue.enqueueParallelBroadcastLocked(r);
14948                queue.scheduleBroadcastsLocked();
14949            }
14950            registeredReceivers = null;
14951            NR = 0;
14952        }
14953
14954        // Merge into one list.
14955        int ir = 0;
14956        if (receivers != null) {
14957            // A special case for PACKAGE_ADDED: do not allow the package
14958            // being added to see this broadcast.  This prevents them from
14959            // using this as a back door to get run as soon as they are
14960            // installed.  Maybe in the future we want to have a special install
14961            // broadcast or such for apps, but we'd like to deliberately make
14962            // this decision.
14963            String skipPackages[] = null;
14964            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14965                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14966                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14967                Uri data = intent.getData();
14968                if (data != null) {
14969                    String pkgName = data.getSchemeSpecificPart();
14970                    if (pkgName != null) {
14971                        skipPackages = new String[] { pkgName };
14972                    }
14973                }
14974            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14975                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14976            }
14977            if (skipPackages != null && (skipPackages.length > 0)) {
14978                for (String skipPackage : skipPackages) {
14979                    if (skipPackage != null) {
14980                        int NT = receivers.size();
14981                        for (int it=0; it<NT; it++) {
14982                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14983                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14984                                receivers.remove(it);
14985                                it--;
14986                                NT--;
14987                            }
14988                        }
14989                    }
14990                }
14991            }
14992
14993            int NT = receivers != null ? receivers.size() : 0;
14994            int it = 0;
14995            ResolveInfo curt = null;
14996            BroadcastFilter curr = null;
14997            while (it < NT && ir < NR) {
14998                if (curt == null) {
14999                    curt = (ResolveInfo)receivers.get(it);
15000                }
15001                if (curr == null) {
15002                    curr = registeredReceivers.get(ir);
15003                }
15004                if (curr.getPriority() >= curt.priority) {
15005                    // Insert this broadcast record into the final list.
15006                    receivers.add(it, curr);
15007                    ir++;
15008                    curr = null;
15009                    it++;
15010                    NT++;
15011                } else {
15012                    // Skip to the next ResolveInfo in the final list.
15013                    it++;
15014                    curt = null;
15015                }
15016            }
15017        }
15018        while (ir < NR) {
15019            if (receivers == null) {
15020                receivers = new ArrayList();
15021            }
15022            receivers.add(registeredReceivers.get(ir));
15023            ir++;
15024        }
15025
15026        if ((receivers != null && receivers.size() > 0)
15027                || resultTo != null) {
15028            BroadcastQueue queue = broadcastQueueForIntent(intent);
15029            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15030                    callerPackage, callingPid, callingUid, resolvedType,
15031                    requiredPermission, appOp, receivers, resultTo, resultCode,
15032                    resultData, map, ordered, sticky, false, userId);
15033            if (DEBUG_BROADCAST) Slog.v(
15034                    TAG, "Enqueueing ordered broadcast " + r
15035                    + ": prev had " + queue.mOrderedBroadcasts.size());
15036            if (DEBUG_BROADCAST) {
15037                int seq = r.intent.getIntExtra("seq", -1);
15038                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15039            }
15040            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15041            if (!replaced) {
15042                queue.enqueueOrderedBroadcastLocked(r);
15043                queue.scheduleBroadcastsLocked();
15044            }
15045        }
15046
15047        return ActivityManager.BROADCAST_SUCCESS;
15048    }
15049
15050    final Intent verifyBroadcastLocked(Intent intent) {
15051        // Refuse possible leaked file descriptors
15052        if (intent != null && intent.hasFileDescriptors() == true) {
15053            throw new IllegalArgumentException("File descriptors passed in Intent");
15054        }
15055
15056        int flags = intent.getFlags();
15057
15058        if (!mProcessesReady) {
15059            // if the caller really truly claims to know what they're doing, go
15060            // ahead and allow the broadcast without launching any receivers
15061            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15062                intent = new Intent(intent);
15063                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15064            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15065                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15066                        + " before boot completion");
15067                throw new IllegalStateException("Cannot broadcast before boot completed");
15068            }
15069        }
15070
15071        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15072            throw new IllegalArgumentException(
15073                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15074        }
15075
15076        return intent;
15077    }
15078
15079    public final int broadcastIntent(IApplicationThread caller,
15080            Intent intent, String resolvedType, IIntentReceiver resultTo,
15081            int resultCode, String resultData, Bundle map,
15082            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15083        enforceNotIsolatedCaller("broadcastIntent");
15084        synchronized(this) {
15085            intent = verifyBroadcastLocked(intent);
15086
15087            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15088            final int callingPid = Binder.getCallingPid();
15089            final int callingUid = Binder.getCallingUid();
15090            final long origId = Binder.clearCallingIdentity();
15091            int res = broadcastIntentLocked(callerApp,
15092                    callerApp != null ? callerApp.info.packageName : null,
15093                    intent, resolvedType, resultTo,
15094                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15095                    callingPid, callingUid, userId);
15096            Binder.restoreCallingIdentity(origId);
15097            return res;
15098        }
15099    }
15100
15101    int broadcastIntentInPackage(String packageName, int uid,
15102            Intent intent, String resolvedType, IIntentReceiver resultTo,
15103            int resultCode, String resultData, Bundle map,
15104            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15105        synchronized(this) {
15106            intent = verifyBroadcastLocked(intent);
15107
15108            final long origId = Binder.clearCallingIdentity();
15109            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15110                    resultTo, resultCode, resultData, map, requiredPermission,
15111                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15112            Binder.restoreCallingIdentity(origId);
15113            return res;
15114        }
15115    }
15116
15117    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15118        // Refuse possible leaked file descriptors
15119        if (intent != null && intent.hasFileDescriptors() == true) {
15120            throw new IllegalArgumentException("File descriptors passed in Intent");
15121        }
15122
15123        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15124                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15125
15126        synchronized(this) {
15127            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15128                    != PackageManager.PERMISSION_GRANTED) {
15129                String msg = "Permission Denial: unbroadcastIntent() from pid="
15130                        + Binder.getCallingPid()
15131                        + ", uid=" + Binder.getCallingUid()
15132                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15133                Slog.w(TAG, msg);
15134                throw new SecurityException(msg);
15135            }
15136            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15137            if (stickies != null) {
15138                ArrayList<Intent> list = stickies.get(intent.getAction());
15139                if (list != null) {
15140                    int N = list.size();
15141                    int i;
15142                    for (i=0; i<N; i++) {
15143                        if (intent.filterEquals(list.get(i))) {
15144                            list.remove(i);
15145                            break;
15146                        }
15147                    }
15148                    if (list.size() <= 0) {
15149                        stickies.remove(intent.getAction());
15150                    }
15151                }
15152                if (stickies.size() <= 0) {
15153                    mStickyBroadcasts.remove(userId);
15154                }
15155            }
15156        }
15157    }
15158
15159    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15160            String resultData, Bundle resultExtras, boolean resultAbort) {
15161        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15162        if (r == null) {
15163            Slog.w(TAG, "finishReceiver called but not found on queue");
15164            return false;
15165        }
15166
15167        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15168    }
15169
15170    void backgroundServicesFinishedLocked(int userId) {
15171        for (BroadcastQueue queue : mBroadcastQueues) {
15172            queue.backgroundServicesFinishedLocked(userId);
15173        }
15174    }
15175
15176    public void finishReceiver(IBinder who, int resultCode, String resultData,
15177            Bundle resultExtras, boolean resultAbort) {
15178        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15179
15180        // Refuse possible leaked file descriptors
15181        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15182            throw new IllegalArgumentException("File descriptors passed in Bundle");
15183        }
15184
15185        final long origId = Binder.clearCallingIdentity();
15186        try {
15187            boolean doNext = false;
15188            BroadcastRecord r;
15189
15190            synchronized(this) {
15191                r = broadcastRecordForReceiverLocked(who);
15192                if (r != null) {
15193                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15194                        resultData, resultExtras, resultAbort, true);
15195                }
15196            }
15197
15198            if (doNext) {
15199                r.queue.processNextBroadcast(false);
15200            }
15201            trimApplications();
15202        } finally {
15203            Binder.restoreCallingIdentity(origId);
15204        }
15205    }
15206
15207    // =========================================================
15208    // INSTRUMENTATION
15209    // =========================================================
15210
15211    public boolean startInstrumentation(ComponentName className,
15212            String profileFile, int flags, Bundle arguments,
15213            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15214            int userId, String abiOverride) {
15215        enforceNotIsolatedCaller("startInstrumentation");
15216        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15217                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15218        // Refuse possible leaked file descriptors
15219        if (arguments != null && arguments.hasFileDescriptors()) {
15220            throw new IllegalArgumentException("File descriptors passed in Bundle");
15221        }
15222
15223        synchronized(this) {
15224            InstrumentationInfo ii = null;
15225            ApplicationInfo ai = null;
15226            try {
15227                ii = mContext.getPackageManager().getInstrumentationInfo(
15228                    className, STOCK_PM_FLAGS);
15229                ai = AppGlobals.getPackageManager().getApplicationInfo(
15230                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15231            } catch (PackageManager.NameNotFoundException e) {
15232            } catch (RemoteException e) {
15233            }
15234            if (ii == null) {
15235                reportStartInstrumentationFailure(watcher, className,
15236                        "Unable to find instrumentation info for: " + className);
15237                return false;
15238            }
15239            if (ai == null) {
15240                reportStartInstrumentationFailure(watcher, className,
15241                        "Unable to find instrumentation target package: " + ii.targetPackage);
15242                return false;
15243            }
15244
15245            int match = mContext.getPackageManager().checkSignatures(
15246                    ii.targetPackage, ii.packageName);
15247            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15248                String msg = "Permission Denial: starting instrumentation "
15249                        + className + " from pid="
15250                        + Binder.getCallingPid()
15251                        + ", uid=" + Binder.getCallingPid()
15252                        + " not allowed because package " + ii.packageName
15253                        + " does not have a signature matching the target "
15254                        + ii.targetPackage;
15255                reportStartInstrumentationFailure(watcher, className, msg);
15256                throw new SecurityException(msg);
15257            }
15258
15259            final long origId = Binder.clearCallingIdentity();
15260            // Instrumentation can kill and relaunch even persistent processes
15261            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15262                    "start instr");
15263            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15264            app.instrumentationClass = className;
15265            app.instrumentationInfo = ai;
15266            app.instrumentationProfileFile = profileFile;
15267            app.instrumentationArguments = arguments;
15268            app.instrumentationWatcher = watcher;
15269            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15270            app.instrumentationResultClass = className;
15271            Binder.restoreCallingIdentity(origId);
15272        }
15273
15274        return true;
15275    }
15276
15277    /**
15278     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15279     * error to the logs, but if somebody is watching, send the report there too.  This enables
15280     * the "am" command to report errors with more information.
15281     *
15282     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15283     * @param cn The component name of the instrumentation.
15284     * @param report The error report.
15285     */
15286    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15287            ComponentName cn, String report) {
15288        Slog.w(TAG, report);
15289        try {
15290            if (watcher != null) {
15291                Bundle results = new Bundle();
15292                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15293                results.putString("Error", report);
15294                watcher.instrumentationStatus(cn, -1, results);
15295            }
15296        } catch (RemoteException e) {
15297            Slog.w(TAG, e);
15298        }
15299    }
15300
15301    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15302        if (app.instrumentationWatcher != null) {
15303            try {
15304                // NOTE:  IInstrumentationWatcher *must* be oneway here
15305                app.instrumentationWatcher.instrumentationFinished(
15306                    app.instrumentationClass,
15307                    resultCode,
15308                    results);
15309            } catch (RemoteException e) {
15310            }
15311        }
15312        if (app.instrumentationUiAutomationConnection != null) {
15313            try {
15314                app.instrumentationUiAutomationConnection.shutdown();
15315            } catch (RemoteException re) {
15316                /* ignore */
15317            }
15318            // Only a UiAutomation can set this flag and now that
15319            // it is finished we make sure it is reset to its default.
15320            mUserIsMonkey = false;
15321        }
15322        app.instrumentationWatcher = null;
15323        app.instrumentationUiAutomationConnection = null;
15324        app.instrumentationClass = null;
15325        app.instrumentationInfo = null;
15326        app.instrumentationProfileFile = null;
15327        app.instrumentationArguments = null;
15328
15329        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15330                "finished inst");
15331    }
15332
15333    public void finishInstrumentation(IApplicationThread target,
15334            int resultCode, Bundle results) {
15335        int userId = UserHandle.getCallingUserId();
15336        // Refuse possible leaked file descriptors
15337        if (results != null && results.hasFileDescriptors()) {
15338            throw new IllegalArgumentException("File descriptors passed in Intent");
15339        }
15340
15341        synchronized(this) {
15342            ProcessRecord app = getRecordForAppLocked(target);
15343            if (app == null) {
15344                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15345                return;
15346            }
15347            final long origId = Binder.clearCallingIdentity();
15348            finishInstrumentationLocked(app, resultCode, results);
15349            Binder.restoreCallingIdentity(origId);
15350        }
15351    }
15352
15353    // =========================================================
15354    // CONFIGURATION
15355    // =========================================================
15356
15357    public ConfigurationInfo getDeviceConfigurationInfo() {
15358        ConfigurationInfo config = new ConfigurationInfo();
15359        synchronized (this) {
15360            config.reqTouchScreen = mConfiguration.touchscreen;
15361            config.reqKeyboardType = mConfiguration.keyboard;
15362            config.reqNavigation = mConfiguration.navigation;
15363            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15364                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15365                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15366            }
15367            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15368                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15369                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15370            }
15371            config.reqGlEsVersion = GL_ES_VERSION;
15372        }
15373        return config;
15374    }
15375
15376    ActivityStack getFocusedStack() {
15377        return mStackSupervisor.getFocusedStack();
15378    }
15379
15380    public Configuration getConfiguration() {
15381        Configuration ci;
15382        synchronized(this) {
15383            ci = new Configuration(mConfiguration);
15384        }
15385        return ci;
15386    }
15387
15388    public void updatePersistentConfiguration(Configuration values) {
15389        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15390                "updateConfiguration()");
15391        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15392                "updateConfiguration()");
15393        if (values == null) {
15394            throw new NullPointerException("Configuration must not be null");
15395        }
15396
15397        synchronized(this) {
15398            final long origId = Binder.clearCallingIdentity();
15399            updateConfigurationLocked(values, null, true, false);
15400            Binder.restoreCallingIdentity(origId);
15401        }
15402    }
15403
15404    public void updateConfiguration(Configuration values) {
15405        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15406                "updateConfiguration()");
15407
15408        synchronized(this) {
15409            if (values == null && mWindowManager != null) {
15410                // sentinel: fetch the current configuration from the window manager
15411                values = mWindowManager.computeNewConfiguration();
15412            }
15413
15414            if (mWindowManager != null) {
15415                mProcessList.applyDisplaySize(mWindowManager);
15416            }
15417
15418            final long origId = Binder.clearCallingIdentity();
15419            if (values != null) {
15420                Settings.System.clearConfiguration(values);
15421            }
15422            updateConfigurationLocked(values, null, false, false);
15423            Binder.restoreCallingIdentity(origId);
15424        }
15425    }
15426
15427    /**
15428     * Do either or both things: (1) change the current configuration, and (2)
15429     * make sure the given activity is running with the (now) current
15430     * configuration.  Returns true if the activity has been left running, or
15431     * false if <var>starting</var> is being destroyed to match the new
15432     * configuration.
15433     * @param persistent TODO
15434     */
15435    boolean updateConfigurationLocked(Configuration values,
15436            ActivityRecord starting, boolean persistent, boolean initLocale) {
15437        int changes = 0;
15438
15439        if (values != null) {
15440            Configuration newConfig = new Configuration(mConfiguration);
15441            changes = newConfig.updateFrom(values);
15442            if (changes != 0) {
15443                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15444                    Slog.i(TAG, "Updating configuration to: " + values);
15445                }
15446
15447                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15448
15449                if (values.locale != null && !initLocale) {
15450                    saveLocaleLocked(values.locale,
15451                                     !values.locale.equals(mConfiguration.locale),
15452                                     values.userSetLocale);
15453                }
15454
15455                mConfigurationSeq++;
15456                if (mConfigurationSeq <= 0) {
15457                    mConfigurationSeq = 1;
15458                }
15459                newConfig.seq = mConfigurationSeq;
15460                mConfiguration = newConfig;
15461                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15462                //mUsageStatsService.noteStartConfig(newConfig);
15463
15464                final Configuration configCopy = new Configuration(mConfiguration);
15465
15466                // TODO: If our config changes, should we auto dismiss any currently
15467                // showing dialogs?
15468                mShowDialogs = shouldShowDialogs(newConfig);
15469
15470                AttributeCache ac = AttributeCache.instance();
15471                if (ac != null) {
15472                    ac.updateConfiguration(configCopy);
15473                }
15474
15475                // Make sure all resources in our process are updated
15476                // right now, so that anyone who is going to retrieve
15477                // resource values after we return will be sure to get
15478                // the new ones.  This is especially important during
15479                // boot, where the first config change needs to guarantee
15480                // all resources have that config before following boot
15481                // code is executed.
15482                mSystemThread.applyConfigurationToResources(configCopy);
15483
15484                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15485                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15486                    msg.obj = new Configuration(configCopy);
15487                    mHandler.sendMessage(msg);
15488                }
15489
15490                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15491                    ProcessRecord app = mLruProcesses.get(i);
15492                    try {
15493                        if (app.thread != null) {
15494                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15495                                    + app.processName + " new config " + mConfiguration);
15496                            app.thread.scheduleConfigurationChanged(configCopy);
15497                        }
15498                    } catch (Exception e) {
15499                    }
15500                }
15501                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15502                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15503                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15504                        | Intent.FLAG_RECEIVER_FOREGROUND);
15505                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15506                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15507                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15508                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15509                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15510                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15511                    broadcastIntentLocked(null, null, intent,
15512                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15513                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15514                }
15515            }
15516        }
15517
15518        boolean kept = true;
15519        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15520        // mainStack is null during startup.
15521        if (mainStack != null) {
15522            if (changes != 0 && starting == null) {
15523                // If the configuration changed, and the caller is not already
15524                // in the process of starting an activity, then find the top
15525                // activity to check if its configuration needs to change.
15526                starting = mainStack.topRunningActivityLocked(null);
15527            }
15528
15529            if (starting != null) {
15530                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15531                // And we need to make sure at this point that all other activities
15532                // are made visible with the correct configuration.
15533                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15534            }
15535        }
15536
15537        if (values != null && mWindowManager != null) {
15538            mWindowManager.setNewConfiguration(mConfiguration);
15539        }
15540
15541        return kept;
15542    }
15543
15544    /**
15545     * Decide based on the configuration whether we should shouw the ANR,
15546     * crash, etc dialogs.  The idea is that if there is no affordnace to
15547     * press the on-screen buttons, we shouldn't show the dialog.
15548     *
15549     * A thought: SystemUI might also want to get told about this, the Power
15550     * dialog / global actions also might want different behaviors.
15551     */
15552    private static final boolean shouldShowDialogs(Configuration config) {
15553        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15554                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15555    }
15556
15557    /**
15558     * Save the locale.  You must be inside a synchronized (this) block.
15559     */
15560    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15561        if(isDiff) {
15562            SystemProperties.set("user.language", l.getLanguage());
15563            SystemProperties.set("user.region", l.getCountry());
15564        }
15565
15566        if(isPersist) {
15567            SystemProperties.set("persist.sys.language", l.getLanguage());
15568            SystemProperties.set("persist.sys.country", l.getCountry());
15569            SystemProperties.set("persist.sys.localevar", l.getVariant());
15570        }
15571    }
15572
15573    @Override
15574    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15575        ActivityRecord srec = ActivityRecord.forToken(token);
15576        return srec != null && srec.task.affinity != null &&
15577                srec.task.affinity.equals(destAffinity);
15578    }
15579
15580    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15581            Intent resultData) {
15582
15583        synchronized (this) {
15584            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15585            if (stack != null) {
15586                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15587            }
15588            return false;
15589        }
15590    }
15591
15592    public int getLaunchedFromUid(IBinder activityToken) {
15593        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15594        if (srec == null) {
15595            return -1;
15596        }
15597        return srec.launchedFromUid;
15598    }
15599
15600    public String getLaunchedFromPackage(IBinder activityToken) {
15601        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15602        if (srec == null) {
15603            return null;
15604        }
15605        return srec.launchedFromPackage;
15606    }
15607
15608    // =========================================================
15609    // LIFETIME MANAGEMENT
15610    // =========================================================
15611
15612    // Returns which broadcast queue the app is the current [or imminent] receiver
15613    // on, or 'null' if the app is not an active broadcast recipient.
15614    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15615        BroadcastRecord r = app.curReceiver;
15616        if (r != null) {
15617            return r.queue;
15618        }
15619
15620        // It's not the current receiver, but it might be starting up to become one
15621        synchronized (this) {
15622            for (BroadcastQueue queue : mBroadcastQueues) {
15623                r = queue.mPendingBroadcast;
15624                if (r != null && r.curApp == app) {
15625                    // found it; report which queue it's in
15626                    return queue;
15627                }
15628            }
15629        }
15630
15631        return null;
15632    }
15633
15634    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15635            boolean doingAll, long now) {
15636        if (mAdjSeq == app.adjSeq) {
15637            // This adjustment has already been computed.
15638            return app.curRawAdj;
15639        }
15640
15641        if (app.thread == null) {
15642            app.adjSeq = mAdjSeq;
15643            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15644            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15645            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15646        }
15647
15648        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15649        app.adjSource = null;
15650        app.adjTarget = null;
15651        app.empty = false;
15652        app.cached = false;
15653
15654        final int activitiesSize = app.activities.size();
15655
15656        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15657            // The max adjustment doesn't allow this app to be anything
15658            // below foreground, so it is not worth doing work for it.
15659            app.adjType = "fixed";
15660            app.adjSeq = mAdjSeq;
15661            app.curRawAdj = app.maxAdj;
15662            app.foregroundActivities = false;
15663            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15664            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15665            // System processes can do UI, and when they do we want to have
15666            // them trim their memory after the user leaves the UI.  To
15667            // facilitate this, here we need to determine whether or not it
15668            // is currently showing UI.
15669            app.systemNoUi = true;
15670            if (app == TOP_APP) {
15671                app.systemNoUi = false;
15672            } else if (activitiesSize > 0) {
15673                for (int j = 0; j < activitiesSize; j++) {
15674                    final ActivityRecord r = app.activities.get(j);
15675                    if (r.visible) {
15676                        app.systemNoUi = false;
15677                    }
15678                }
15679            }
15680            if (!app.systemNoUi) {
15681                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15682            }
15683            return (app.curAdj=app.maxAdj);
15684        }
15685
15686        app.systemNoUi = false;
15687
15688        // Determine the importance of the process, starting with most
15689        // important to least, and assign an appropriate OOM adjustment.
15690        int adj;
15691        int schedGroup;
15692        int procState;
15693        boolean foregroundActivities = false;
15694        BroadcastQueue queue;
15695        if (app == TOP_APP) {
15696            // The last app on the list is the foreground app.
15697            adj = ProcessList.FOREGROUND_APP_ADJ;
15698            schedGroup = Process.THREAD_GROUP_DEFAULT;
15699            app.adjType = "top-activity";
15700            foregroundActivities = true;
15701            procState = ActivityManager.PROCESS_STATE_TOP;
15702        } else if (app.instrumentationClass != null) {
15703            // Don't want to kill running instrumentation.
15704            adj = ProcessList.FOREGROUND_APP_ADJ;
15705            schedGroup = Process.THREAD_GROUP_DEFAULT;
15706            app.adjType = "instrumentation";
15707            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15708        } else if ((queue = isReceivingBroadcast(app)) != null) {
15709            // An app that is currently receiving a broadcast also
15710            // counts as being in the foreground for OOM killer purposes.
15711            // It's placed in a sched group based on the nature of the
15712            // broadcast as reflected by which queue it's active in.
15713            adj = ProcessList.FOREGROUND_APP_ADJ;
15714            schedGroup = (queue == mFgBroadcastQueue)
15715                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15716            app.adjType = "broadcast";
15717            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15718        } else if (app.executingServices.size() > 0) {
15719            // An app that is currently executing a service callback also
15720            // counts as being in the foreground.
15721            adj = ProcessList.FOREGROUND_APP_ADJ;
15722            schedGroup = app.execServicesFg ?
15723                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15724            app.adjType = "exec-service";
15725            procState = ActivityManager.PROCESS_STATE_SERVICE;
15726            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15727        } else {
15728            // As far as we know the process is empty.  We may change our mind later.
15729            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15730            // At this point we don't actually know the adjustment.  Use the cached adj
15731            // value that the caller wants us to.
15732            adj = cachedAdj;
15733            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15734            app.cached = true;
15735            app.empty = true;
15736            app.adjType = "cch-empty";
15737        }
15738
15739        // Examine all activities if not already foreground.
15740        if (!foregroundActivities && activitiesSize > 0) {
15741            for (int j = 0; j < activitiesSize; j++) {
15742                final ActivityRecord r = app.activities.get(j);
15743                if (r.app != app) {
15744                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15745                            + app + "?!?");
15746                    continue;
15747                }
15748                if (r.visible) {
15749                    // App has a visible activity; only upgrade adjustment.
15750                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15751                        adj = ProcessList.VISIBLE_APP_ADJ;
15752                        app.adjType = "visible";
15753                    }
15754                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15755                        procState = ActivityManager.PROCESS_STATE_TOP;
15756                    }
15757                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15758                    app.cached = false;
15759                    app.empty = false;
15760                    foregroundActivities = true;
15761                    break;
15762                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15763                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15764                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15765                        app.adjType = "pausing";
15766                    }
15767                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15768                        procState = ActivityManager.PROCESS_STATE_TOP;
15769                    }
15770                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15771                    app.cached = false;
15772                    app.empty = false;
15773                    foregroundActivities = true;
15774                } else if (r.state == ActivityState.STOPPING) {
15775                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15776                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15777                        app.adjType = "stopping";
15778                    }
15779                    // For the process state, we will at this point consider the
15780                    // process to be cached.  It will be cached either as an activity
15781                    // or empty depending on whether the activity is finishing.  We do
15782                    // this so that we can treat the process as cached for purposes of
15783                    // memory trimming (determing current memory level, trim command to
15784                    // send to process) since there can be an arbitrary number of stopping
15785                    // processes and they should soon all go into the cached state.
15786                    if (!r.finishing) {
15787                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15788                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15789                        }
15790                    }
15791                    app.cached = false;
15792                    app.empty = false;
15793                    foregroundActivities = true;
15794                } else {
15795                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15796                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15797                        app.adjType = "cch-act";
15798                    }
15799                }
15800            }
15801        }
15802
15803        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15804            if (app.foregroundServices) {
15805                // The user is aware of this app, so make it visible.
15806                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15807                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15808                app.cached = false;
15809                app.adjType = "fg-service";
15810                schedGroup = Process.THREAD_GROUP_DEFAULT;
15811            } else if (app.forcingToForeground != null) {
15812                // The user is aware of this app, so make it visible.
15813                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15814                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15815                app.cached = false;
15816                app.adjType = "force-fg";
15817                app.adjSource = app.forcingToForeground;
15818                schedGroup = Process.THREAD_GROUP_DEFAULT;
15819            }
15820        }
15821
15822        if (app == mHeavyWeightProcess) {
15823            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15824                // We don't want to kill the current heavy-weight process.
15825                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15826                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15827                app.cached = false;
15828                app.adjType = "heavy";
15829            }
15830            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15831                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15832            }
15833        }
15834
15835        if (app == mHomeProcess) {
15836            if (adj > ProcessList.HOME_APP_ADJ) {
15837                // This process is hosting what we currently consider to be the
15838                // home app, so we don't want to let it go into the background.
15839                adj = ProcessList.HOME_APP_ADJ;
15840                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15841                app.cached = false;
15842                app.adjType = "home";
15843            }
15844            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15845                procState = ActivityManager.PROCESS_STATE_HOME;
15846            }
15847        }
15848
15849        if (app == mPreviousProcess && app.activities.size() > 0) {
15850            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15851                // This was the previous process that showed UI to the user.
15852                // We want to try to keep it around more aggressively, to give
15853                // a good experience around switching between two apps.
15854                adj = ProcessList.PREVIOUS_APP_ADJ;
15855                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15856                app.cached = false;
15857                app.adjType = "previous";
15858            }
15859            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15860                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15861            }
15862        }
15863
15864        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15865                + " reason=" + app.adjType);
15866
15867        // By default, we use the computed adjustment.  It may be changed if
15868        // there are applications dependent on our services or providers, but
15869        // this gives us a baseline and makes sure we don't get into an
15870        // infinite recursion.
15871        app.adjSeq = mAdjSeq;
15872        app.curRawAdj = adj;
15873        app.hasStartedServices = false;
15874
15875        if (mBackupTarget != null && app == mBackupTarget.app) {
15876            // If possible we want to avoid killing apps while they're being backed up
15877            if (adj > ProcessList.BACKUP_APP_ADJ) {
15878                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15879                adj = ProcessList.BACKUP_APP_ADJ;
15880                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15881                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15882                }
15883                app.adjType = "backup";
15884                app.cached = false;
15885            }
15886            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15887                procState = ActivityManager.PROCESS_STATE_BACKUP;
15888            }
15889        }
15890
15891        boolean mayBeTop = false;
15892
15893        for (int is = app.services.size()-1;
15894                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15895                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15896                        || procState > ActivityManager.PROCESS_STATE_TOP);
15897                is--) {
15898            ServiceRecord s = app.services.valueAt(is);
15899            if (s.startRequested) {
15900                app.hasStartedServices = true;
15901                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15902                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15903                }
15904                if (app.hasShownUi && app != mHomeProcess) {
15905                    // If this process has shown some UI, let it immediately
15906                    // go to the LRU list because it may be pretty heavy with
15907                    // UI stuff.  We'll tag it with a label just to help
15908                    // debug and understand what is going on.
15909                    if (adj > ProcessList.SERVICE_ADJ) {
15910                        app.adjType = "cch-started-ui-services";
15911                    }
15912                } else {
15913                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15914                        // This service has seen some activity within
15915                        // recent memory, so we will keep its process ahead
15916                        // of the background processes.
15917                        if (adj > ProcessList.SERVICE_ADJ) {
15918                            adj = ProcessList.SERVICE_ADJ;
15919                            app.adjType = "started-services";
15920                            app.cached = false;
15921                        }
15922                    }
15923                    // If we have let the service slide into the background
15924                    // state, still have some text describing what it is doing
15925                    // even though the service no longer has an impact.
15926                    if (adj > ProcessList.SERVICE_ADJ) {
15927                        app.adjType = "cch-started-services";
15928                    }
15929                }
15930            }
15931            for (int conni = s.connections.size()-1;
15932                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15933                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15934                            || procState > ActivityManager.PROCESS_STATE_TOP);
15935                    conni--) {
15936                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15937                for (int i = 0;
15938                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15939                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15940                                || procState > ActivityManager.PROCESS_STATE_TOP);
15941                        i++) {
15942                    // XXX should compute this based on the max of
15943                    // all connected clients.
15944                    ConnectionRecord cr = clist.get(i);
15945                    if (cr.binding.client == app) {
15946                        // Binding to ourself is not interesting.
15947                        continue;
15948                    }
15949                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15950                        ProcessRecord client = cr.binding.client;
15951                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15952                                TOP_APP, doingAll, now);
15953                        int clientProcState = client.curProcState;
15954                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15955                            // If the other app is cached for any reason, for purposes here
15956                            // we are going to consider it empty.  The specific cached state
15957                            // doesn't propagate except under certain conditions.
15958                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15959                        }
15960                        String adjType = null;
15961                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15962                            // Not doing bind OOM management, so treat
15963                            // this guy more like a started service.
15964                            if (app.hasShownUi && app != mHomeProcess) {
15965                                // If this process has shown some UI, let it immediately
15966                                // go to the LRU list because it may be pretty heavy with
15967                                // UI stuff.  We'll tag it with a label just to help
15968                                // debug and understand what is going on.
15969                                if (adj > clientAdj) {
15970                                    adjType = "cch-bound-ui-services";
15971                                }
15972                                app.cached = false;
15973                                clientAdj = adj;
15974                                clientProcState = procState;
15975                            } else {
15976                                if (now >= (s.lastActivity
15977                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15978                                    // This service has not seen activity within
15979                                    // recent memory, so allow it to drop to the
15980                                    // LRU list if there is no other reason to keep
15981                                    // it around.  We'll also tag it with a label just
15982                                    // to help debug and undertand what is going on.
15983                                    if (adj > clientAdj) {
15984                                        adjType = "cch-bound-services";
15985                                    }
15986                                    clientAdj = adj;
15987                                }
15988                            }
15989                        }
15990                        if (adj > clientAdj) {
15991                            // If this process has recently shown UI, and
15992                            // the process that is binding to it is less
15993                            // important than being visible, then we don't
15994                            // care about the binding as much as we care
15995                            // about letting this process get into the LRU
15996                            // list to be killed and restarted if needed for
15997                            // memory.
15998                            if (app.hasShownUi && app != mHomeProcess
15999                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16000                                adjType = "cch-bound-ui-services";
16001                            } else {
16002                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16003                                        |Context.BIND_IMPORTANT)) != 0) {
16004                                    adj = clientAdj;
16005                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16006                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16007                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16008                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16009                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16010                                    adj = clientAdj;
16011                                } else {
16012                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16013                                        adj = ProcessList.VISIBLE_APP_ADJ;
16014                                    }
16015                                }
16016                                if (!client.cached) {
16017                                    app.cached = false;
16018                                }
16019                                adjType = "service";
16020                            }
16021                        }
16022                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16023                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16024                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16025                            }
16026                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16027                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16028                                    // Special handling of clients who are in the top state.
16029                                    // We *may* want to consider this process to be in the
16030                                    // top state as well, but only if there is not another
16031                                    // reason for it to be running.  Being on the top is a
16032                                    // special state, meaning you are specifically running
16033                                    // for the current top app.  If the process is already
16034                                    // running in the background for some other reason, it
16035                                    // is more important to continue considering it to be
16036                                    // in the background state.
16037                                    mayBeTop = true;
16038                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16039                                } else {
16040                                    // Special handling for above-top states (persistent
16041                                    // processes).  These should not bring the current process
16042                                    // into the top state, since they are not on top.  Instead
16043                                    // give them the best state after that.
16044                                    clientProcState =
16045                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16046                                }
16047                            }
16048                        } else {
16049                            if (clientProcState <
16050                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16051                                clientProcState =
16052                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16053                            }
16054                        }
16055                        if (procState > clientProcState) {
16056                            procState = clientProcState;
16057                        }
16058                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16059                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16060                            app.pendingUiClean = true;
16061                        }
16062                        if (adjType != null) {
16063                            app.adjType = adjType;
16064                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16065                                    .REASON_SERVICE_IN_USE;
16066                            app.adjSource = cr.binding.client;
16067                            app.adjSourceProcState = clientProcState;
16068                            app.adjTarget = s.name;
16069                        }
16070                    }
16071                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16072                        app.treatLikeActivity = true;
16073                    }
16074                    final ActivityRecord a = cr.activity;
16075                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16076                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16077                                (a.visible || a.state == ActivityState.RESUMED
16078                                 || a.state == ActivityState.PAUSING)) {
16079                            adj = ProcessList.FOREGROUND_APP_ADJ;
16080                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16081                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16082                            }
16083                            app.cached = false;
16084                            app.adjType = "service";
16085                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16086                                    .REASON_SERVICE_IN_USE;
16087                            app.adjSource = a;
16088                            app.adjSourceProcState = procState;
16089                            app.adjTarget = s.name;
16090                        }
16091                    }
16092                }
16093            }
16094        }
16095
16096        for (int provi = app.pubProviders.size()-1;
16097                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16098                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16099                        || procState > ActivityManager.PROCESS_STATE_TOP);
16100                provi--) {
16101            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16102            for (int i = cpr.connections.size()-1;
16103                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16104                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16105                            || procState > ActivityManager.PROCESS_STATE_TOP);
16106                    i--) {
16107                ContentProviderConnection conn = cpr.connections.get(i);
16108                ProcessRecord client = conn.client;
16109                if (client == app) {
16110                    // Being our own client is not interesting.
16111                    continue;
16112                }
16113                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16114                int clientProcState = client.curProcState;
16115                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16116                    // If the other app is cached for any reason, for purposes here
16117                    // we are going to consider it empty.
16118                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16119                }
16120                if (adj > clientAdj) {
16121                    if (app.hasShownUi && app != mHomeProcess
16122                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16123                        app.adjType = "cch-ui-provider";
16124                    } else {
16125                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16126                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16127                        app.adjType = "provider";
16128                    }
16129                    app.cached &= client.cached;
16130                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16131                            .REASON_PROVIDER_IN_USE;
16132                    app.adjSource = client;
16133                    app.adjSourceProcState = clientProcState;
16134                    app.adjTarget = cpr.name;
16135                }
16136                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16137                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16138                        // Special handling of clients who are in the top state.
16139                        // We *may* want to consider this process to be in the
16140                        // top state as well, but only if there is not another
16141                        // reason for it to be running.  Being on the top is a
16142                        // special state, meaning you are specifically running
16143                        // for the current top app.  If the process is already
16144                        // running in the background for some other reason, it
16145                        // is more important to continue considering it to be
16146                        // in the background state.
16147                        mayBeTop = true;
16148                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16149                    } else {
16150                        // Special handling for above-top states (persistent
16151                        // processes).  These should not bring the current process
16152                        // into the top state, since they are not on top.  Instead
16153                        // give them the best state after that.
16154                        clientProcState =
16155                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16156                    }
16157                }
16158                if (procState > clientProcState) {
16159                    procState = clientProcState;
16160                }
16161                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16162                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16163                }
16164            }
16165            // If the provider has external (non-framework) process
16166            // dependencies, ensure that its adjustment is at least
16167            // FOREGROUND_APP_ADJ.
16168            if (cpr.hasExternalProcessHandles()) {
16169                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16170                    adj = ProcessList.FOREGROUND_APP_ADJ;
16171                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16172                    app.cached = false;
16173                    app.adjType = "provider";
16174                    app.adjTarget = cpr.name;
16175                }
16176                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16177                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16178                }
16179            }
16180        }
16181
16182        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16183            // A client of one of our services or providers is in the top state.  We
16184            // *may* want to be in the top state, but not if we are already running in
16185            // the background for some other reason.  For the decision here, we are going
16186            // to pick out a few specific states that we want to remain in when a client
16187            // is top (states that tend to be longer-term) and otherwise allow it to go
16188            // to the top state.
16189            switch (procState) {
16190                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16191                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16192                case ActivityManager.PROCESS_STATE_SERVICE:
16193                    // These all are longer-term states, so pull them up to the top
16194                    // of the background states, but not all the way to the top state.
16195                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16196                    break;
16197                default:
16198                    // Otherwise, top is a better choice, so take it.
16199                    procState = ActivityManager.PROCESS_STATE_TOP;
16200                    break;
16201            }
16202        }
16203
16204        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16205            if (app.hasClientActivities) {
16206                // This is a cached process, but with client activities.  Mark it so.
16207                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16208                app.adjType = "cch-client-act";
16209            } else if (app.treatLikeActivity) {
16210                // This is a cached process, but somebody wants us to treat it like it has
16211                // an activity, okay!
16212                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16213                app.adjType = "cch-as-act";
16214            }
16215        }
16216
16217        if (adj == ProcessList.SERVICE_ADJ) {
16218            if (doingAll) {
16219                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16220                mNewNumServiceProcs++;
16221                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16222                if (!app.serviceb) {
16223                    // This service isn't far enough down on the LRU list to
16224                    // normally be a B service, but if we are low on RAM and it
16225                    // is large we want to force it down since we would prefer to
16226                    // keep launcher over it.
16227                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16228                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16229                        app.serviceHighRam = true;
16230                        app.serviceb = true;
16231                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16232                    } else {
16233                        mNewNumAServiceProcs++;
16234                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16235                    }
16236                } else {
16237                    app.serviceHighRam = false;
16238                }
16239            }
16240            if (app.serviceb) {
16241                adj = ProcessList.SERVICE_B_ADJ;
16242            }
16243        }
16244
16245        app.curRawAdj = adj;
16246
16247        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16248        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16249        if (adj > app.maxAdj) {
16250            adj = app.maxAdj;
16251            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16252                schedGroup = Process.THREAD_GROUP_DEFAULT;
16253            }
16254        }
16255
16256        // Do final modification to adj.  Everything we do between here and applying
16257        // the final setAdj must be done in this function, because we will also use
16258        // it when computing the final cached adj later.  Note that we don't need to
16259        // worry about this for max adj above, since max adj will always be used to
16260        // keep it out of the cached vaues.
16261        app.curAdj = app.modifyRawOomAdj(adj);
16262        app.curSchedGroup = schedGroup;
16263        app.curProcState = procState;
16264        app.foregroundActivities = foregroundActivities;
16265
16266        return app.curRawAdj;
16267    }
16268
16269    /**
16270     * Schedule PSS collection of a process.
16271     */
16272    void requestPssLocked(ProcessRecord proc, int procState) {
16273        if (mPendingPssProcesses.contains(proc)) {
16274            return;
16275        }
16276        if (mPendingPssProcesses.size() == 0) {
16277            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16278        }
16279        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16280        proc.pssProcState = procState;
16281        mPendingPssProcesses.add(proc);
16282    }
16283
16284    /**
16285     * Schedule PSS collection of all processes.
16286     */
16287    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16288        if (!always) {
16289            if (now < (mLastFullPssTime +
16290                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16291                return;
16292            }
16293        }
16294        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16295        mLastFullPssTime = now;
16296        mFullPssPending = true;
16297        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16298        mPendingPssProcesses.clear();
16299        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16300            ProcessRecord app = mLruProcesses.get(i);
16301            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16302                app.pssProcState = app.setProcState;
16303                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16304                        isSleeping(), now);
16305                mPendingPssProcesses.add(app);
16306            }
16307        }
16308        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16309    }
16310
16311    /**
16312     * Ask a given process to GC right now.
16313     */
16314    final void performAppGcLocked(ProcessRecord app) {
16315        try {
16316            app.lastRequestedGc = SystemClock.uptimeMillis();
16317            if (app.thread != null) {
16318                if (app.reportLowMemory) {
16319                    app.reportLowMemory = false;
16320                    app.thread.scheduleLowMemory();
16321                } else {
16322                    app.thread.processInBackground();
16323                }
16324            }
16325        } catch (Exception e) {
16326            // whatever.
16327        }
16328    }
16329
16330    /**
16331     * Returns true if things are idle enough to perform GCs.
16332     */
16333    private final boolean canGcNowLocked() {
16334        boolean processingBroadcasts = false;
16335        for (BroadcastQueue q : mBroadcastQueues) {
16336            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16337                processingBroadcasts = true;
16338            }
16339        }
16340        return !processingBroadcasts
16341                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16342    }
16343
16344    /**
16345     * Perform GCs on all processes that are waiting for it, but only
16346     * if things are idle.
16347     */
16348    final void performAppGcsLocked() {
16349        final int N = mProcessesToGc.size();
16350        if (N <= 0) {
16351            return;
16352        }
16353        if (canGcNowLocked()) {
16354            while (mProcessesToGc.size() > 0) {
16355                ProcessRecord proc = mProcessesToGc.remove(0);
16356                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16357                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16358                            <= SystemClock.uptimeMillis()) {
16359                        // To avoid spamming the system, we will GC processes one
16360                        // at a time, waiting a few seconds between each.
16361                        performAppGcLocked(proc);
16362                        scheduleAppGcsLocked();
16363                        return;
16364                    } else {
16365                        // It hasn't been long enough since we last GCed this
16366                        // process...  put it in the list to wait for its time.
16367                        addProcessToGcListLocked(proc);
16368                        break;
16369                    }
16370                }
16371            }
16372
16373            scheduleAppGcsLocked();
16374        }
16375    }
16376
16377    /**
16378     * If all looks good, perform GCs on all processes waiting for them.
16379     */
16380    final void performAppGcsIfAppropriateLocked() {
16381        if (canGcNowLocked()) {
16382            performAppGcsLocked();
16383            return;
16384        }
16385        // Still not idle, wait some more.
16386        scheduleAppGcsLocked();
16387    }
16388
16389    /**
16390     * Schedule the execution of all pending app GCs.
16391     */
16392    final void scheduleAppGcsLocked() {
16393        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16394
16395        if (mProcessesToGc.size() > 0) {
16396            // Schedule a GC for the time to the next process.
16397            ProcessRecord proc = mProcessesToGc.get(0);
16398            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16399
16400            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16401            long now = SystemClock.uptimeMillis();
16402            if (when < (now+GC_TIMEOUT)) {
16403                when = now + GC_TIMEOUT;
16404            }
16405            mHandler.sendMessageAtTime(msg, when);
16406        }
16407    }
16408
16409    /**
16410     * Add a process to the array of processes waiting to be GCed.  Keeps the
16411     * list in sorted order by the last GC time.  The process can't already be
16412     * on the list.
16413     */
16414    final void addProcessToGcListLocked(ProcessRecord proc) {
16415        boolean added = false;
16416        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16417            if (mProcessesToGc.get(i).lastRequestedGc <
16418                    proc.lastRequestedGc) {
16419                added = true;
16420                mProcessesToGc.add(i+1, proc);
16421                break;
16422            }
16423        }
16424        if (!added) {
16425            mProcessesToGc.add(0, proc);
16426        }
16427    }
16428
16429    /**
16430     * Set up to ask a process to GC itself.  This will either do it
16431     * immediately, or put it on the list of processes to gc the next
16432     * time things are idle.
16433     */
16434    final void scheduleAppGcLocked(ProcessRecord app) {
16435        long now = SystemClock.uptimeMillis();
16436        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16437            return;
16438        }
16439        if (!mProcessesToGc.contains(app)) {
16440            addProcessToGcListLocked(app);
16441            scheduleAppGcsLocked();
16442        }
16443    }
16444
16445    final void checkExcessivePowerUsageLocked(boolean doKills) {
16446        updateCpuStatsNow();
16447
16448        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16449        boolean doWakeKills = doKills;
16450        boolean doCpuKills = doKills;
16451        if (mLastPowerCheckRealtime == 0) {
16452            doWakeKills = false;
16453        }
16454        if (mLastPowerCheckUptime == 0) {
16455            doCpuKills = false;
16456        }
16457        if (stats.isScreenOn()) {
16458            doWakeKills = false;
16459        }
16460        final long curRealtime = SystemClock.elapsedRealtime();
16461        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16462        final long curUptime = SystemClock.uptimeMillis();
16463        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16464        mLastPowerCheckRealtime = curRealtime;
16465        mLastPowerCheckUptime = curUptime;
16466        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16467            doWakeKills = false;
16468        }
16469        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16470            doCpuKills = false;
16471        }
16472        int i = mLruProcesses.size();
16473        while (i > 0) {
16474            i--;
16475            ProcessRecord app = mLruProcesses.get(i);
16476            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16477                long wtime;
16478                synchronized (stats) {
16479                    wtime = stats.getProcessWakeTime(app.info.uid,
16480                            app.pid, curRealtime);
16481                }
16482                long wtimeUsed = wtime - app.lastWakeTime;
16483                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16484                if (DEBUG_POWER) {
16485                    StringBuilder sb = new StringBuilder(128);
16486                    sb.append("Wake for ");
16487                    app.toShortString(sb);
16488                    sb.append(": over ");
16489                    TimeUtils.formatDuration(realtimeSince, sb);
16490                    sb.append(" used ");
16491                    TimeUtils.formatDuration(wtimeUsed, sb);
16492                    sb.append(" (");
16493                    sb.append((wtimeUsed*100)/realtimeSince);
16494                    sb.append("%)");
16495                    Slog.i(TAG, sb.toString());
16496                    sb.setLength(0);
16497                    sb.append("CPU for ");
16498                    app.toShortString(sb);
16499                    sb.append(": over ");
16500                    TimeUtils.formatDuration(uptimeSince, sb);
16501                    sb.append(" used ");
16502                    TimeUtils.formatDuration(cputimeUsed, sb);
16503                    sb.append(" (");
16504                    sb.append((cputimeUsed*100)/uptimeSince);
16505                    sb.append("%)");
16506                    Slog.i(TAG, sb.toString());
16507                }
16508                // If a process has held a wake lock for more
16509                // than 50% of the time during this period,
16510                // that sounds bad.  Kill!
16511                if (doWakeKills && realtimeSince > 0
16512                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16513                    synchronized (stats) {
16514                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16515                                realtimeSince, wtimeUsed);
16516                    }
16517                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16518                            + " during " + realtimeSince);
16519                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16520                } else if (doCpuKills && uptimeSince > 0
16521                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16522                    synchronized (stats) {
16523                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16524                                uptimeSince, cputimeUsed);
16525                    }
16526                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16527                            + " during " + uptimeSince);
16528                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16529                } else {
16530                    app.lastWakeTime = wtime;
16531                    app.lastCpuTime = app.curCpuTime;
16532                }
16533            }
16534        }
16535    }
16536
16537    private final boolean applyOomAdjLocked(ProcessRecord app,
16538            ProcessRecord TOP_APP, boolean doingAll, long now) {
16539        boolean success = true;
16540
16541        if (app.curRawAdj != app.setRawAdj) {
16542            app.setRawAdj = app.curRawAdj;
16543        }
16544
16545        int changes = 0;
16546
16547        if (app.curAdj != app.setAdj) {
16548            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16549            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16550                TAG, "Set " + app.pid + " " + app.processName +
16551                " adj " + app.curAdj + ": " + app.adjType);
16552            app.setAdj = app.curAdj;
16553        }
16554
16555        if (app.setSchedGroup != app.curSchedGroup) {
16556            app.setSchedGroup = app.curSchedGroup;
16557            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16558                    "Setting process group of " + app.processName
16559                    + " to " + app.curSchedGroup);
16560            if (app.waitingToKill != null &&
16561                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16562                killUnneededProcessLocked(app, app.waitingToKill);
16563                success = false;
16564            } else {
16565                if (true) {
16566                    long oldId = Binder.clearCallingIdentity();
16567                    try {
16568                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16569                    } catch (Exception e) {
16570                        Slog.w(TAG, "Failed setting process group of " + app.pid
16571                                + " to " + app.curSchedGroup);
16572                        e.printStackTrace();
16573                    } finally {
16574                        Binder.restoreCallingIdentity(oldId);
16575                    }
16576                } else {
16577                    if (app.thread != null) {
16578                        try {
16579                            app.thread.setSchedulingGroup(app.curSchedGroup);
16580                        } catch (RemoteException e) {
16581                        }
16582                    }
16583                }
16584                Process.setSwappiness(app.pid,
16585                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16586            }
16587        }
16588        if (app.repForegroundActivities != app.foregroundActivities) {
16589            app.repForegroundActivities = app.foregroundActivities;
16590            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16591        }
16592        if (app.repProcState != app.curProcState) {
16593            app.repProcState = app.curProcState;
16594            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16595            if (app.thread != null) {
16596                try {
16597                    if (false) {
16598                        //RuntimeException h = new RuntimeException("here");
16599                        Slog.i(TAG, "Sending new process state " + app.repProcState
16600                                + " to " + app /*, h*/);
16601                    }
16602                    app.thread.setProcessState(app.repProcState);
16603                } catch (RemoteException e) {
16604                }
16605            }
16606        }
16607        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16608                app.setProcState)) {
16609            app.lastStateTime = now;
16610            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16611                    isSleeping(), now);
16612            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16613                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16614                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16615                    + (app.nextPssTime-now) + ": " + app);
16616        } else {
16617            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16618                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16619                requestPssLocked(app, app.setProcState);
16620                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16621                        isSleeping(), now);
16622            } else if (false && DEBUG_PSS) {
16623                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16624            }
16625        }
16626        if (app.setProcState != app.curProcState) {
16627            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16628                    "Proc state change of " + app.processName
16629                    + " to " + app.curProcState);
16630            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16631            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16632            if (setImportant && !curImportant) {
16633                // This app is no longer something we consider important enough to allow to
16634                // use arbitrary amounts of battery power.  Note
16635                // its current wake lock time to later know to kill it if
16636                // it is not behaving well.
16637                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16638                synchronized (stats) {
16639                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16640                            app.pid, SystemClock.elapsedRealtime());
16641                }
16642                app.lastCpuTime = app.curCpuTime;
16643
16644            }
16645            app.setProcState = app.curProcState;
16646            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16647                app.notCachedSinceIdle = false;
16648            }
16649            if (!doingAll) {
16650                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16651            } else {
16652                app.procStateChanged = true;
16653            }
16654        }
16655
16656        if (changes != 0) {
16657            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16658            int i = mPendingProcessChanges.size()-1;
16659            ProcessChangeItem item = null;
16660            while (i >= 0) {
16661                item = mPendingProcessChanges.get(i);
16662                if (item.pid == app.pid) {
16663                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16664                    break;
16665                }
16666                i--;
16667            }
16668            if (i < 0) {
16669                // No existing item in pending changes; need a new one.
16670                final int NA = mAvailProcessChanges.size();
16671                if (NA > 0) {
16672                    item = mAvailProcessChanges.remove(NA-1);
16673                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16674                } else {
16675                    item = new ProcessChangeItem();
16676                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16677                }
16678                item.changes = 0;
16679                item.pid = app.pid;
16680                item.uid = app.info.uid;
16681                if (mPendingProcessChanges.size() == 0) {
16682                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16683                            "*** Enqueueing dispatch processes changed!");
16684                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16685                }
16686                mPendingProcessChanges.add(item);
16687            }
16688            item.changes |= changes;
16689            item.processState = app.repProcState;
16690            item.foregroundActivities = app.repForegroundActivities;
16691            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16692                    + Integer.toHexString(System.identityHashCode(item))
16693                    + " " + app.toShortString() + ": changes=" + item.changes
16694                    + " procState=" + item.processState
16695                    + " foreground=" + item.foregroundActivities
16696                    + " type=" + app.adjType + " source=" + app.adjSource
16697                    + " target=" + app.adjTarget);
16698        }
16699
16700        return success;
16701    }
16702
16703    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16704        if (proc.thread != null) {
16705            if (proc.baseProcessTracker != null) {
16706                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16707            }
16708            if (proc.repProcState >= 0) {
16709                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16710                        proc.repProcState);
16711            }
16712        }
16713    }
16714
16715    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16716            ProcessRecord TOP_APP, boolean doingAll, long now) {
16717        if (app.thread == null) {
16718            return false;
16719        }
16720
16721        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16722
16723        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16724    }
16725
16726    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16727            boolean oomAdj) {
16728        if (isForeground != proc.foregroundServices) {
16729            proc.foregroundServices = isForeground;
16730            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16731                    proc.info.uid);
16732            if (isForeground) {
16733                if (curProcs == null) {
16734                    curProcs = new ArrayList<ProcessRecord>();
16735                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16736                }
16737                if (!curProcs.contains(proc)) {
16738                    curProcs.add(proc);
16739                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16740                            proc.info.packageName, proc.info.uid);
16741                }
16742            } else {
16743                if (curProcs != null) {
16744                    if (curProcs.remove(proc)) {
16745                        mBatteryStatsService.noteEvent(
16746                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16747                                proc.info.packageName, proc.info.uid);
16748                        if (curProcs.size() <= 0) {
16749                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16750                        }
16751                    }
16752                }
16753            }
16754            if (oomAdj) {
16755                updateOomAdjLocked();
16756            }
16757        }
16758    }
16759
16760    private final ActivityRecord resumedAppLocked() {
16761        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16762        String pkg;
16763        int uid;
16764        if (act != null) {
16765            pkg = act.packageName;
16766            uid = act.info.applicationInfo.uid;
16767        } else {
16768            pkg = null;
16769            uid = -1;
16770        }
16771        // Has the UID or resumed package name changed?
16772        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16773                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16774            if (mCurResumedPackage != null) {
16775                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16776                        mCurResumedPackage, mCurResumedUid);
16777            }
16778            mCurResumedPackage = pkg;
16779            mCurResumedUid = uid;
16780            if (mCurResumedPackage != null) {
16781                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16782                        mCurResumedPackage, mCurResumedUid);
16783            }
16784        }
16785        return act;
16786    }
16787
16788    final boolean updateOomAdjLocked(ProcessRecord app) {
16789        final ActivityRecord TOP_ACT = resumedAppLocked();
16790        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16791        final boolean wasCached = app.cached;
16792
16793        mAdjSeq++;
16794
16795        // This is the desired cached adjusment we want to tell it to use.
16796        // If our app is currently cached, we know it, and that is it.  Otherwise,
16797        // we don't know it yet, and it needs to now be cached we will then
16798        // need to do a complete oom adj.
16799        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16800                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16801        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16802                SystemClock.uptimeMillis());
16803        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16804            // Changed to/from cached state, so apps after it in the LRU
16805            // list may also be changed.
16806            updateOomAdjLocked();
16807        }
16808        return success;
16809    }
16810
16811    final void updateOomAdjLocked() {
16812        final ActivityRecord TOP_ACT = resumedAppLocked();
16813        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16814        final long now = SystemClock.uptimeMillis();
16815        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16816        final int N = mLruProcesses.size();
16817
16818        if (false) {
16819            RuntimeException e = new RuntimeException();
16820            e.fillInStackTrace();
16821            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16822        }
16823
16824        mAdjSeq++;
16825        mNewNumServiceProcs = 0;
16826        mNewNumAServiceProcs = 0;
16827
16828        final int emptyProcessLimit;
16829        final int cachedProcessLimit;
16830        if (mProcessLimit <= 0) {
16831            emptyProcessLimit = cachedProcessLimit = 0;
16832        } else if (mProcessLimit == 1) {
16833            emptyProcessLimit = 1;
16834            cachedProcessLimit = 0;
16835        } else {
16836            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16837            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16838        }
16839
16840        // Let's determine how many processes we have running vs.
16841        // how many slots we have for background processes; we may want
16842        // to put multiple processes in a slot of there are enough of
16843        // them.
16844        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16845                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16846        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16847        if (numEmptyProcs > cachedProcessLimit) {
16848            // If there are more empty processes than our limit on cached
16849            // processes, then use the cached process limit for the factor.
16850            // This ensures that the really old empty processes get pushed
16851            // down to the bottom, so if we are running low on memory we will
16852            // have a better chance at keeping around more cached processes
16853            // instead of a gazillion empty processes.
16854            numEmptyProcs = cachedProcessLimit;
16855        }
16856        int emptyFactor = numEmptyProcs/numSlots;
16857        if (emptyFactor < 1) emptyFactor = 1;
16858        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16859        if (cachedFactor < 1) cachedFactor = 1;
16860        int stepCached = 0;
16861        int stepEmpty = 0;
16862        int numCached = 0;
16863        int numEmpty = 0;
16864        int numTrimming = 0;
16865
16866        mNumNonCachedProcs = 0;
16867        mNumCachedHiddenProcs = 0;
16868
16869        // First update the OOM adjustment for each of the
16870        // application processes based on their current state.
16871        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16872        int nextCachedAdj = curCachedAdj+1;
16873        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16874        int nextEmptyAdj = curEmptyAdj+2;
16875        for (int i=N-1; i>=0; i--) {
16876            ProcessRecord app = mLruProcesses.get(i);
16877            if (!app.killedByAm && app.thread != null) {
16878                app.procStateChanged = false;
16879                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16880
16881                // If we haven't yet assigned the final cached adj
16882                // to the process, do that now.
16883                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16884                    switch (app.curProcState) {
16885                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16886                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16887                            // This process is a cached process holding activities...
16888                            // assign it the next cached value for that type, and then
16889                            // step that cached level.
16890                            app.curRawAdj = curCachedAdj;
16891                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16892                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16893                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16894                                    + ")");
16895                            if (curCachedAdj != nextCachedAdj) {
16896                                stepCached++;
16897                                if (stepCached >= cachedFactor) {
16898                                    stepCached = 0;
16899                                    curCachedAdj = nextCachedAdj;
16900                                    nextCachedAdj += 2;
16901                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16902                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16903                                    }
16904                                }
16905                            }
16906                            break;
16907                        default:
16908                            // For everything else, assign next empty cached process
16909                            // level and bump that up.  Note that this means that
16910                            // long-running services that have dropped down to the
16911                            // cached level will be treated as empty (since their process
16912                            // state is still as a service), which is what we want.
16913                            app.curRawAdj = curEmptyAdj;
16914                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16915                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16916                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16917                                    + ")");
16918                            if (curEmptyAdj != nextEmptyAdj) {
16919                                stepEmpty++;
16920                                if (stepEmpty >= emptyFactor) {
16921                                    stepEmpty = 0;
16922                                    curEmptyAdj = nextEmptyAdj;
16923                                    nextEmptyAdj += 2;
16924                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16925                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16926                                    }
16927                                }
16928                            }
16929                            break;
16930                    }
16931                }
16932
16933                applyOomAdjLocked(app, TOP_APP, true, now);
16934
16935                // Count the number of process types.
16936                switch (app.curProcState) {
16937                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16938                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16939                        mNumCachedHiddenProcs++;
16940                        numCached++;
16941                        if (numCached > cachedProcessLimit) {
16942                            killUnneededProcessLocked(app, "cached #" + numCached);
16943                        }
16944                        break;
16945                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16946                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16947                                && app.lastActivityTime < oldTime) {
16948                            killUnneededProcessLocked(app, "empty for "
16949                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16950                                    / 1000) + "s");
16951                        } else {
16952                            numEmpty++;
16953                            if (numEmpty > emptyProcessLimit) {
16954                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16955                            }
16956                        }
16957                        break;
16958                    default:
16959                        mNumNonCachedProcs++;
16960                        break;
16961                }
16962
16963                if (app.isolated && app.services.size() <= 0) {
16964                    // If this is an isolated process, and there are no
16965                    // services running in it, then the process is no longer
16966                    // needed.  We agressively kill these because we can by
16967                    // definition not re-use the same process again, and it is
16968                    // good to avoid having whatever code was running in them
16969                    // left sitting around after no longer needed.
16970                    killUnneededProcessLocked(app, "isolated not needed");
16971                }
16972
16973                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16974                        && !app.killedByAm) {
16975                    numTrimming++;
16976                }
16977            }
16978        }
16979
16980        mNumServiceProcs = mNewNumServiceProcs;
16981
16982        // Now determine the memory trimming level of background processes.
16983        // Unfortunately we need to start at the back of the list to do this
16984        // properly.  We only do this if the number of background apps we
16985        // are managing to keep around is less than half the maximum we desire;
16986        // if we are keeping a good number around, we'll let them use whatever
16987        // memory they want.
16988        final int numCachedAndEmpty = numCached + numEmpty;
16989        int memFactor;
16990        if (numCached <= ProcessList.TRIM_CACHED_APPS
16991                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16992            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16993                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16994            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16995                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16996            } else {
16997                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16998            }
16999        } else {
17000            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17001        }
17002        // We always allow the memory level to go up (better).  We only allow it to go
17003        // down if we are in a state where that is allowed, *and* the total number of processes
17004        // has gone down since last time.
17005        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17006                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17007                + " last=" + mLastNumProcesses);
17008        if (memFactor > mLastMemoryLevel) {
17009            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17010                memFactor = mLastMemoryLevel;
17011                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17012            }
17013        }
17014        mLastMemoryLevel = memFactor;
17015        mLastNumProcesses = mLruProcesses.size();
17016        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17017        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17018        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17019            if (mLowRamStartTime == 0) {
17020                mLowRamStartTime = now;
17021            }
17022            int step = 0;
17023            int fgTrimLevel;
17024            switch (memFactor) {
17025                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17026                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17027                    break;
17028                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17029                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17030                    break;
17031                default:
17032                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17033                    break;
17034            }
17035            int factor = numTrimming/3;
17036            int minFactor = 2;
17037            if (mHomeProcess != null) minFactor++;
17038            if (mPreviousProcess != null) minFactor++;
17039            if (factor < minFactor) factor = minFactor;
17040            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17041            for (int i=N-1; i>=0; i--) {
17042                ProcessRecord app = mLruProcesses.get(i);
17043                if (allChanged || app.procStateChanged) {
17044                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17045                    app.procStateChanged = false;
17046                }
17047                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17048                        && !app.killedByAm) {
17049                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17050                        try {
17051                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17052                                    "Trimming memory of " + app.processName
17053                                    + " to " + curLevel);
17054                            app.thread.scheduleTrimMemory(curLevel);
17055                        } catch (RemoteException e) {
17056                        }
17057                        if (false) {
17058                            // For now we won't do this; our memory trimming seems
17059                            // to be good enough at this point that destroying
17060                            // activities causes more harm than good.
17061                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17062                                    && app != mHomeProcess && app != mPreviousProcess) {
17063                                // Need to do this on its own message because the stack may not
17064                                // be in a consistent state at this point.
17065                                // For these apps we will also finish their activities
17066                                // to help them free memory.
17067                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17068                            }
17069                        }
17070                    }
17071                    app.trimMemoryLevel = curLevel;
17072                    step++;
17073                    if (step >= factor) {
17074                        step = 0;
17075                        switch (curLevel) {
17076                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17077                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17078                                break;
17079                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17080                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17081                                break;
17082                        }
17083                    }
17084                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17085                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17086                            && app.thread != null) {
17087                        try {
17088                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17089                                    "Trimming memory of heavy-weight " + app.processName
17090                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17091                            app.thread.scheduleTrimMemory(
17092                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17093                        } catch (RemoteException e) {
17094                        }
17095                    }
17096                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17097                } else {
17098                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17099                            || app.systemNoUi) && app.pendingUiClean) {
17100                        // If this application is now in the background and it
17101                        // had done UI, then give it the special trim level to
17102                        // have it free UI resources.
17103                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17104                        if (app.trimMemoryLevel < level && app.thread != null) {
17105                            try {
17106                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17107                                        "Trimming memory of bg-ui " + app.processName
17108                                        + " to " + level);
17109                                app.thread.scheduleTrimMemory(level);
17110                            } catch (RemoteException e) {
17111                            }
17112                        }
17113                        app.pendingUiClean = false;
17114                    }
17115                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17116                        try {
17117                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17118                                    "Trimming memory of fg " + app.processName
17119                                    + " to " + fgTrimLevel);
17120                            app.thread.scheduleTrimMemory(fgTrimLevel);
17121                        } catch (RemoteException e) {
17122                        }
17123                    }
17124                    app.trimMemoryLevel = fgTrimLevel;
17125                }
17126            }
17127        } else {
17128            if (mLowRamStartTime != 0) {
17129                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17130                mLowRamStartTime = 0;
17131            }
17132            for (int i=N-1; i>=0; i--) {
17133                ProcessRecord app = mLruProcesses.get(i);
17134                if (allChanged || app.procStateChanged) {
17135                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17136                    app.procStateChanged = false;
17137                }
17138                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17139                        || app.systemNoUi) && app.pendingUiClean) {
17140                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17141                            && app.thread != null) {
17142                        try {
17143                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17144                                    "Trimming memory of ui hidden " + app.processName
17145                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17146                            app.thread.scheduleTrimMemory(
17147                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17148                        } catch (RemoteException e) {
17149                        }
17150                    }
17151                    app.pendingUiClean = false;
17152                }
17153                app.trimMemoryLevel = 0;
17154            }
17155        }
17156
17157        if (mAlwaysFinishActivities) {
17158            // Need to do this on its own message because the stack may not
17159            // be in a consistent state at this point.
17160            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17161        }
17162
17163        if (allChanged) {
17164            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17165        }
17166
17167        if (mProcessStats.shouldWriteNowLocked(now)) {
17168            mHandler.post(new Runnable() {
17169                @Override public void run() {
17170                    synchronized (ActivityManagerService.this) {
17171                        mProcessStats.writeStateAsyncLocked();
17172                    }
17173                }
17174            });
17175        }
17176
17177        if (DEBUG_OOM_ADJ) {
17178            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17179        }
17180    }
17181
17182    final void trimApplications() {
17183        synchronized (this) {
17184            int i;
17185
17186            // First remove any unused application processes whose package
17187            // has been removed.
17188            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17189                final ProcessRecord app = mRemovedProcesses.get(i);
17190                if (app.activities.size() == 0
17191                        && app.curReceiver == null && app.services.size() == 0) {
17192                    Slog.i(
17193                        TAG, "Exiting empty application process "
17194                        + app.processName + " ("
17195                        + (app.thread != null ? app.thread.asBinder() : null)
17196                        + ")\n");
17197                    if (app.pid > 0 && app.pid != MY_PID) {
17198                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
17199                                app.processName, app.setAdj, "empty");
17200                        app.killedByAm = true;
17201                        Process.killProcessQuiet(app.pid);
17202                        Process.killProcessGroup(app.info.uid, app.pid);
17203                    } else {
17204                        try {
17205                            app.thread.scheduleExit();
17206                        } catch (Exception e) {
17207                            // Ignore exceptions.
17208                        }
17209                    }
17210                    cleanUpApplicationRecordLocked(app, false, true, -1);
17211                    mRemovedProcesses.remove(i);
17212
17213                    if (app.persistent) {
17214                        addAppLocked(app.info, false, null /* ABI override */);
17215                    }
17216                }
17217            }
17218
17219            // Now update the oom adj for all processes.
17220            updateOomAdjLocked();
17221        }
17222    }
17223
17224    /** This method sends the specified signal to each of the persistent apps */
17225    public void signalPersistentProcesses(int sig) throws RemoteException {
17226        if (sig != Process.SIGNAL_USR1) {
17227            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17228        }
17229
17230        synchronized (this) {
17231            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17232                    != PackageManager.PERMISSION_GRANTED) {
17233                throw new SecurityException("Requires permission "
17234                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17235            }
17236
17237            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17238                ProcessRecord r = mLruProcesses.get(i);
17239                if (r.thread != null && r.persistent) {
17240                    Process.sendSignal(r.pid, sig);
17241                }
17242            }
17243        }
17244    }
17245
17246    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17247        if (proc == null || proc == mProfileProc) {
17248            proc = mProfileProc;
17249            path = mProfileFile;
17250            profileType = mProfileType;
17251            clearProfilerLocked();
17252        }
17253        if (proc == null) {
17254            return;
17255        }
17256        try {
17257            proc.thread.profilerControl(false, path, null, profileType);
17258        } catch (RemoteException e) {
17259            throw new IllegalStateException("Process disappeared");
17260        }
17261    }
17262
17263    private void clearProfilerLocked() {
17264        if (mProfileFd != null) {
17265            try {
17266                mProfileFd.close();
17267            } catch (IOException e) {
17268            }
17269        }
17270        mProfileApp = null;
17271        mProfileProc = null;
17272        mProfileFile = null;
17273        mProfileType = 0;
17274        mAutoStopProfiler = false;
17275    }
17276
17277    public boolean profileControl(String process, int userId, boolean start,
17278            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17279
17280        try {
17281            synchronized (this) {
17282                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17283                // its own permission.
17284                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17285                        != PackageManager.PERMISSION_GRANTED) {
17286                    throw new SecurityException("Requires permission "
17287                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17288                }
17289
17290                if (start && fd == null) {
17291                    throw new IllegalArgumentException("null fd");
17292                }
17293
17294                ProcessRecord proc = null;
17295                if (process != null) {
17296                    proc = findProcessLocked(process, userId, "profileControl");
17297                }
17298
17299                if (start && (proc == null || proc.thread == null)) {
17300                    throw new IllegalArgumentException("Unknown process: " + process);
17301                }
17302
17303                if (start) {
17304                    stopProfilerLocked(null, null, 0);
17305                    setProfileApp(proc.info, proc.processName, path, fd, false);
17306                    mProfileProc = proc;
17307                    mProfileType = profileType;
17308                    try {
17309                        fd = fd.dup();
17310                    } catch (IOException e) {
17311                        fd = null;
17312                    }
17313                    proc.thread.profilerControl(start, path, fd, profileType);
17314                    fd = null;
17315                    mProfileFd = null;
17316                } else {
17317                    stopProfilerLocked(proc, path, profileType);
17318                    if (fd != null) {
17319                        try {
17320                            fd.close();
17321                        } catch (IOException e) {
17322                        }
17323                    }
17324                }
17325
17326                return true;
17327            }
17328        } catch (RemoteException e) {
17329            throw new IllegalStateException("Process disappeared");
17330        } finally {
17331            if (fd != null) {
17332                try {
17333                    fd.close();
17334                } catch (IOException e) {
17335                }
17336            }
17337        }
17338    }
17339
17340    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17341        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17342                userId, true, ALLOW_FULL_ONLY, callName, null);
17343        ProcessRecord proc = null;
17344        try {
17345            int pid = Integer.parseInt(process);
17346            synchronized (mPidsSelfLocked) {
17347                proc = mPidsSelfLocked.get(pid);
17348            }
17349        } catch (NumberFormatException e) {
17350        }
17351
17352        if (proc == null) {
17353            ArrayMap<String, SparseArray<ProcessRecord>> all
17354                    = mProcessNames.getMap();
17355            SparseArray<ProcessRecord> procs = all.get(process);
17356            if (procs != null && procs.size() > 0) {
17357                proc = procs.valueAt(0);
17358                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17359                    for (int i=1; i<procs.size(); i++) {
17360                        ProcessRecord thisProc = procs.valueAt(i);
17361                        if (thisProc.userId == userId) {
17362                            proc = thisProc;
17363                            break;
17364                        }
17365                    }
17366                }
17367            }
17368        }
17369
17370        return proc;
17371    }
17372
17373    public boolean dumpHeap(String process, int userId, boolean managed,
17374            String path, ParcelFileDescriptor fd) throws RemoteException {
17375
17376        try {
17377            synchronized (this) {
17378                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17379                // its own permission (same as profileControl).
17380                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17381                        != PackageManager.PERMISSION_GRANTED) {
17382                    throw new SecurityException("Requires permission "
17383                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17384                }
17385
17386                if (fd == null) {
17387                    throw new IllegalArgumentException("null fd");
17388                }
17389
17390                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17391                if (proc == null || proc.thread == null) {
17392                    throw new IllegalArgumentException("Unknown process: " + process);
17393                }
17394
17395                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17396                if (!isDebuggable) {
17397                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17398                        throw new SecurityException("Process not debuggable: " + proc);
17399                    }
17400                }
17401
17402                proc.thread.dumpHeap(managed, path, fd);
17403                fd = null;
17404                return true;
17405            }
17406        } catch (RemoteException e) {
17407            throw new IllegalStateException("Process disappeared");
17408        } finally {
17409            if (fd != null) {
17410                try {
17411                    fd.close();
17412                } catch (IOException e) {
17413                }
17414            }
17415        }
17416    }
17417
17418    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17419    public void monitor() {
17420        synchronized (this) { }
17421    }
17422
17423    void onCoreSettingsChange(Bundle settings) {
17424        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17425            ProcessRecord processRecord = mLruProcesses.get(i);
17426            try {
17427                if (processRecord.thread != null) {
17428                    processRecord.thread.setCoreSettings(settings);
17429                }
17430            } catch (RemoteException re) {
17431                /* ignore */
17432            }
17433        }
17434    }
17435
17436    // Multi-user methods
17437
17438    /**
17439     * Start user, if its not already running, but don't bring it to foreground.
17440     */
17441    @Override
17442    public boolean startUserInBackground(final int userId) {
17443        return startUser(userId, /* foreground */ false);
17444    }
17445
17446    /**
17447     * Start user, if its not already running, and bring it to foreground.
17448     */
17449    boolean startUserInForeground(final int userId, Dialog dlg) {
17450        boolean result = startUser(userId, /* foreground */ true);
17451        dlg.dismiss();
17452        return result;
17453    }
17454
17455    /**
17456     * Refreshes the list of users related to the current user when either a
17457     * user switch happens or when a new related user is started in the
17458     * background.
17459     */
17460    private void updateCurrentProfileIdsLocked() {
17461        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17462                mCurrentUserId, false /* enabledOnly */);
17463        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17464        for (int i = 0; i < currentProfileIds.length; i++) {
17465            currentProfileIds[i] = profiles.get(i).id;
17466        }
17467        mCurrentProfileIds = currentProfileIds;
17468
17469        synchronized (mUserProfileGroupIdsSelfLocked) {
17470            mUserProfileGroupIdsSelfLocked.clear();
17471            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17472            for (int i = 0; i < users.size(); i++) {
17473                UserInfo user = users.get(i);
17474                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17475                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17476                }
17477            }
17478        }
17479    }
17480
17481    private Set getProfileIdsLocked(int userId) {
17482        Set userIds = new HashSet<Integer>();
17483        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17484                userId, false /* enabledOnly */);
17485        for (UserInfo user : profiles) {
17486            userIds.add(Integer.valueOf(user.id));
17487        }
17488        return userIds;
17489    }
17490
17491    @Override
17492    public boolean switchUser(final int userId) {
17493        String userName;
17494        synchronized (this) {
17495            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17496            if (userInfo == null) {
17497                Slog.w(TAG, "No user info for user #" + userId);
17498                return false;
17499            }
17500            if (userInfo.isManagedProfile()) {
17501                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17502                return false;
17503            }
17504            userName = userInfo.name;
17505        }
17506        mHandler.removeMessages(START_USER_SWITCH_MSG);
17507        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17508        return true;
17509    }
17510
17511    private void showUserSwitchDialog(int userId, String userName) {
17512        // The dialog will show and then initiate the user switch by calling startUserInForeground
17513        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17514                true /* above system */);
17515        d.show();
17516    }
17517
17518    private boolean startUser(final int userId, boolean foreground) {
17519        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17520                != PackageManager.PERMISSION_GRANTED) {
17521            String msg = "Permission Denial: switchUser() from pid="
17522                    + Binder.getCallingPid()
17523                    + ", uid=" + Binder.getCallingUid()
17524                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17525            Slog.w(TAG, msg);
17526            throw new SecurityException(msg);
17527        }
17528
17529        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17530
17531        final long ident = Binder.clearCallingIdentity();
17532        try {
17533            synchronized (this) {
17534                final int oldUserId = mCurrentUserId;
17535                if (oldUserId == userId) {
17536                    return true;
17537                }
17538
17539                mStackSupervisor.setLockTaskModeLocked(null, false);
17540
17541                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17542                if (userInfo == null) {
17543                    Slog.w(TAG, "No user info for user #" + userId);
17544                    return false;
17545                }
17546                if (foreground && userInfo.isManagedProfile()) {
17547                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17548                    return false;
17549                }
17550
17551                if (foreground) {
17552                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17553                            R.anim.screen_user_enter);
17554                }
17555
17556                boolean needStart = false;
17557
17558                // If the user we are switching to is not currently started, then
17559                // we need to start it now.
17560                if (mStartedUsers.get(userId) == null) {
17561                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17562                    updateStartedUserArrayLocked();
17563                    needStart = true;
17564                }
17565
17566                final Integer userIdInt = Integer.valueOf(userId);
17567                mUserLru.remove(userIdInt);
17568                mUserLru.add(userIdInt);
17569
17570                if (foreground) {
17571                    mCurrentUserId = userId;
17572                    updateCurrentProfileIdsLocked();
17573                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17574                    // Once the internal notion of the active user has switched, we lock the device
17575                    // with the option to show the user switcher on the keyguard.
17576                    mWindowManager.lockNow(null);
17577                } else {
17578                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17579                    updateCurrentProfileIdsLocked();
17580                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17581                    mUserLru.remove(currentUserIdInt);
17582                    mUserLru.add(currentUserIdInt);
17583                }
17584
17585                final UserStartedState uss = mStartedUsers.get(userId);
17586
17587                // Make sure user is in the started state.  If it is currently
17588                // stopping, we need to knock that off.
17589                if (uss.mState == UserStartedState.STATE_STOPPING) {
17590                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17591                    // so we can just fairly silently bring the user back from
17592                    // the almost-dead.
17593                    uss.mState = UserStartedState.STATE_RUNNING;
17594                    updateStartedUserArrayLocked();
17595                    needStart = true;
17596                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17597                    // This means ACTION_SHUTDOWN has been sent, so we will
17598                    // need to treat this as a new boot of the user.
17599                    uss.mState = UserStartedState.STATE_BOOTING;
17600                    updateStartedUserArrayLocked();
17601                    needStart = true;
17602                }
17603
17604                if (uss.mState == UserStartedState.STATE_BOOTING) {
17605                    // Booting up a new user, need to tell system services about it.
17606                    // Note that this is on the same handler as scheduling of broadcasts,
17607                    // which is important because it needs to go first.
17608                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17609                }
17610
17611                if (foreground) {
17612                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17613                            oldUserId));
17614                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17615                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17616                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17617                            oldUserId, userId, uss));
17618                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17619                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17620                }
17621
17622                if (needStart) {
17623                    // Send USER_STARTED broadcast
17624                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17625                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17626                            | Intent.FLAG_RECEIVER_FOREGROUND);
17627                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17628                    broadcastIntentLocked(null, null, intent,
17629                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17630                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17631                }
17632
17633                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17634                    if (userId != UserHandle.USER_OWNER) {
17635                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17636                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17637                        broadcastIntentLocked(null, null, intent, null,
17638                                new IIntentReceiver.Stub() {
17639                                    public void performReceive(Intent intent, int resultCode,
17640                                            String data, Bundle extras, boolean ordered,
17641                                            boolean sticky, int sendingUser) {
17642                                        userInitialized(uss, userId);
17643                                    }
17644                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17645                                true, false, MY_PID, Process.SYSTEM_UID,
17646                                userId);
17647                        uss.initializing = true;
17648                    } else {
17649                        getUserManagerLocked().makeInitialized(userInfo.id);
17650                    }
17651                }
17652
17653                if (foreground) {
17654                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17655                    if (homeInFront) {
17656                        startHomeActivityLocked(userId);
17657                    } else {
17658                        mStackSupervisor.resumeTopActivitiesLocked();
17659                    }
17660                    EventLogTags.writeAmSwitchUser(userId);
17661                    getUserManagerLocked().userForeground(userId);
17662                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17663                } else {
17664                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17665                }
17666
17667                if (needStart) {
17668                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17669                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17670                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17671                    broadcastIntentLocked(null, null, intent,
17672                            null, new IIntentReceiver.Stub() {
17673                                @Override
17674                                public void performReceive(Intent intent, int resultCode, String data,
17675                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17676                                        throws RemoteException {
17677                                }
17678                            }, 0, null, null,
17679                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17680                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17681                }
17682            }
17683        } finally {
17684            Binder.restoreCallingIdentity(ident);
17685        }
17686
17687        return true;
17688    }
17689
17690    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17691        long ident = Binder.clearCallingIdentity();
17692        try {
17693            Intent intent;
17694            if (oldUserId >= 0) {
17695                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17696                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17697                int count = profiles.size();
17698                for (int i = 0; i < count; i++) {
17699                    int profileUserId = profiles.get(i).id;
17700                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17701                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17702                            | Intent.FLAG_RECEIVER_FOREGROUND);
17703                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17704                    broadcastIntentLocked(null, null, intent,
17705                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17706                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17707                }
17708            }
17709            if (newUserId >= 0) {
17710                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17711                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17712                int count = profiles.size();
17713                for (int i = 0; i < count; i++) {
17714                    int profileUserId = profiles.get(i).id;
17715                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17716                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17717                            | Intent.FLAG_RECEIVER_FOREGROUND);
17718                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17719                    broadcastIntentLocked(null, null, intent,
17720                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17721                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17722                }
17723                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17724                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17725                        | Intent.FLAG_RECEIVER_FOREGROUND);
17726                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17727                broadcastIntentLocked(null, null, intent,
17728                        null, null, 0, null, null,
17729                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17730                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17731            }
17732        } finally {
17733            Binder.restoreCallingIdentity(ident);
17734        }
17735    }
17736
17737    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17738            final int newUserId) {
17739        final int N = mUserSwitchObservers.beginBroadcast();
17740        if (N > 0) {
17741            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17742                int mCount = 0;
17743                @Override
17744                public void sendResult(Bundle data) throws RemoteException {
17745                    synchronized (ActivityManagerService.this) {
17746                        if (mCurUserSwitchCallback == this) {
17747                            mCount++;
17748                            if (mCount == N) {
17749                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17750                            }
17751                        }
17752                    }
17753                }
17754            };
17755            synchronized (this) {
17756                uss.switching = true;
17757                mCurUserSwitchCallback = callback;
17758            }
17759            for (int i=0; i<N; i++) {
17760                try {
17761                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17762                            newUserId, callback);
17763                } catch (RemoteException e) {
17764                }
17765            }
17766        } else {
17767            synchronized (this) {
17768                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17769            }
17770        }
17771        mUserSwitchObservers.finishBroadcast();
17772    }
17773
17774    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17775        synchronized (this) {
17776            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17777            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17778        }
17779    }
17780
17781    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17782        mCurUserSwitchCallback = null;
17783        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17784        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17785                oldUserId, newUserId, uss));
17786    }
17787
17788    void userInitialized(UserStartedState uss, int newUserId) {
17789        completeSwitchAndInitalize(uss, newUserId, true, false);
17790    }
17791
17792    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17793        completeSwitchAndInitalize(uss, newUserId, false, true);
17794    }
17795
17796    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17797            boolean clearInitializing, boolean clearSwitching) {
17798        boolean unfrozen = false;
17799        synchronized (this) {
17800            if (clearInitializing) {
17801                uss.initializing = false;
17802                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17803            }
17804            if (clearSwitching) {
17805                uss.switching = false;
17806            }
17807            if (!uss.switching && !uss.initializing) {
17808                mWindowManager.stopFreezingScreen();
17809                unfrozen = true;
17810            }
17811        }
17812        if (unfrozen) {
17813            final int N = mUserSwitchObservers.beginBroadcast();
17814            for (int i=0; i<N; i++) {
17815                try {
17816                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17817                } catch (RemoteException e) {
17818                }
17819            }
17820            mUserSwitchObservers.finishBroadcast();
17821        }
17822    }
17823
17824    void scheduleStartProfilesLocked() {
17825        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17826            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17827                    DateUtils.SECOND_IN_MILLIS);
17828        }
17829    }
17830
17831    void startProfilesLocked() {
17832        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17833        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17834                mCurrentUserId, false /* enabledOnly */);
17835        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17836        for (UserInfo user : profiles) {
17837            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17838                    && user.id != mCurrentUserId) {
17839                toStart.add(user);
17840            }
17841        }
17842        final int n = toStart.size();
17843        int i = 0;
17844        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17845            startUserInBackground(toStart.get(i).id);
17846        }
17847        if (i < n) {
17848            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17849        }
17850    }
17851
17852    void finishUserBoot(UserStartedState uss) {
17853        synchronized (this) {
17854            if (uss.mState == UserStartedState.STATE_BOOTING
17855                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17856                uss.mState = UserStartedState.STATE_RUNNING;
17857                final int userId = uss.mHandle.getIdentifier();
17858                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17859                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17860                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17861                broadcastIntentLocked(null, null, intent,
17862                        null, null, 0, null, null,
17863                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17864                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17865            }
17866        }
17867    }
17868
17869    void finishUserSwitch(UserStartedState uss) {
17870        synchronized (this) {
17871            finishUserBoot(uss);
17872
17873            startProfilesLocked();
17874
17875            int num = mUserLru.size();
17876            int i = 0;
17877            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17878                Integer oldUserId = mUserLru.get(i);
17879                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17880                if (oldUss == null) {
17881                    // Shouldn't happen, but be sane if it does.
17882                    mUserLru.remove(i);
17883                    num--;
17884                    continue;
17885                }
17886                if (oldUss.mState == UserStartedState.STATE_STOPPING
17887                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17888                    // This user is already stopping, doesn't count.
17889                    num--;
17890                    i++;
17891                    continue;
17892                }
17893                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17894                    // Owner and current can't be stopped, but count as running.
17895                    i++;
17896                    continue;
17897                }
17898                // This is a user to be stopped.
17899                stopUserLocked(oldUserId, null);
17900                num--;
17901                i++;
17902            }
17903        }
17904    }
17905
17906    @Override
17907    public int stopUser(final int userId, final IStopUserCallback callback) {
17908        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17909                != PackageManager.PERMISSION_GRANTED) {
17910            String msg = "Permission Denial: switchUser() from pid="
17911                    + Binder.getCallingPid()
17912                    + ", uid=" + Binder.getCallingUid()
17913                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17914            Slog.w(TAG, msg);
17915            throw new SecurityException(msg);
17916        }
17917        if (userId <= 0) {
17918            throw new IllegalArgumentException("Can't stop primary user " + userId);
17919        }
17920        synchronized (this) {
17921            return stopUserLocked(userId, callback);
17922        }
17923    }
17924
17925    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17926        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17927        if (mCurrentUserId == userId) {
17928            return ActivityManager.USER_OP_IS_CURRENT;
17929        }
17930
17931        final UserStartedState uss = mStartedUsers.get(userId);
17932        if (uss == null) {
17933            // User is not started, nothing to do...  but we do need to
17934            // callback if requested.
17935            if (callback != null) {
17936                mHandler.post(new Runnable() {
17937                    @Override
17938                    public void run() {
17939                        try {
17940                            callback.userStopped(userId);
17941                        } catch (RemoteException e) {
17942                        }
17943                    }
17944                });
17945            }
17946            return ActivityManager.USER_OP_SUCCESS;
17947        }
17948
17949        if (callback != null) {
17950            uss.mStopCallbacks.add(callback);
17951        }
17952
17953        if (uss.mState != UserStartedState.STATE_STOPPING
17954                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17955            uss.mState = UserStartedState.STATE_STOPPING;
17956            updateStartedUserArrayLocked();
17957
17958            long ident = Binder.clearCallingIdentity();
17959            try {
17960                // We are going to broadcast ACTION_USER_STOPPING and then
17961                // once that is done send a final ACTION_SHUTDOWN and then
17962                // stop the user.
17963                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17964                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17965                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17966                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17967                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17968                // This is the result receiver for the final shutdown broadcast.
17969                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17970                    @Override
17971                    public void performReceive(Intent intent, int resultCode, String data,
17972                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17973                        finishUserStop(uss);
17974                    }
17975                };
17976                // This is the result receiver for the initial stopping broadcast.
17977                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17978                    @Override
17979                    public void performReceive(Intent intent, int resultCode, String data,
17980                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17981                        // On to the next.
17982                        synchronized (ActivityManagerService.this) {
17983                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17984                                // Whoops, we are being started back up.  Abort, abort!
17985                                return;
17986                            }
17987                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17988                        }
17989                        mBatteryStatsService.noteEvent(
17990                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17991                                Integer.toString(userId), userId);
17992                        mSystemServiceManager.stopUser(userId);
17993                        broadcastIntentLocked(null, null, shutdownIntent,
17994                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17995                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17996                    }
17997                };
17998                // Kick things off.
17999                broadcastIntentLocked(null, null, stoppingIntent,
18000                        null, stoppingReceiver, 0, null, null,
18001                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18002                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18003            } finally {
18004                Binder.restoreCallingIdentity(ident);
18005            }
18006        }
18007
18008        return ActivityManager.USER_OP_SUCCESS;
18009    }
18010
18011    void finishUserStop(UserStartedState uss) {
18012        final int userId = uss.mHandle.getIdentifier();
18013        boolean stopped;
18014        ArrayList<IStopUserCallback> callbacks;
18015        synchronized (this) {
18016            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18017            if (mStartedUsers.get(userId) != uss) {
18018                stopped = false;
18019            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18020                stopped = false;
18021            } else {
18022                stopped = true;
18023                // User can no longer run.
18024                mStartedUsers.remove(userId);
18025                mUserLru.remove(Integer.valueOf(userId));
18026                updateStartedUserArrayLocked();
18027
18028                // Clean up all state and processes associated with the user.
18029                // Kill all the processes for the user.
18030                forceStopUserLocked(userId, "finish user");
18031            }
18032
18033            // Explicitly remove the old information in mRecentTasks.
18034            removeRecentTasksForUserLocked(userId);
18035        }
18036
18037        for (int i=0; i<callbacks.size(); i++) {
18038            try {
18039                if (stopped) callbacks.get(i).userStopped(userId);
18040                else callbacks.get(i).userStopAborted(userId);
18041            } catch (RemoteException e) {
18042            }
18043        }
18044
18045        if (stopped) {
18046            mSystemServiceManager.cleanupUser(userId);
18047            synchronized (this) {
18048                mStackSupervisor.removeUserLocked(userId);
18049            }
18050        }
18051    }
18052
18053    @Override
18054    public UserInfo getCurrentUser() {
18055        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18056                != PackageManager.PERMISSION_GRANTED) && (
18057                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18058                != PackageManager.PERMISSION_GRANTED)) {
18059            String msg = "Permission Denial: getCurrentUser() from pid="
18060                    + Binder.getCallingPid()
18061                    + ", uid=" + Binder.getCallingUid()
18062                    + " requires " + INTERACT_ACROSS_USERS;
18063            Slog.w(TAG, msg);
18064            throw new SecurityException(msg);
18065        }
18066        synchronized (this) {
18067            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18068        }
18069    }
18070
18071    int getCurrentUserIdLocked() {
18072        return mCurrentUserId;
18073    }
18074
18075    @Override
18076    public boolean isUserRunning(int userId, boolean orStopped) {
18077        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18078                != PackageManager.PERMISSION_GRANTED) {
18079            String msg = "Permission Denial: isUserRunning() from pid="
18080                    + Binder.getCallingPid()
18081                    + ", uid=" + Binder.getCallingUid()
18082                    + " requires " + INTERACT_ACROSS_USERS;
18083            Slog.w(TAG, msg);
18084            throw new SecurityException(msg);
18085        }
18086        synchronized (this) {
18087            return isUserRunningLocked(userId, orStopped);
18088        }
18089    }
18090
18091    boolean isUserRunningLocked(int userId, boolean orStopped) {
18092        UserStartedState state = mStartedUsers.get(userId);
18093        if (state == null) {
18094            return false;
18095        }
18096        if (orStopped) {
18097            return true;
18098        }
18099        return state.mState != UserStartedState.STATE_STOPPING
18100                && state.mState != UserStartedState.STATE_SHUTDOWN;
18101    }
18102
18103    @Override
18104    public int[] getRunningUserIds() {
18105        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18106                != PackageManager.PERMISSION_GRANTED) {
18107            String msg = "Permission Denial: isUserRunning() from pid="
18108                    + Binder.getCallingPid()
18109                    + ", uid=" + Binder.getCallingUid()
18110                    + " requires " + INTERACT_ACROSS_USERS;
18111            Slog.w(TAG, msg);
18112            throw new SecurityException(msg);
18113        }
18114        synchronized (this) {
18115            return mStartedUserArray;
18116        }
18117    }
18118
18119    private void updateStartedUserArrayLocked() {
18120        int num = 0;
18121        for (int i=0; i<mStartedUsers.size();  i++) {
18122            UserStartedState uss = mStartedUsers.valueAt(i);
18123            // This list does not include stopping users.
18124            if (uss.mState != UserStartedState.STATE_STOPPING
18125                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18126                num++;
18127            }
18128        }
18129        mStartedUserArray = new int[num];
18130        num = 0;
18131        for (int i=0; i<mStartedUsers.size();  i++) {
18132            UserStartedState uss = mStartedUsers.valueAt(i);
18133            if (uss.mState != UserStartedState.STATE_STOPPING
18134                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18135                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18136                num++;
18137            }
18138        }
18139    }
18140
18141    @Override
18142    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18143        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18144                != PackageManager.PERMISSION_GRANTED) {
18145            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18146                    + Binder.getCallingPid()
18147                    + ", uid=" + Binder.getCallingUid()
18148                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18149            Slog.w(TAG, msg);
18150            throw new SecurityException(msg);
18151        }
18152
18153        mUserSwitchObservers.register(observer);
18154    }
18155
18156    @Override
18157    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18158        mUserSwitchObservers.unregister(observer);
18159    }
18160
18161    private boolean userExists(int userId) {
18162        if (userId == 0) {
18163            return true;
18164        }
18165        UserManagerService ums = getUserManagerLocked();
18166        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18167    }
18168
18169    int[] getUsersLocked() {
18170        UserManagerService ums = getUserManagerLocked();
18171        return ums != null ? ums.getUserIds() : new int[] { 0 };
18172    }
18173
18174    UserManagerService getUserManagerLocked() {
18175        if (mUserManager == null) {
18176            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18177            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18178        }
18179        return mUserManager;
18180    }
18181
18182    private int applyUserId(int uid, int userId) {
18183        return UserHandle.getUid(userId, uid);
18184    }
18185
18186    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18187        if (info == null) return null;
18188        ApplicationInfo newInfo = new ApplicationInfo(info);
18189        newInfo.uid = applyUserId(info.uid, userId);
18190        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18191                + info.packageName;
18192        return newInfo;
18193    }
18194
18195    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18196        if (aInfo == null
18197                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18198            return aInfo;
18199        }
18200
18201        ActivityInfo info = new ActivityInfo(aInfo);
18202        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18203        return info;
18204    }
18205
18206    private final class LocalService extends ActivityManagerInternal {
18207        @Override
18208        public void goingToSleep() {
18209            ActivityManagerService.this.goingToSleep();
18210        }
18211
18212        @Override
18213        public void wakingUp() {
18214            ActivityManagerService.this.wakingUp();
18215        }
18216
18217        @Override
18218        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18219                String processName, String abiOverride, int uid, Runnable crashHandler) {
18220            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18221                    processName, abiOverride, uid, crashHandler);
18222        }
18223    }
18224
18225    /**
18226     * An implementation of IAppTask, that allows an app to manage its own tasks via
18227     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18228     * only the process that calls getAppTasks() can call the AppTask methods.
18229     */
18230    class AppTaskImpl extends IAppTask.Stub {
18231        private int mTaskId;
18232        private int mCallingUid;
18233
18234        public AppTaskImpl(int taskId, int callingUid) {
18235            mTaskId = taskId;
18236            mCallingUid = callingUid;
18237        }
18238
18239        private void checkCaller() {
18240            if (mCallingUid != Binder.getCallingUid()) {
18241                throw new SecurityException("Caller " + mCallingUid
18242                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18243            }
18244        }
18245
18246        @Override
18247        public void finishAndRemoveTask() {
18248            checkCaller();
18249
18250            synchronized (ActivityManagerService.this) {
18251                long origId = Binder.clearCallingIdentity();
18252                try {
18253                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18254                    if (tr != null) {
18255                        // Only kill the process if we are not a new document
18256                        int flags = tr.getBaseIntent().getFlags();
18257                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18258                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18259                        removeTaskByIdLocked(mTaskId,
18260                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18261                    }
18262                } finally {
18263                    Binder.restoreCallingIdentity(origId);
18264                }
18265            }
18266        }
18267
18268        @Override
18269        public ActivityManager.RecentTaskInfo getTaskInfo() {
18270            checkCaller();
18271
18272            synchronized (ActivityManagerService.this) {
18273                long origId = Binder.clearCallingIdentity();
18274                try {
18275                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18276                    if (tr != null) {
18277                        return createRecentTaskInfoFromTaskRecord(tr);
18278                    }
18279                } finally {
18280                    Binder.restoreCallingIdentity(origId);
18281                }
18282                return null;
18283            }
18284        }
18285
18286        @Override
18287        public void setExcludeFromRecents(boolean exclude) {
18288            checkCaller();
18289
18290            synchronized (ActivityManagerService.this) {
18291                long origId = Binder.clearCallingIdentity();
18292                try {
18293                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18294                    if (tr != null) {
18295                        Intent intent = tr.getBaseIntent();
18296                        if (exclude) {
18297                            intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18298                        } else {
18299                            intent.setFlags(intent.getFlags()
18300                                    & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18301                        }
18302                    }
18303                } finally {
18304                    Binder.restoreCallingIdentity(origId);
18305                }
18306            }
18307        }
18308    }
18309}
18310