ActivityManagerService.java revision aec68bb89fe614181a20eb97340149406218ce2f
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
1183    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1184    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1185    static final int FIRST_COMPAT_MODE_MSG = 300;
1186    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1187
1188    AlertDialog mUidAlert;
1189    CompatModeDialog mCompatModeDialog;
1190    long mLastMemUsageReportTime = 0;
1191
1192    private LockToAppRequestDialog mLockToAppRequest;
1193
1194    /**
1195     * Flag whether the current user is a "monkey", i.e. whether
1196     * the UI is driven by a UI automation tool.
1197     */
1198    private boolean mUserIsMonkey;
1199
1200    /** Flag whether the device has a recents UI */
1201    final boolean mHasRecents;
1202
1203    final int mThumbnailWidth;
1204    final int mThumbnailHeight;
1205
1206    final ServiceThread mHandlerThread;
1207    final MainHandler mHandler;
1208
1209    final class MainHandler extends Handler {
1210        public MainHandler(Looper looper) {
1211            super(looper, null, true);
1212        }
1213
1214        @Override
1215        public void handleMessage(Message msg) {
1216            switch (msg.what) {
1217            case SHOW_ERROR_MSG: {
1218                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1219                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1220                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1221                synchronized (ActivityManagerService.this) {
1222                    ProcessRecord proc = (ProcessRecord)data.get("app");
1223                    AppErrorResult res = (AppErrorResult) data.get("result");
1224                    if (proc != null && proc.crashDialog != null) {
1225                        Slog.e(TAG, "App already has crash dialog: " + proc);
1226                        if (res != null) {
1227                            res.set(0);
1228                        }
1229                        return;
1230                    }
1231                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1232                            >= Process.FIRST_APPLICATION_UID
1233                            && proc.pid != MY_PID);
1234                    for (int userId : mCurrentProfileIds) {
1235                        isBackground &= (proc.userId != userId);
1236                    }
1237                    if (isBackground && !showBackground) {
1238                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1239                        if (res != null) {
1240                            res.set(0);
1241                        }
1242                        return;
1243                    }
1244                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1245                        Dialog d = new AppErrorDialog(mContext,
1246                                ActivityManagerService.this, res, proc);
1247                        d.show();
1248                        proc.crashDialog = d;
1249                    } else {
1250                        // The device is asleep, so just pretend that the user
1251                        // saw a crash dialog and hit "force quit".
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                    }
1256                }
1257
1258                ensureBootCompleted();
1259            } break;
1260            case SHOW_NOT_RESPONDING_MSG: {
1261                synchronized (ActivityManagerService.this) {
1262                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1263                    ProcessRecord proc = (ProcessRecord)data.get("app");
1264                    if (proc != null && proc.anrDialog != null) {
1265                        Slog.e(TAG, "App already has anr dialog: " + proc);
1266                        return;
1267                    }
1268
1269                    Intent intent = new Intent("android.intent.action.ANR");
1270                    if (!mProcessesReady) {
1271                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1272                                | Intent.FLAG_RECEIVER_FOREGROUND);
1273                    }
1274                    broadcastIntentLocked(null, null, intent,
1275                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1276                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1277
1278                    if (mShowDialogs) {
1279                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1280                                mContext, proc, (ActivityRecord)data.get("activity"),
1281                                msg.arg1 != 0);
1282                        d.show();
1283                        proc.anrDialog = d;
1284                    } else {
1285                        // Just kill the app if there is no dialog to be shown.
1286                        killAppAtUsersRequest(proc, null);
1287                    }
1288                }
1289
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1293                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1294                synchronized (ActivityManagerService.this) {
1295                    ProcessRecord proc = (ProcessRecord) data.get("app");
1296                    if (proc == null) {
1297                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1298                        break;
1299                    }
1300                    if (proc.crashDialog != null) {
1301                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1302                        return;
1303                    }
1304                    AppErrorResult res = (AppErrorResult) data.get("result");
1305                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1306                        Dialog d = new StrictModeViolationDialog(mContext,
1307                                ActivityManagerService.this, res, proc);
1308                        d.show();
1309                        proc.crashDialog = d;
1310                    } else {
1311                        // The device is asleep, so just pretend that the user
1312                        // saw a crash dialog and hit "force quit".
1313                        res.set(0);
1314                    }
1315                }
1316                ensureBootCompleted();
1317            } break;
1318            case SHOW_FACTORY_ERROR_MSG: {
1319                Dialog d = new FactoryErrorDialog(
1320                    mContext, msg.getData().getCharSequence("msg"));
1321                d.show();
1322                ensureBootCompleted();
1323            } break;
1324            case UPDATE_CONFIGURATION_MSG: {
1325                final ContentResolver resolver = mContext.getContentResolver();
1326                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1327            } break;
1328            case GC_BACKGROUND_PROCESSES_MSG: {
1329                synchronized (ActivityManagerService.this) {
1330                    performAppGcsIfAppropriateLocked();
1331                }
1332            } break;
1333            case WAIT_FOR_DEBUGGER_MSG: {
1334                synchronized (ActivityManagerService.this) {
1335                    ProcessRecord app = (ProcessRecord)msg.obj;
1336                    if (msg.arg1 != 0) {
1337                        if (!app.waitedForDebugger) {
1338                            Dialog d = new AppWaitingForDebuggerDialog(
1339                                    ActivityManagerService.this,
1340                                    mContext, app);
1341                            app.waitDialog = d;
1342                            app.waitedForDebugger = true;
1343                            d.show();
1344                        }
1345                    } else {
1346                        if (app.waitDialog != null) {
1347                            app.waitDialog.dismiss();
1348                            app.waitDialog = null;
1349                        }
1350                    }
1351                }
1352            } break;
1353            case SERVICE_TIMEOUT_MSG: {
1354                if (mDidDexOpt) {
1355                    mDidDexOpt = false;
1356                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1357                    nmsg.obj = msg.obj;
1358                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1359                    return;
1360                }
1361                mServices.serviceTimeout((ProcessRecord)msg.obj);
1362            } break;
1363            case UPDATE_TIME_ZONE: {
1364                synchronized (ActivityManagerService.this) {
1365                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1366                        ProcessRecord r = mLruProcesses.get(i);
1367                        if (r.thread != null) {
1368                            try {
1369                                r.thread.updateTimeZone();
1370                            } catch (RemoteException ex) {
1371                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1372                            }
1373                        }
1374                    }
1375                }
1376            } break;
1377            case CLEAR_DNS_CACHE_MSG: {
1378                synchronized (ActivityManagerService.this) {
1379                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1380                        ProcessRecord r = mLruProcesses.get(i);
1381                        if (r.thread != null) {
1382                            try {
1383                                r.thread.clearDnsCache();
1384                            } catch (RemoteException ex) {
1385                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case UPDATE_HTTP_PROXY_MSG: {
1392                ProxyInfo proxy = (ProxyInfo)msg.obj;
1393                String host = "";
1394                String port = "";
1395                String exclList = "";
1396                Uri pacFileUrl = Uri.EMPTY;
1397                if (proxy != null) {
1398                    host = proxy.getHost();
1399                    port = Integer.toString(proxy.getPort());
1400                    exclList = proxy.getExclusionListAsString();
1401                    pacFileUrl = proxy.getPacFileUrl();
1402                }
1403                synchronized (ActivityManagerService.this) {
1404                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1405                        ProcessRecord r = mLruProcesses.get(i);
1406                        if (r.thread != null) {
1407                            try {
1408                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1409                            } catch (RemoteException ex) {
1410                                Slog.w(TAG, "Failed to update http proxy for: " +
1411                                        r.info.processName);
1412                            }
1413                        }
1414                    }
1415                }
1416            } break;
1417            case SHOW_UID_ERROR_MSG: {
1418                String title = "System UIDs Inconsistent";
1419                String text = "UIDs on the system are inconsistent, you need to wipe your"
1420                        + " data partition or your device will be unstable.";
1421                Log.e(TAG, title + ": " + text);
1422                if (mShowDialogs) {
1423                    // XXX This is a temporary dialog, no need to localize.
1424                    AlertDialog d = new BaseErrorDialog(mContext);
1425                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1426                    d.setCancelable(false);
1427                    d.setTitle(title);
1428                    d.setMessage(text);
1429                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1430                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1431                    mUidAlert = d;
1432                    d.show();
1433                }
1434            } break;
1435            case IM_FEELING_LUCKY_MSG: {
1436                if (mUidAlert != null) {
1437                    mUidAlert.dismiss();
1438                    mUidAlert = null;
1439                }
1440            } break;
1441            case PROC_START_TIMEOUT_MSG: {
1442                if (mDidDexOpt) {
1443                    mDidDexOpt = false;
1444                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1445                    nmsg.obj = msg.obj;
1446                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1447                    return;
1448                }
1449                ProcessRecord app = (ProcessRecord)msg.obj;
1450                synchronized (ActivityManagerService.this) {
1451                    processStartTimedOutLocked(app);
1452                }
1453            } break;
1454            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1455                synchronized (ActivityManagerService.this) {
1456                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1457                }
1458            } break;
1459            case KILL_APPLICATION_MSG: {
1460                synchronized (ActivityManagerService.this) {
1461                    int appid = msg.arg1;
1462                    boolean restart = (msg.arg2 == 1);
1463                    Bundle bundle = (Bundle)msg.obj;
1464                    String pkg = bundle.getString("pkg");
1465                    String reason = bundle.getString("reason");
1466                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1467                            false, UserHandle.USER_ALL, reason);
1468                }
1469            } break;
1470            case FINALIZE_PENDING_INTENT_MSG: {
1471                ((PendingIntentRecord)msg.obj).completeFinalize();
1472            } break;
1473            case POST_HEAVY_NOTIFICATION_MSG: {
1474                INotificationManager inm = NotificationManager.getService();
1475                if (inm == null) {
1476                    return;
1477                }
1478
1479                ActivityRecord root = (ActivityRecord)msg.obj;
1480                ProcessRecord process = root.app;
1481                if (process == null) {
1482                    return;
1483                }
1484
1485                try {
1486                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1487                    String text = mContext.getString(R.string.heavy_weight_notification,
1488                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1489                    Notification notification = new Notification();
1490                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1491                    notification.when = 0;
1492                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1493                    notification.tickerText = text;
1494                    notification.defaults = 0; // please be quiet
1495                    notification.sound = null;
1496                    notification.vibrate = null;
1497                    notification.color = mContext.getResources().getColor(
1498                            com.android.internal.R.color.system_notification_accent_color);
1499                    notification.setLatestEventInfo(context, text,
1500                            mContext.getText(R.string.heavy_weight_notification_detail),
1501                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1502                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1503                                    new UserHandle(root.userId)));
1504
1505                    try {
1506                        int[] outId = new int[1];
1507                        inm.enqueueNotificationWithTag("android", "android", null,
1508                                R.string.heavy_weight_notification,
1509                                notification, outId, root.userId);
1510                    } catch (RuntimeException e) {
1511                        Slog.w(ActivityManagerService.TAG,
1512                                "Error showing notification for heavy-weight app", e);
1513                    } catch (RemoteException e) {
1514                    }
1515                } catch (NameNotFoundException e) {
1516                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1517                }
1518            } break;
1519            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1520                INotificationManager inm = NotificationManager.getService();
1521                if (inm == null) {
1522                    return;
1523                }
1524                try {
1525                    inm.cancelNotificationWithTag("android", null,
1526                            R.string.heavy_weight_notification,  msg.arg1);
1527                } catch (RuntimeException e) {
1528                    Slog.w(ActivityManagerService.TAG,
1529                            "Error canceling notification for service", e);
1530                } catch (RemoteException e) {
1531                }
1532            } break;
1533            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1534                synchronized (ActivityManagerService.this) {
1535                    checkExcessivePowerUsageLocked(true);
1536                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1537                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1538                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1539                }
1540            } break;
1541            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1542                synchronized (ActivityManagerService.this) {
1543                    ActivityRecord ar = (ActivityRecord)msg.obj;
1544                    if (mCompatModeDialog != null) {
1545                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1546                                ar.info.applicationInfo.packageName)) {
1547                            return;
1548                        }
1549                        mCompatModeDialog.dismiss();
1550                        mCompatModeDialog = null;
1551                    }
1552                    if (ar != null && false) {
1553                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1554                                ar.packageName)) {
1555                            int mode = mCompatModePackages.computeCompatModeLocked(
1556                                    ar.info.applicationInfo);
1557                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1558                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1559                                mCompatModeDialog = new CompatModeDialog(
1560                                        ActivityManagerService.this, mContext,
1561                                        ar.info.applicationInfo);
1562                                mCompatModeDialog.show();
1563                            }
1564                        }
1565                    }
1566                }
1567                break;
1568            }
1569            case DISPATCH_PROCESSES_CHANGED: {
1570                dispatchProcessesChanged();
1571                break;
1572            }
1573            case DISPATCH_PROCESS_DIED: {
1574                final int pid = msg.arg1;
1575                final int uid = msg.arg2;
1576                dispatchProcessDied(pid, uid);
1577                break;
1578            }
1579            case REPORT_MEM_USAGE_MSG: {
1580                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1581                Thread thread = new Thread() {
1582                    @Override public void run() {
1583                        final SparseArray<ProcessMemInfo> infoMap
1584                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587                            infoMap.put(mi.pid, mi);
1588                        }
1589                        updateCpuStatsNow();
1590                        synchronized (mProcessCpuThread) {
1591                            final int N = mProcessCpuTracker.countStats();
1592                            for (int i=0; i<N; i++) {
1593                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1594                                if (st.vsize > 0) {
1595                                    long pss = Debug.getPss(st.pid, null);
1596                                    if (pss > 0) {
1597                                        if (infoMap.indexOfKey(st.pid) < 0) {
1598                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1599                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1600                                            mi.pss = pss;
1601                                            memInfos.add(mi);
1602                                        }
1603                                    }
1604                                }
1605                            }
1606                        }
1607
1608                        long totalPss = 0;
1609                        for (int i=0, N=memInfos.size(); i<N; i++) {
1610                            ProcessMemInfo mi = memInfos.get(i);
1611                            if (mi.pss == 0) {
1612                                mi.pss = Debug.getPss(mi.pid, null);
1613                            }
1614                            totalPss += mi.pss;
1615                        }
1616                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1617                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1618                                if (lhs.oomAdj != rhs.oomAdj) {
1619                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1620                                }
1621                                if (lhs.pss != rhs.pss) {
1622                                    return lhs.pss < rhs.pss ? 1 : -1;
1623                                }
1624                                return 0;
1625                            }
1626                        });
1627
1628                        StringBuilder tag = new StringBuilder(128);
1629                        StringBuilder stack = new StringBuilder(128);
1630                        tag.append("Low on memory -- ");
1631                        appendMemBucket(tag, totalPss, "total", false);
1632                        appendMemBucket(stack, totalPss, "total", true);
1633
1634                        StringBuilder logBuilder = new StringBuilder(1024);
1635                        logBuilder.append("Low on memory:\n");
1636
1637                        boolean firstLine = true;
1638                        int lastOomAdj = Integer.MIN_VALUE;
1639                        for (int i=0, N=memInfos.size(); i<N; i++) {
1640                            ProcessMemInfo mi = memInfos.get(i);
1641
1642                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1643                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1644                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1645                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1646                                if (lastOomAdj != mi.oomAdj) {
1647                                    lastOomAdj = mi.oomAdj;
1648                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1649                                        tag.append(" / ");
1650                                    }
1651                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1652                                        if (firstLine) {
1653                                            stack.append(":");
1654                                            firstLine = false;
1655                                        }
1656                                        stack.append("\n\t at ");
1657                                    } else {
1658                                        stack.append("$");
1659                                    }
1660                                } else {
1661                                    tag.append(" ");
1662                                    stack.append("$");
1663                                }
1664                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1665                                    appendMemBucket(tag, mi.pss, mi.name, false);
1666                                }
1667                                appendMemBucket(stack, mi.pss, mi.name, true);
1668                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1669                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1670                                    stack.append("(");
1671                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1672                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1673                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1674                                            stack.append(":");
1675                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1676                                        }
1677                                    }
1678                                    stack.append(")");
1679                                }
1680                            }
1681
1682                            logBuilder.append("  ");
1683                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1684                            logBuilder.append(' ');
1685                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1686                            logBuilder.append(' ');
1687                            ProcessList.appendRamKb(logBuilder, mi.pss);
1688                            logBuilder.append(" kB: ");
1689                            logBuilder.append(mi.name);
1690                            logBuilder.append(" (");
1691                            logBuilder.append(mi.pid);
1692                            logBuilder.append(") ");
1693                            logBuilder.append(mi.adjType);
1694                            logBuilder.append('\n');
1695                            if (mi.adjReason != null) {
1696                                logBuilder.append("                      ");
1697                                logBuilder.append(mi.adjReason);
1698                                logBuilder.append('\n');
1699                            }
1700                        }
1701
1702                        logBuilder.append("           ");
1703                        ProcessList.appendRamKb(logBuilder, totalPss);
1704                        logBuilder.append(" kB: TOTAL\n");
1705
1706                        long[] infos = new long[Debug.MEMINFO_COUNT];
1707                        Debug.getMemInfo(infos);
1708                        logBuilder.append("  MemInfo: ");
1709                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1710                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1711                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1712                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1713                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1714                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1715                            logBuilder.append("  ZRAM: ");
1716                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1717                            logBuilder.append(" kB RAM, ");
1718                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1719                            logBuilder.append(" kB swap total, ");
1720                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1721                            logBuilder.append(" kB swap free\n");
1722                        }
1723                        Slog.i(TAG, logBuilder.toString());
1724
1725                        StringBuilder dropBuilder = new StringBuilder(1024);
1726                        /*
1727                        StringWriter oomSw = new StringWriter();
1728                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1729                        StringWriter catSw = new StringWriter();
1730                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1731                        String[] emptyArgs = new String[] { };
1732                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1733                        oomPw.flush();
1734                        String oomString = oomSw.toString();
1735                        */
1736                        dropBuilder.append(stack);
1737                        dropBuilder.append('\n');
1738                        dropBuilder.append('\n');
1739                        dropBuilder.append(logBuilder);
1740                        dropBuilder.append('\n');
1741                        /*
1742                        dropBuilder.append(oomString);
1743                        dropBuilder.append('\n');
1744                        */
1745                        StringWriter catSw = new StringWriter();
1746                        synchronized (ActivityManagerService.this) {
1747                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1748                            String[] emptyArgs = new String[] { };
1749                            catPw.println();
1750                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1751                            catPw.println();
1752                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1753                                    false, false, null);
1754                            catPw.println();
1755                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1756                            catPw.flush();
1757                        }
1758                        dropBuilder.append(catSw.toString());
1759                        addErrorToDropBox("lowmem", null, "system_server", null,
1760                                null, tag.toString(), dropBuilder.toString(), null, null);
1761                        //Slog.i(TAG, "Sent to dropbox:");
1762                        //Slog.i(TAG, dropBuilder.toString());
1763                        synchronized (ActivityManagerService.this) {
1764                            long now = SystemClock.uptimeMillis();
1765                            if (mLastMemUsageReportTime < now) {
1766                                mLastMemUsageReportTime = now;
1767                            }
1768                        }
1769                    }
1770                };
1771                thread.start();
1772                break;
1773            }
1774            case REPORT_USER_SWITCH_MSG: {
1775                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1776                break;
1777            }
1778            case CONTINUE_USER_SWITCH_MSG: {
1779                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1780                break;
1781            }
1782            case USER_SWITCH_TIMEOUT_MSG: {
1783                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1784                break;
1785            }
1786            case IMMERSIVE_MODE_LOCK_MSG: {
1787                final boolean nextState = (msg.arg1 != 0);
1788                if (mUpdateLock.isHeld() != nextState) {
1789                    if (DEBUG_IMMERSIVE) {
1790                        final ActivityRecord r = (ActivityRecord) msg.obj;
1791                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1792                    }
1793                    if (nextState) {
1794                        mUpdateLock.acquire();
1795                    } else {
1796                        mUpdateLock.release();
1797                    }
1798                }
1799                break;
1800            }
1801            case PERSIST_URI_GRANTS_MSG: {
1802                writeGrantedUriPermissions();
1803                break;
1804            }
1805            case REQUEST_ALL_PSS_MSG: {
1806                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1807                break;
1808            }
1809            case START_PROFILES_MSG: {
1810                synchronized (ActivityManagerService.this) {
1811                    startProfilesLocked();
1812                }
1813                break;
1814            }
1815            case UPDATE_TIME: {
1816                synchronized (ActivityManagerService.this) {
1817                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1818                        ProcessRecord r = mLruProcesses.get(i);
1819                        if (r.thread != null) {
1820                            try {
1821                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1822                            } catch (RemoteException ex) {
1823                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1824                            }
1825                        }
1826                    }
1827                }
1828                break;
1829            }
1830            case SYSTEM_USER_START_MSG: {
1831                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1832                        Integer.toString(msg.arg1), msg.arg1);
1833                mSystemServiceManager.startUser(msg.arg1);
1834                break;
1835            }
1836            case SYSTEM_USER_CURRENT_MSG: {
1837                mBatteryStatsService.noteEvent(
1838                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1839                        Integer.toString(msg.arg2), msg.arg2);
1840                mBatteryStatsService.noteEvent(
1841                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1842                        Integer.toString(msg.arg1), msg.arg1);
1843                mSystemServiceManager.switchUser(msg.arg1);
1844                break;
1845            }
1846            case ENTER_ANIMATION_COMPLETE_MSG: {
1847                synchronized (ActivityManagerService.this) {
1848                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1849                    if (r != null && r.app != null && r.app.thread != null) {
1850                        try {
1851                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1852                        } catch (RemoteException e) {
1853                        }
1854                    }
1855                }
1856                break;
1857            }
1858            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1859                enableScreenAfterBoot();
1860                break;
1861            }
1862            }
1863        }
1864    };
1865
1866    static final int COLLECT_PSS_BG_MSG = 1;
1867
1868    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1869        @Override
1870        public void handleMessage(Message msg) {
1871            switch (msg.what) {
1872            case COLLECT_PSS_BG_MSG: {
1873                long start = SystemClock.uptimeMillis();
1874                MemInfoReader memInfo = null;
1875                synchronized (ActivityManagerService.this) {
1876                    if (mFullPssPending) {
1877                        mFullPssPending = false;
1878                        memInfo = new MemInfoReader();
1879                    }
1880                }
1881                if (memInfo != null) {
1882                    updateCpuStatsNow();
1883                    long nativeTotalPss = 0;
1884                    synchronized (mProcessCpuThread) {
1885                        final int N = mProcessCpuTracker.countStats();
1886                        for (int j=0; j<N; j++) {
1887                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1888                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1889                                // This is definitely an application process; skip it.
1890                                continue;
1891                            }
1892                            synchronized (mPidsSelfLocked) {
1893                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1894                                    // This is one of our own processes; skip it.
1895                                    continue;
1896                                }
1897                            }
1898                            nativeTotalPss += Debug.getPss(st.pid, null);
1899                        }
1900                    }
1901                    memInfo.readMemInfo();
1902                    synchronized (this) {
1903                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1904                                + (SystemClock.uptimeMillis()-start) + "ms");
1905                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1906                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1907                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1908                                        +memInfo.getSlabSizeKb(),
1909                                nativeTotalPss);
1910                    }
1911                }
1912
1913                int i=0, num=0;
1914                long[] tmp = new long[1];
1915                do {
1916                    ProcessRecord proc;
1917                    int procState;
1918                    int pid;
1919                    synchronized (ActivityManagerService.this) {
1920                        if (i >= mPendingPssProcesses.size()) {
1921                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1922                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1923                            mPendingPssProcesses.clear();
1924                            return;
1925                        }
1926                        proc = mPendingPssProcesses.get(i);
1927                        procState = proc.pssProcState;
1928                        if (proc.thread != null && procState == proc.setProcState) {
1929                            pid = proc.pid;
1930                        } else {
1931                            proc = null;
1932                            pid = 0;
1933                        }
1934                        i++;
1935                    }
1936                    if (proc != null) {
1937                        long pss = Debug.getPss(pid, tmp);
1938                        synchronized (ActivityManagerService.this) {
1939                            if (proc.thread != null && proc.setProcState == procState
1940                                    && proc.pid == pid) {
1941                                num++;
1942                                proc.lastPssTime = SystemClock.uptimeMillis();
1943                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1944                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1945                                        + ": " + pss + " lastPss=" + proc.lastPss
1946                                        + " state=" + ProcessList.makeProcStateString(procState));
1947                                if (proc.initialIdlePss == 0) {
1948                                    proc.initialIdlePss = pss;
1949                                }
1950                                proc.lastPss = pss;
1951                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1952                                    proc.lastCachedPss = pss;
1953                                }
1954                            }
1955                        }
1956                    }
1957                } while (true);
1958            }
1959            }
1960        }
1961    };
1962
1963    /**
1964     * Monitor for package changes and update our internal state.
1965     */
1966    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1967        @Override
1968        public void onPackageRemoved(String packageName, int uid) {
1969            // Remove all tasks with activities in the specified package from the list of recent tasks
1970            synchronized (ActivityManagerService.this) {
1971                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1972                    TaskRecord tr = mRecentTasks.get(i);
1973                    ComponentName cn = tr.intent.getComponent();
1974                    if (cn != null && cn.getPackageName().equals(packageName)) {
1975                        // If the package name matches, remove the task and kill the process
1976                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1977                    }
1978                }
1979            }
1980        }
1981
1982        @Override
1983        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1984            onPackageModified(packageName);
1985            return true;
1986        }
1987
1988        @Override
1989        public void onPackageModified(String packageName) {
1990            final PackageManager pm = mContext.getPackageManager();
1991            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1992                    new ArrayList<Pair<Intent, Integer>>();
1993            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1994            // Copy the list of recent tasks so that we don't hold onto the lock on
1995            // ActivityManagerService for long periods while checking if components exist.
1996            synchronized (ActivityManagerService.this) {
1997                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1998                    TaskRecord tr = mRecentTasks.get(i);
1999                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2000                }
2001            }
2002            // Check the recent tasks and filter out all tasks with components that no longer exist.
2003            Intent tmpI = new Intent();
2004            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2005                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2006                ComponentName cn = p.first.getComponent();
2007                if (cn != null && cn.getPackageName().equals(packageName)) {
2008                    try {
2009                        // Add the task to the list to remove if the component no longer exists
2010                        tmpI.setComponent(cn);
2011                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2012                            tasksToRemove.add(p.second);
2013                        }
2014                    } catch (Exception e) {}
2015                }
2016            }
2017            // Prune all the tasks with removed components from the list of recent tasks
2018            synchronized (ActivityManagerService.this) {
2019                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2020                    // Remove the task but don't kill the process (since other components in that
2021                    // package may still be running and in the background)
2022                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2023                }
2024            }
2025        }
2026
2027        @Override
2028        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2029            // Force stop the specified packages
2030            if (packages != null) {
2031                for (String pkg : packages) {
2032                    synchronized (ActivityManagerService.this) {
2033                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2034                                "finished booting")) {
2035                            return true;
2036                        }
2037                    }
2038                }
2039            }
2040            return false;
2041        }
2042    };
2043
2044    public void setSystemProcess() {
2045        try {
2046            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2047            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2048            ServiceManager.addService("meminfo", new MemBinder(this));
2049            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2050            ServiceManager.addService("dbinfo", new DbBinder(this));
2051            if (MONITOR_CPU_USAGE) {
2052                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2053            }
2054            ServiceManager.addService("permission", new PermissionController(this));
2055
2056            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2057                    "android", STOCK_PM_FLAGS);
2058            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2059
2060            synchronized (this) {
2061                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2062                app.persistent = true;
2063                app.pid = MY_PID;
2064                app.maxAdj = ProcessList.SYSTEM_ADJ;
2065                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2066                mProcessNames.put(app.processName, app.uid, app);
2067                synchronized (mPidsSelfLocked) {
2068                    mPidsSelfLocked.put(app.pid, app);
2069                }
2070                updateLruProcessLocked(app, false, null);
2071                updateOomAdjLocked();
2072            }
2073        } catch (PackageManager.NameNotFoundException e) {
2074            throw new RuntimeException(
2075                    "Unable to find android system package", e);
2076        }
2077    }
2078
2079    public void setWindowManager(WindowManagerService wm) {
2080        mWindowManager = wm;
2081        mStackSupervisor.setWindowManager(wm);
2082    }
2083
2084    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2085        mUsageStatsService = usageStatsManager;
2086    }
2087
2088    public void startObservingNativeCrashes() {
2089        final NativeCrashListener ncl = new NativeCrashListener(this);
2090        ncl.start();
2091    }
2092
2093    public IAppOpsService getAppOpsService() {
2094        return mAppOpsService;
2095    }
2096
2097    static class MemBinder extends Binder {
2098        ActivityManagerService mActivityManagerService;
2099        MemBinder(ActivityManagerService activityManagerService) {
2100            mActivityManagerService = activityManagerService;
2101        }
2102
2103        @Override
2104        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2105            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2106                    != PackageManager.PERMISSION_GRANTED) {
2107                pw.println("Permission Denial: can't dump meminfo from from pid="
2108                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2109                        + " without permission " + android.Manifest.permission.DUMP);
2110                return;
2111            }
2112
2113            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2114        }
2115    }
2116
2117    static class GraphicsBinder extends Binder {
2118        ActivityManagerService mActivityManagerService;
2119        GraphicsBinder(ActivityManagerService activityManagerService) {
2120            mActivityManagerService = activityManagerService;
2121        }
2122
2123        @Override
2124        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2125            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2126                    != PackageManager.PERMISSION_GRANTED) {
2127                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2128                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2129                        + " without permission " + android.Manifest.permission.DUMP);
2130                return;
2131            }
2132
2133            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2134        }
2135    }
2136
2137    static class DbBinder extends Binder {
2138        ActivityManagerService mActivityManagerService;
2139        DbBinder(ActivityManagerService activityManagerService) {
2140            mActivityManagerService = activityManagerService;
2141        }
2142
2143        @Override
2144        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2145            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2146                    != PackageManager.PERMISSION_GRANTED) {
2147                pw.println("Permission Denial: can't dump dbinfo from from pid="
2148                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2149                        + " without permission " + android.Manifest.permission.DUMP);
2150                return;
2151            }
2152
2153            mActivityManagerService.dumpDbInfo(fd, pw, args);
2154        }
2155    }
2156
2157    static class CpuBinder extends Binder {
2158        ActivityManagerService mActivityManagerService;
2159        CpuBinder(ActivityManagerService activityManagerService) {
2160            mActivityManagerService = activityManagerService;
2161        }
2162
2163        @Override
2164        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2165            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2166                    != PackageManager.PERMISSION_GRANTED) {
2167                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2168                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2169                        + " without permission " + android.Manifest.permission.DUMP);
2170                return;
2171            }
2172
2173            synchronized (mActivityManagerService.mProcessCpuThread) {
2174                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2175                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2176                        SystemClock.uptimeMillis()));
2177            }
2178        }
2179    }
2180
2181    public static final class Lifecycle extends SystemService {
2182        private final ActivityManagerService mService;
2183
2184        public Lifecycle(Context context) {
2185            super(context);
2186            mService = new ActivityManagerService(context);
2187        }
2188
2189        @Override
2190        public void onStart() {
2191            mService.start();
2192        }
2193
2194        public ActivityManagerService getService() {
2195            return mService;
2196        }
2197    }
2198
2199    // Note: This method is invoked on the main thread but may need to attach various
2200    // handlers to other threads.  So take care to be explicit about the looper.
2201    public ActivityManagerService(Context systemContext) {
2202        mContext = systemContext;
2203        mFactoryTest = FactoryTest.getMode();
2204        mSystemThread = ActivityThread.currentActivityThread();
2205
2206        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2207
2208        mHandlerThread = new ServiceThread(TAG,
2209                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2210        mHandlerThread.start();
2211        mHandler = new MainHandler(mHandlerThread.getLooper());
2212
2213        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2214                "foreground", BROADCAST_FG_TIMEOUT, false);
2215        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2216                "background", BROADCAST_BG_TIMEOUT, true);
2217        mBroadcastQueues[0] = mFgBroadcastQueue;
2218        mBroadcastQueues[1] = mBgBroadcastQueue;
2219
2220        mServices = new ActiveServices(this);
2221        mProviderMap = new ProviderMap(this);
2222
2223        // TODO: Move creation of battery stats service outside of activity manager service.
2224        File dataDir = Environment.getDataDirectory();
2225        File systemDir = new File(dataDir, "system");
2226        systemDir.mkdirs();
2227        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2228        mBatteryStatsService.getActiveStatistics().readLocked();
2229        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2230        mOnBattery = DEBUG_POWER ? true
2231                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2232        mBatteryStatsService.getActiveStatistics().setCallback(this);
2233
2234        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2235
2236        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2237
2238        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2239
2240        // User 0 is the first and only user that runs at boot.
2241        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2242        mUserLru.add(Integer.valueOf(0));
2243        updateStartedUserArrayLocked();
2244
2245        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2246            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2247
2248        mConfiguration.setToDefaults();
2249        mConfiguration.setLocale(Locale.getDefault());
2250
2251        mConfigurationSeq = mConfiguration.seq = 1;
2252        mProcessCpuTracker.init();
2253
2254        final Resources res = mContext.getResources();
2255        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
2256        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2257        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2258
2259        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2260        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2261        mStackSupervisor = new ActivityStackSupervisor(this);
2262        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2263
2264        mProcessCpuThread = new Thread("CpuTracker") {
2265            @Override
2266            public void run() {
2267                while (true) {
2268                    try {
2269                        try {
2270                            synchronized(this) {
2271                                final long now = SystemClock.uptimeMillis();
2272                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2273                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2274                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2275                                //        + ", write delay=" + nextWriteDelay);
2276                                if (nextWriteDelay < nextCpuDelay) {
2277                                    nextCpuDelay = nextWriteDelay;
2278                                }
2279                                if (nextCpuDelay > 0) {
2280                                    mProcessCpuMutexFree.set(true);
2281                                    this.wait(nextCpuDelay);
2282                                }
2283                            }
2284                        } catch (InterruptedException e) {
2285                        }
2286                        updateCpuStatsNow();
2287                    } catch (Exception e) {
2288                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2289                    }
2290                }
2291            }
2292        };
2293
2294        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2295
2296        Watchdog.getInstance().addMonitor(this);
2297        Watchdog.getInstance().addThread(mHandler);
2298    }
2299
2300    public void setSystemServiceManager(SystemServiceManager mgr) {
2301        mSystemServiceManager = mgr;
2302    }
2303
2304    private void start() {
2305        Process.removeAllProcessGroups();
2306        mProcessCpuThread.start();
2307
2308        mBatteryStatsService.publish(mContext);
2309        mAppOpsService.publish(mContext);
2310        Slog.d("AppOps", "AppOpsService published");
2311        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2312    }
2313
2314    public void initPowerManagement() {
2315        mStackSupervisor.initPowerManagement();
2316        mBatteryStatsService.initPowerManagement();
2317    }
2318
2319    @Override
2320    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2321            throws RemoteException {
2322        if (code == SYSPROPS_TRANSACTION) {
2323            // We need to tell all apps about the system property change.
2324            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2325            synchronized(this) {
2326                final int NP = mProcessNames.getMap().size();
2327                for (int ip=0; ip<NP; ip++) {
2328                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2329                    final int NA = apps.size();
2330                    for (int ia=0; ia<NA; ia++) {
2331                        ProcessRecord app = apps.valueAt(ia);
2332                        if (app.thread != null) {
2333                            procs.add(app.thread.asBinder());
2334                        }
2335                    }
2336                }
2337            }
2338
2339            int N = procs.size();
2340            for (int i=0; i<N; i++) {
2341                Parcel data2 = Parcel.obtain();
2342                try {
2343                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2344                } catch (RemoteException e) {
2345                }
2346                data2.recycle();
2347            }
2348        }
2349        try {
2350            return super.onTransact(code, data, reply, flags);
2351        } catch (RuntimeException e) {
2352            // The activity manager only throws security exceptions, so let's
2353            // log all others.
2354            if (!(e instanceof SecurityException)) {
2355                Slog.wtf(TAG, "Activity Manager Crash", e);
2356            }
2357            throw e;
2358        }
2359    }
2360
2361    void updateCpuStats() {
2362        final long now = SystemClock.uptimeMillis();
2363        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2364            return;
2365        }
2366        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2367            synchronized (mProcessCpuThread) {
2368                mProcessCpuThread.notify();
2369            }
2370        }
2371    }
2372
2373    void updateCpuStatsNow() {
2374        synchronized (mProcessCpuThread) {
2375            mProcessCpuMutexFree.set(false);
2376            final long now = SystemClock.uptimeMillis();
2377            boolean haveNewCpuStats = false;
2378
2379            if (MONITOR_CPU_USAGE &&
2380                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2381                mLastCpuTime.set(now);
2382                haveNewCpuStats = true;
2383                mProcessCpuTracker.update();
2384                //Slog.i(TAG, mProcessCpu.printCurrentState());
2385                //Slog.i(TAG, "Total CPU usage: "
2386                //        + mProcessCpu.getTotalCpuPercent() + "%");
2387
2388                // Slog the cpu usage if the property is set.
2389                if ("true".equals(SystemProperties.get("events.cpu"))) {
2390                    int user = mProcessCpuTracker.getLastUserTime();
2391                    int system = mProcessCpuTracker.getLastSystemTime();
2392                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2393                    int irq = mProcessCpuTracker.getLastIrqTime();
2394                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2395                    int idle = mProcessCpuTracker.getLastIdleTime();
2396
2397                    int total = user + system + iowait + irq + softIrq + idle;
2398                    if (total == 0) total = 1;
2399
2400                    EventLog.writeEvent(EventLogTags.CPU,
2401                            ((user+system+iowait+irq+softIrq) * 100) / total,
2402                            (user * 100) / total,
2403                            (system * 100) / total,
2404                            (iowait * 100) / total,
2405                            (irq * 100) / total,
2406                            (softIrq * 100) / total);
2407                }
2408            }
2409
2410            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2411            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2412            synchronized(bstats) {
2413                synchronized(mPidsSelfLocked) {
2414                    if (haveNewCpuStats) {
2415                        if (mOnBattery) {
2416                            int perc = bstats.startAddingCpuLocked();
2417                            int totalUTime = 0;
2418                            int totalSTime = 0;
2419                            final int N = mProcessCpuTracker.countStats();
2420                            for (int i=0; i<N; i++) {
2421                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2422                                if (!st.working) {
2423                                    continue;
2424                                }
2425                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2426                                int otherUTime = (st.rel_utime*perc)/100;
2427                                int otherSTime = (st.rel_stime*perc)/100;
2428                                totalUTime += otherUTime;
2429                                totalSTime += otherSTime;
2430                                if (pr != null) {
2431                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2432                                    if (ps == null || !ps.isActive()) {
2433                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2434                                                pr.info.uid, pr.processName);
2435                                    }
2436                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2437                                            st.rel_stime-otherSTime);
2438                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2439                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2440                                } else {
2441                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2442                                    if (ps == null || !ps.isActive()) {
2443                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2444                                                bstats.mapUid(st.uid), st.name);
2445                                    }
2446                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2447                                            st.rel_stime-otherSTime);
2448                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2449                                }
2450                            }
2451                            bstats.finishAddingCpuLocked(perc, totalUTime,
2452                                    totalSTime, cpuSpeedTimes);
2453                        }
2454                    }
2455                }
2456
2457                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2458                    mLastWriteTime = now;
2459                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2460                }
2461            }
2462        }
2463    }
2464
2465    @Override
2466    public void batteryNeedsCpuUpdate() {
2467        updateCpuStatsNow();
2468    }
2469
2470    @Override
2471    public void batteryPowerChanged(boolean onBattery) {
2472        // When plugging in, update the CPU stats first before changing
2473        // the plug state.
2474        updateCpuStatsNow();
2475        synchronized (this) {
2476            synchronized(mPidsSelfLocked) {
2477                mOnBattery = DEBUG_POWER ? true : onBattery;
2478            }
2479        }
2480    }
2481
2482    /**
2483     * Initialize the application bind args. These are passed to each
2484     * process when the bindApplication() IPC is sent to the process. They're
2485     * lazily setup to make sure the services are running when they're asked for.
2486     */
2487    private HashMap<String, IBinder> getCommonServicesLocked() {
2488        if (mAppBindArgs == null) {
2489            mAppBindArgs = new HashMap<String, IBinder>();
2490
2491            // Setup the application init args
2492            mAppBindArgs.put("package", ServiceManager.getService("package"));
2493            mAppBindArgs.put("window", ServiceManager.getService("window"));
2494            mAppBindArgs.put(Context.ALARM_SERVICE,
2495                    ServiceManager.getService(Context.ALARM_SERVICE));
2496        }
2497        return mAppBindArgs;
2498    }
2499
2500    final void setFocusedActivityLocked(ActivityRecord r) {
2501        if (mFocusedActivity != r) {
2502            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2503            mFocusedActivity = r;
2504            if (r.task != null && r.task.voiceInteractor != null) {
2505                startRunningVoiceLocked();
2506            } else {
2507                finishRunningVoiceLocked();
2508            }
2509            mStackSupervisor.setFocusedStack(r);
2510            if (r != null) {
2511                mWindowManager.setFocusedApp(r.appToken, true);
2512            }
2513            applyUpdateLockStateLocked(r);
2514        }
2515    }
2516
2517    final void clearFocusedActivity(ActivityRecord r) {
2518        if (mFocusedActivity == r) {
2519            mFocusedActivity = null;
2520        }
2521    }
2522
2523    @Override
2524    public void setFocusedStack(int stackId) {
2525        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2526        synchronized (ActivityManagerService.this) {
2527            ActivityStack stack = mStackSupervisor.getStack(stackId);
2528            if (stack != null) {
2529                ActivityRecord r = stack.topRunningActivityLocked(null);
2530                if (r != null) {
2531                    setFocusedActivityLocked(r);
2532                }
2533            }
2534        }
2535    }
2536
2537    @Override
2538    public void notifyActivityDrawn(IBinder token) {
2539        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2540        synchronized (this) {
2541            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2542            if (r != null) {
2543                r.task.stack.notifyActivityDrawnLocked(r);
2544            }
2545        }
2546    }
2547
2548    final void applyUpdateLockStateLocked(ActivityRecord r) {
2549        // Modifications to the UpdateLock state are done on our handler, outside
2550        // the activity manager's locks.  The new state is determined based on the
2551        // state *now* of the relevant activity record.  The object is passed to
2552        // the handler solely for logging detail, not to be consulted/modified.
2553        final boolean nextState = r != null && r.immersive;
2554        mHandler.sendMessage(
2555                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2556    }
2557
2558    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2559        Message msg = Message.obtain();
2560        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2561        msg.obj = r.task.askedCompatMode ? null : r;
2562        mHandler.sendMessage(msg);
2563    }
2564
2565    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2566            String what, Object obj, ProcessRecord srcApp) {
2567        app.lastActivityTime = now;
2568
2569        if (app.activities.size() > 0) {
2570            // Don't want to touch dependent processes that are hosting activities.
2571            return index;
2572        }
2573
2574        int lrui = mLruProcesses.lastIndexOf(app);
2575        if (lrui < 0) {
2576            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2577                    + what + " " + obj + " from " + srcApp);
2578            return index;
2579        }
2580
2581        if (lrui >= index) {
2582            // Don't want to cause this to move dependent processes *back* in the
2583            // list as if they were less frequently used.
2584            return index;
2585        }
2586
2587        if (lrui >= mLruProcessActivityStart) {
2588            // Don't want to touch dependent processes that are hosting activities.
2589            return index;
2590        }
2591
2592        mLruProcesses.remove(lrui);
2593        if (index > 0) {
2594            index--;
2595        }
2596        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2597                + " in LRU list: " + app);
2598        mLruProcesses.add(index, app);
2599        return index;
2600    }
2601
2602    final void removeLruProcessLocked(ProcessRecord app) {
2603        int lrui = mLruProcesses.lastIndexOf(app);
2604        if (lrui >= 0) {
2605            if (lrui <= mLruProcessActivityStart) {
2606                mLruProcessActivityStart--;
2607            }
2608            if (lrui <= mLruProcessServiceStart) {
2609                mLruProcessServiceStart--;
2610            }
2611            mLruProcesses.remove(lrui);
2612        }
2613    }
2614
2615    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2616            ProcessRecord client) {
2617        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2618                || app.treatLikeActivity;
2619        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2620        if (!activityChange && hasActivity) {
2621            // The process has activities, so we are only allowing activity-based adjustments
2622            // to move it.  It should be kept in the front of the list with other
2623            // processes that have activities, and we don't want those to change their
2624            // order except due to activity operations.
2625            return;
2626        }
2627
2628        mLruSeq++;
2629        final long now = SystemClock.uptimeMillis();
2630        app.lastActivityTime = now;
2631
2632        // First a quick reject: if the app is already at the position we will
2633        // put it, then there is nothing to do.
2634        if (hasActivity) {
2635            final int N = mLruProcesses.size();
2636            if (N > 0 && mLruProcesses.get(N-1) == app) {
2637                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2638                return;
2639            }
2640        } else {
2641            if (mLruProcessServiceStart > 0
2642                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2643                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2644                return;
2645            }
2646        }
2647
2648        int lrui = mLruProcesses.lastIndexOf(app);
2649
2650        if (app.persistent && lrui >= 0) {
2651            // We don't care about the position of persistent processes, as long as
2652            // they are in the list.
2653            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2654            return;
2655        }
2656
2657        /* In progress: compute new position first, so we can avoid doing work
2658           if the process is not actually going to move.  Not yet working.
2659        int addIndex;
2660        int nextIndex;
2661        boolean inActivity = false, inService = false;
2662        if (hasActivity) {
2663            // Process has activities, put it at the very tipsy-top.
2664            addIndex = mLruProcesses.size();
2665            nextIndex = mLruProcessServiceStart;
2666            inActivity = true;
2667        } else if (hasService) {
2668            // Process has services, put it at the top of the service list.
2669            addIndex = mLruProcessActivityStart;
2670            nextIndex = mLruProcessServiceStart;
2671            inActivity = true;
2672            inService = true;
2673        } else  {
2674            // Process not otherwise of interest, it goes to the top of the non-service area.
2675            addIndex = mLruProcessServiceStart;
2676            if (client != null) {
2677                int clientIndex = mLruProcesses.lastIndexOf(client);
2678                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2679                        + app);
2680                if (clientIndex >= 0 && addIndex > clientIndex) {
2681                    addIndex = clientIndex;
2682                }
2683            }
2684            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2685        }
2686
2687        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2688                + mLruProcessActivityStart + "): " + app);
2689        */
2690
2691        if (lrui >= 0) {
2692            if (lrui < mLruProcessActivityStart) {
2693                mLruProcessActivityStart--;
2694            }
2695            if (lrui < mLruProcessServiceStart) {
2696                mLruProcessServiceStart--;
2697            }
2698            /*
2699            if (addIndex > lrui) {
2700                addIndex--;
2701            }
2702            if (nextIndex > lrui) {
2703                nextIndex--;
2704            }
2705            */
2706            mLruProcesses.remove(lrui);
2707        }
2708
2709        /*
2710        mLruProcesses.add(addIndex, app);
2711        if (inActivity) {
2712            mLruProcessActivityStart++;
2713        }
2714        if (inService) {
2715            mLruProcessActivityStart++;
2716        }
2717        */
2718
2719        int nextIndex;
2720        if (hasActivity) {
2721            final int N = mLruProcesses.size();
2722            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2723                // Process doesn't have activities, but has clients with
2724                // activities...  move it up, but one below the top (the top
2725                // should always have a real activity).
2726                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2727                mLruProcesses.add(N-1, app);
2728                // To keep it from spamming the LRU list (by making a bunch of clients),
2729                // we will push down any other entries owned by the app.
2730                final int uid = app.info.uid;
2731                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2732                    ProcessRecord subProc = mLruProcesses.get(i);
2733                    if (subProc.info.uid == uid) {
2734                        // We want to push this one down the list.  If the process after
2735                        // it is for the same uid, however, don't do so, because we don't
2736                        // want them internally to be re-ordered.
2737                        if (mLruProcesses.get(i-1).info.uid != uid) {
2738                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2739                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2740                            ProcessRecord tmp = mLruProcesses.get(i);
2741                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2742                            mLruProcesses.set(i-1, tmp);
2743                            i--;
2744                        }
2745                    } else {
2746                        // A gap, we can stop here.
2747                        break;
2748                    }
2749                }
2750            } else {
2751                // Process has activities, put it at the very tipsy-top.
2752                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2753                mLruProcesses.add(app);
2754            }
2755            nextIndex = mLruProcessServiceStart;
2756        } else if (hasService) {
2757            // Process has services, put it at the top of the service list.
2758            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2759            mLruProcesses.add(mLruProcessActivityStart, app);
2760            nextIndex = mLruProcessServiceStart;
2761            mLruProcessActivityStart++;
2762        } else  {
2763            // Process not otherwise of interest, it goes to the top of the non-service area.
2764            int index = mLruProcessServiceStart;
2765            if (client != null) {
2766                // If there is a client, don't allow the process to be moved up higher
2767                // in the list than that client.
2768                int clientIndex = mLruProcesses.lastIndexOf(client);
2769                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2770                        + " when updating " + app);
2771                if (clientIndex <= lrui) {
2772                    // Don't allow the client index restriction to push it down farther in the
2773                    // list than it already is.
2774                    clientIndex = lrui;
2775                }
2776                if (clientIndex >= 0 && index > clientIndex) {
2777                    index = clientIndex;
2778                }
2779            }
2780            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2781            mLruProcesses.add(index, app);
2782            nextIndex = index-1;
2783            mLruProcessActivityStart++;
2784            mLruProcessServiceStart++;
2785        }
2786
2787        // If the app is currently using a content provider or service,
2788        // bump those processes as well.
2789        for (int j=app.connections.size()-1; j>=0; j--) {
2790            ConnectionRecord cr = app.connections.valueAt(j);
2791            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2792                    && cr.binding.service.app != null
2793                    && cr.binding.service.app.lruSeq != mLruSeq
2794                    && !cr.binding.service.app.persistent) {
2795                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2796                        "service connection", cr, app);
2797            }
2798        }
2799        for (int j=app.conProviders.size()-1; j>=0; j--) {
2800            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2801            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2802                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2803                        "provider reference", cpr, app);
2804            }
2805        }
2806    }
2807
2808    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2809        if (uid == Process.SYSTEM_UID) {
2810            // The system gets to run in any process.  If there are multiple
2811            // processes with the same uid, just pick the first (this
2812            // should never happen).
2813            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2814            if (procs == null) return null;
2815            final int N = procs.size();
2816            for (int i = 0; i < N; i++) {
2817                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2818            }
2819        }
2820        ProcessRecord proc = mProcessNames.get(processName, uid);
2821        if (false && proc != null && !keepIfLarge
2822                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2823                && proc.lastCachedPss >= 4000) {
2824            // Turn this condition on to cause killing to happen regularly, for testing.
2825            if (proc.baseProcessTracker != null) {
2826                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2827            }
2828            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2829                    + "k from cached");
2830        } else if (proc != null && !keepIfLarge
2831                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2832                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2833            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2834            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2835                if (proc.baseProcessTracker != null) {
2836                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2837                }
2838                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2839                        + "k from cached");
2840            }
2841        }
2842        return proc;
2843    }
2844
2845    void ensurePackageDexOpt(String packageName) {
2846        IPackageManager pm = AppGlobals.getPackageManager();
2847        try {
2848            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2849                mDidDexOpt = true;
2850            }
2851        } catch (RemoteException e) {
2852        }
2853    }
2854
2855    boolean isNextTransitionForward() {
2856        int transit = mWindowManager.getPendingAppTransition();
2857        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2858                || transit == AppTransition.TRANSIT_TASK_OPEN
2859                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2860    }
2861
2862    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2863            String processName, String abiOverride, int uid, Runnable crashHandler) {
2864        synchronized(this) {
2865            ApplicationInfo info = new ApplicationInfo();
2866            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2867            // For isolated processes, the former contains the parent's uid and the latter the
2868            // actual uid of the isolated process.
2869            // In the special case introduced by this method (which is, starting an isolated
2870            // process directly from the SystemServer without an actual parent app process) the
2871            // closest thing to a parent's uid is SYSTEM_UID.
2872            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2873            // the |isolated| logic in the ProcessRecord constructor.
2874            info.uid = Process.SYSTEM_UID;
2875            info.processName = processName;
2876            info.className = entryPoint;
2877            info.packageName = "android";
2878            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2879                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2880                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2881                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2882                    crashHandler);
2883            return proc != null ? proc.pid : 0;
2884        }
2885    }
2886
2887    final ProcessRecord startProcessLocked(String processName,
2888            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2889            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2890            boolean isolated, boolean keepIfLarge) {
2891        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2892                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2893                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2894                null /* crashHandler */);
2895    }
2896
2897    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2898            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2899            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2900            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2901        ProcessRecord app;
2902        if (!isolated) {
2903            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2904        } else {
2905            // If this is an isolated process, it can't re-use an existing process.
2906            app = null;
2907        }
2908        // We don't have to do anything more if:
2909        // (1) There is an existing application record; and
2910        // (2) The caller doesn't think it is dead, OR there is no thread
2911        //     object attached to it so we know it couldn't have crashed; and
2912        // (3) There is a pid assigned to it, so it is either starting or
2913        //     already running.
2914        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2915                + " app=" + app + " knownToBeDead=" + knownToBeDead
2916                + " thread=" + (app != null ? app.thread : null)
2917                + " pid=" + (app != null ? app.pid : -1));
2918        if (app != null && app.pid > 0) {
2919            if (!knownToBeDead || app.thread == null) {
2920                // We already have the app running, or are waiting for it to
2921                // come up (we have a pid but not yet its thread), so keep it.
2922                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2923                // If this is a new package in the process, add the package to the list
2924                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2925                return app;
2926            }
2927
2928            // An application record is attached to a previous process,
2929            // clean it up now.
2930            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2931            Process.killProcessGroup(app.info.uid, app.pid);
2932            handleAppDiedLocked(app, true, true);
2933        }
2934
2935        String hostingNameStr = hostingName != null
2936                ? hostingName.flattenToShortString() : null;
2937
2938        if (!isolated) {
2939            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2940                // If we are in the background, then check to see if this process
2941                // is bad.  If so, we will just silently fail.
2942                if (mBadProcesses.get(info.processName, info.uid) != null) {
2943                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2944                            + "/" + info.processName);
2945                    return null;
2946                }
2947            } else {
2948                // When the user is explicitly starting a process, then clear its
2949                // crash count so that we won't make it bad until they see at
2950                // least one crash dialog again, and make the process good again
2951                // if it had been bad.
2952                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2953                        + "/" + info.processName);
2954                mProcessCrashTimes.remove(info.processName, info.uid);
2955                if (mBadProcesses.get(info.processName, info.uid) != null) {
2956                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2957                            UserHandle.getUserId(info.uid), info.uid,
2958                            info.processName);
2959                    mBadProcesses.remove(info.processName, info.uid);
2960                    if (app != null) {
2961                        app.bad = false;
2962                    }
2963                }
2964            }
2965        }
2966
2967        if (app == null) {
2968            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2969            app.crashHandler = crashHandler;
2970            if (app == null) {
2971                Slog.w(TAG, "Failed making new process record for "
2972                        + processName + "/" + info.uid + " isolated=" + isolated);
2973                return null;
2974            }
2975            mProcessNames.put(processName, app.uid, app);
2976            if (isolated) {
2977                mIsolatedProcesses.put(app.uid, app);
2978            }
2979        } else {
2980            // If this is a new package in the process, add the package to the list
2981            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2982        }
2983
2984        // If the system is not ready yet, then hold off on starting this
2985        // process until it is.
2986        if (!mProcessesReady
2987                && !isAllowedWhileBooting(info)
2988                && !allowWhileBooting) {
2989            if (!mProcessesOnHold.contains(app)) {
2990                mProcessesOnHold.add(app);
2991            }
2992            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2993            return app;
2994        }
2995
2996        startProcessLocked(
2997                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2998        return (app.pid != 0) ? app : null;
2999    }
3000
3001    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3002        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3003    }
3004
3005    private final void startProcessLocked(ProcessRecord app,
3006            String hostingType, String hostingNameStr) {
3007        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3008                null /* entryPoint */, null /* entryPointArgs */);
3009    }
3010
3011    private final void startProcessLocked(ProcessRecord app, String hostingType,
3012            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3013        if (app.pid > 0 && app.pid != MY_PID) {
3014            synchronized (mPidsSelfLocked) {
3015                mPidsSelfLocked.remove(app.pid);
3016                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3017            }
3018            app.setPid(0);
3019        }
3020
3021        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3022                "startProcessLocked removing on hold: " + app);
3023        mProcessesOnHold.remove(app);
3024
3025        updateCpuStats();
3026
3027        try {
3028            int uid = app.uid;
3029
3030            int[] gids = null;
3031            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3032            if (!app.isolated) {
3033                int[] permGids = null;
3034                try {
3035                    final PackageManager pm = mContext.getPackageManager();
3036                    permGids = pm.getPackageGids(app.info.packageName);
3037
3038                    if (Environment.isExternalStorageEmulated()) {
3039                        if (pm.checkPermission(
3040                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3041                                app.info.packageName) == PERMISSION_GRANTED) {
3042                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3043                        } else {
3044                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3045                        }
3046                    }
3047                } catch (PackageManager.NameNotFoundException e) {
3048                    Slog.w(TAG, "Unable to retrieve gids", e);
3049                }
3050
3051                /*
3052                 * Add shared application and profile GIDs so applications can share some
3053                 * resources like shared libraries and access user-wide resources
3054                 */
3055                if (permGids == null) {
3056                    gids = new int[2];
3057                } else {
3058                    gids = new int[permGids.length + 2];
3059                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3060                }
3061                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3062                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3063            }
3064            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3065                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3066                        && mTopComponent != null
3067                        && app.processName.equals(mTopComponent.getPackageName())) {
3068                    uid = 0;
3069                }
3070                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3071                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3072                    uid = 0;
3073                }
3074            }
3075            int debugFlags = 0;
3076            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3077                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3078                // Also turn on CheckJNI for debuggable apps. It's quite
3079                // awkward to turn on otherwise.
3080                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3081            }
3082            // Run the app in safe mode if its manifest requests so or the
3083            // system is booted in safe mode.
3084            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3085                mSafeMode == true) {
3086                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3087            }
3088            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3089                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3090            }
3091            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3092                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3093            }
3094            if ("1".equals(SystemProperties.get("debug.assert"))) {
3095                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3096            }
3097
3098            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3099            if (requiredAbi == null) {
3100                requiredAbi = Build.SUPPORTED_ABIS[0];
3101            }
3102
3103            // Start the process.  It will either succeed and return a result containing
3104            // the PID of the new process, or else throw a RuntimeException.
3105            boolean isActivityProcess = (entryPoint == null);
3106            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3107            Process.ProcessStartResult startResult = Process.start(entryPoint,
3108                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3109                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3110
3111            if (app.isolated) {
3112                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3113            }
3114            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3115
3116            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3117                    UserHandle.getUserId(uid), startResult.pid, uid,
3118                    app.processName, hostingType,
3119                    hostingNameStr != null ? hostingNameStr : "");
3120
3121            if (app.persistent) {
3122                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3123            }
3124
3125            StringBuilder buf = mStringBuilder;
3126            buf.setLength(0);
3127            buf.append("Start proc ");
3128            buf.append(app.processName);
3129            if (!isActivityProcess) {
3130                buf.append(" [");
3131                buf.append(entryPoint);
3132                buf.append("]");
3133            }
3134            buf.append(" for ");
3135            buf.append(hostingType);
3136            if (hostingNameStr != null) {
3137                buf.append(" ");
3138                buf.append(hostingNameStr);
3139            }
3140            buf.append(": pid=");
3141            buf.append(startResult.pid);
3142            buf.append(" uid=");
3143            buf.append(uid);
3144            buf.append(" gids={");
3145            if (gids != null) {
3146                for (int gi=0; gi<gids.length; gi++) {
3147                    if (gi != 0) buf.append(", ");
3148                    buf.append(gids[gi]);
3149
3150                }
3151            }
3152            buf.append("}");
3153            if (requiredAbi != null) {
3154                buf.append(" abi=");
3155                buf.append(requiredAbi);
3156            }
3157            Slog.i(TAG, buf.toString());
3158            app.setPid(startResult.pid);
3159            app.usingWrapper = startResult.usingWrapper;
3160            app.removed = false;
3161            app.killedByAm = false;
3162            synchronized (mPidsSelfLocked) {
3163                this.mPidsSelfLocked.put(startResult.pid, app);
3164                if (isActivityProcess) {
3165                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3166                    msg.obj = app;
3167                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3168                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3169                }
3170            }
3171        } catch (RuntimeException e) {
3172            // XXX do better error recovery.
3173            app.setPid(0);
3174            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3175            if (app.isolated) {
3176                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3177            }
3178            Slog.e(TAG, "Failure starting process " + app.processName, e);
3179        }
3180    }
3181
3182    void updateUsageStats(ActivityRecord component, boolean resumed) {
3183        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3184        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3185        if (resumed) {
3186            if (mUsageStatsService != null) {
3187                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3188                        System.currentTimeMillis(),
3189                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3190            }
3191            synchronized (stats) {
3192                stats.noteActivityResumedLocked(component.app.uid);
3193            }
3194        } else {
3195            if (mUsageStatsService != null) {
3196                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3197                        System.currentTimeMillis(),
3198                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3199            }
3200            synchronized (stats) {
3201                stats.noteActivityPausedLocked(component.app.uid);
3202            }
3203        }
3204    }
3205
3206    Intent getHomeIntent() {
3207        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3208        intent.setComponent(mTopComponent);
3209        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3210            intent.addCategory(Intent.CATEGORY_HOME);
3211        }
3212        return intent;
3213    }
3214
3215    boolean startHomeActivityLocked(int userId) {
3216        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3217                && mTopAction == null) {
3218            // We are running in factory test mode, but unable to find
3219            // the factory test app, so just sit around displaying the
3220            // error message and don't try to start anything.
3221            return false;
3222        }
3223        Intent intent = getHomeIntent();
3224        ActivityInfo aInfo =
3225            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3226        if (aInfo != null) {
3227            intent.setComponent(new ComponentName(
3228                    aInfo.applicationInfo.packageName, aInfo.name));
3229            // Don't do this if the home app is currently being
3230            // instrumented.
3231            aInfo = new ActivityInfo(aInfo);
3232            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3233            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3234                    aInfo.applicationInfo.uid, true);
3235            if (app == null || app.instrumentationClass == null) {
3236                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3237                mStackSupervisor.startHomeActivity(intent, aInfo);
3238            }
3239        }
3240
3241        return true;
3242    }
3243
3244    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3245        ActivityInfo ai = null;
3246        ComponentName comp = intent.getComponent();
3247        try {
3248            if (comp != null) {
3249                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3250            } else {
3251                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3252                        intent,
3253                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3254                            flags, userId);
3255
3256                if (info != null) {
3257                    ai = info.activityInfo;
3258                }
3259            }
3260        } catch (RemoteException e) {
3261            // ignore
3262        }
3263
3264        return ai;
3265    }
3266
3267    /**
3268     * Starts the "new version setup screen" if appropriate.
3269     */
3270    void startSetupActivityLocked() {
3271        // Only do this once per boot.
3272        if (mCheckedForSetup) {
3273            return;
3274        }
3275
3276        // We will show this screen if the current one is a different
3277        // version than the last one shown, and we are not running in
3278        // low-level factory test mode.
3279        final ContentResolver resolver = mContext.getContentResolver();
3280        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3281                Settings.Global.getInt(resolver,
3282                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3283            mCheckedForSetup = true;
3284
3285            // See if we should be showing the platform update setup UI.
3286            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3287            List<ResolveInfo> ris = mContext.getPackageManager()
3288                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3289
3290            // We don't allow third party apps to replace this.
3291            ResolveInfo ri = null;
3292            for (int i=0; ris != null && i<ris.size(); i++) {
3293                if ((ris.get(i).activityInfo.applicationInfo.flags
3294                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3295                    ri = ris.get(i);
3296                    break;
3297                }
3298            }
3299
3300            if (ri != null) {
3301                String vers = ri.activityInfo.metaData != null
3302                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3303                        : null;
3304                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3305                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3306                            Intent.METADATA_SETUP_VERSION);
3307                }
3308                String lastVers = Settings.Secure.getString(
3309                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3310                if (vers != null && !vers.equals(lastVers)) {
3311                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3312                    intent.setComponent(new ComponentName(
3313                            ri.activityInfo.packageName, ri.activityInfo.name));
3314                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3315                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3316                }
3317            }
3318        }
3319    }
3320
3321    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3322        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3323    }
3324
3325    void enforceNotIsolatedCaller(String caller) {
3326        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3327            throw new SecurityException("Isolated process not allowed to call " + caller);
3328        }
3329    }
3330
3331    @Override
3332    public int getFrontActivityScreenCompatMode() {
3333        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3334        synchronized (this) {
3335            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3336        }
3337    }
3338
3339    @Override
3340    public void setFrontActivityScreenCompatMode(int mode) {
3341        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3342                "setFrontActivityScreenCompatMode");
3343        synchronized (this) {
3344            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3345        }
3346    }
3347
3348    @Override
3349    public int getPackageScreenCompatMode(String packageName) {
3350        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3351        synchronized (this) {
3352            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3353        }
3354    }
3355
3356    @Override
3357    public void setPackageScreenCompatMode(String packageName, int mode) {
3358        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3359                "setPackageScreenCompatMode");
3360        synchronized (this) {
3361            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3362        }
3363    }
3364
3365    @Override
3366    public boolean getPackageAskScreenCompat(String packageName) {
3367        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3368        synchronized (this) {
3369            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3370        }
3371    }
3372
3373    @Override
3374    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3375        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3376                "setPackageAskScreenCompat");
3377        synchronized (this) {
3378            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3379        }
3380    }
3381
3382    private void dispatchProcessesChanged() {
3383        int N;
3384        synchronized (this) {
3385            N = mPendingProcessChanges.size();
3386            if (mActiveProcessChanges.length < N) {
3387                mActiveProcessChanges = new ProcessChangeItem[N];
3388            }
3389            mPendingProcessChanges.toArray(mActiveProcessChanges);
3390            mAvailProcessChanges.addAll(mPendingProcessChanges);
3391            mPendingProcessChanges.clear();
3392            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3393        }
3394
3395        int i = mProcessObservers.beginBroadcast();
3396        while (i > 0) {
3397            i--;
3398            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3399            if (observer != null) {
3400                try {
3401                    for (int j=0; j<N; j++) {
3402                        ProcessChangeItem item = mActiveProcessChanges[j];
3403                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3404                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3405                                    + item.pid + " uid=" + item.uid + ": "
3406                                    + item.foregroundActivities);
3407                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3408                                    item.foregroundActivities);
3409                        }
3410                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3411                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3412                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3413                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3414                        }
3415                    }
3416                } catch (RemoteException e) {
3417                }
3418            }
3419        }
3420        mProcessObservers.finishBroadcast();
3421    }
3422
3423    private void dispatchProcessDied(int pid, int uid) {
3424        int i = mProcessObservers.beginBroadcast();
3425        while (i > 0) {
3426            i--;
3427            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3428            if (observer != null) {
3429                try {
3430                    observer.onProcessDied(pid, uid);
3431                } catch (RemoteException e) {
3432                }
3433            }
3434        }
3435        mProcessObservers.finishBroadcast();
3436    }
3437
3438    @Override
3439    public final int startActivity(IApplicationThread caller, String callingPackage,
3440            Intent intent, String resolvedType, IBinder resultTo,
3441            String resultWho, int requestCode, int startFlags,
3442            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3443        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3444                resultWho, requestCode,
3445                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3446    }
3447
3448    @Override
3449    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3450            Intent intent, String resolvedType, IBinder resultTo,
3451            String resultWho, int requestCode, int startFlags,
3452            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3453        enforceNotIsolatedCaller("startActivity");
3454        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3455                false, ALLOW_FULL_ONLY, "startActivity", null);
3456        // TODO: Switch to user app stacks here.
3457        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3458                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3459                null, null, options, userId, null);
3460    }
3461
3462    @Override
3463    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3464            Intent intent, String resolvedType, IBinder resultTo,
3465            String resultWho, int requestCode, int startFlags,
3466            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3467
3468        // This is very dangerous -- it allows you to perform a start activity (including
3469        // permission grants) as any app that may launch one of your own activities.  So
3470        // we will only allow this to be done from activities that are part of the core framework,
3471        // and then only when they are running as the system.
3472        final ActivityRecord sourceRecord;
3473        final int targetUid;
3474        final String targetPackage;
3475        synchronized (this) {
3476            if (resultTo == null) {
3477                throw new SecurityException("Must be called from an activity");
3478            }
3479            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3480            if (sourceRecord == null) {
3481                throw new SecurityException("Called with bad activity token: " + resultTo);
3482            }
3483            if (!sourceRecord.info.packageName.equals("android")) {
3484                throw new SecurityException(
3485                        "Must be called from an activity that is declared in the android package");
3486            }
3487            if (sourceRecord.app == null) {
3488                throw new SecurityException("Called without a process attached to activity");
3489            }
3490            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3491                // This is still okay, as long as this activity is running under the
3492                // uid of the original calling activity.
3493                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3494                    throw new SecurityException(
3495                            "Calling activity in uid " + sourceRecord.app.uid
3496                                    + " must be system uid or original calling uid "
3497                                    + sourceRecord.launchedFromUid);
3498                }
3499            }
3500            targetUid = sourceRecord.launchedFromUid;
3501            targetPackage = sourceRecord.launchedFromPackage;
3502        }
3503
3504        // TODO: Switch to user app stacks here.
3505        try {
3506            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3507                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3508                    null, null, null, null, options, UserHandle.getUserId(targetUid), null);
3509            return ret;
3510        } catch (SecurityException e) {
3511            // XXX need to figure out how to propagate to original app.
3512            // A SecurityException here is generally actually a fault of the original
3513            // calling activity (such as a fairly granting permissions), so propagate it
3514            // back to them.
3515            /*
3516            StringBuilder msg = new StringBuilder();
3517            msg.append("While launching");
3518            msg.append(intent.toString());
3519            msg.append(": ");
3520            msg.append(e.getMessage());
3521            */
3522            throw e;
3523        }
3524    }
3525
3526    @Override
3527    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3528            Intent intent, String resolvedType, IBinder resultTo,
3529            String resultWho, int requestCode, int startFlags, String profileFile,
3530            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3531        enforceNotIsolatedCaller("startActivityAndWait");
3532        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3533                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3534        WaitResult res = new WaitResult();
3535        // TODO: Switch to user app stacks here.
3536        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3537                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3538                res, null, options, userId, null);
3539        return res;
3540    }
3541
3542    @Override
3543    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3544            Intent intent, String resolvedType, IBinder resultTo,
3545            String resultWho, int requestCode, int startFlags, Configuration config,
3546            Bundle options, int userId) {
3547        enforceNotIsolatedCaller("startActivityWithConfig");
3548        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3549                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3550        // TODO: Switch to user app stacks here.
3551        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3552                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3553                null, null, null, config, options, userId, null);
3554        return ret;
3555    }
3556
3557    @Override
3558    public int startActivityIntentSender(IApplicationThread caller,
3559            IntentSender intent, Intent fillInIntent, String resolvedType,
3560            IBinder resultTo, String resultWho, int requestCode,
3561            int flagsMask, int flagsValues, Bundle options) {
3562        enforceNotIsolatedCaller("startActivityIntentSender");
3563        // Refuse possible leaked file descriptors
3564        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3565            throw new IllegalArgumentException("File descriptors passed in Intent");
3566        }
3567
3568        IIntentSender sender = intent.getTarget();
3569        if (!(sender instanceof PendingIntentRecord)) {
3570            throw new IllegalArgumentException("Bad PendingIntent object");
3571        }
3572
3573        PendingIntentRecord pir = (PendingIntentRecord)sender;
3574
3575        synchronized (this) {
3576            // If this is coming from the currently resumed activity, it is
3577            // effectively saying that app switches are allowed at this point.
3578            final ActivityStack stack = getFocusedStack();
3579            if (stack.mResumedActivity != null &&
3580                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3581                mAppSwitchesAllowedTime = 0;
3582            }
3583        }
3584        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3585                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3586        return ret;
3587    }
3588
3589    @Override
3590    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3591            Intent intent, String resolvedType, IVoiceInteractionSession session,
3592            IVoiceInteractor interactor, int startFlags, String profileFile,
3593            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3594        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3595                != PackageManager.PERMISSION_GRANTED) {
3596            String msg = "Permission Denial: startVoiceActivity() from pid="
3597                    + Binder.getCallingPid()
3598                    + ", uid=" + Binder.getCallingUid()
3599                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3600            Slog.w(TAG, msg);
3601            throw new SecurityException(msg);
3602        }
3603        if (session == null || interactor == null) {
3604            throw new NullPointerException("null session or interactor");
3605        }
3606        userId = handleIncomingUser(callingPid, callingUid, userId,
3607                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3608        // TODO: Switch to user app stacks here.
3609        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3610                resolvedType, session, interactor, null, null, 0, startFlags,
3611                profileFile, profileFd, null, null, options, userId, null);
3612    }
3613
3614    @Override
3615    public boolean startNextMatchingActivity(IBinder callingActivity,
3616            Intent intent, Bundle options) {
3617        // Refuse possible leaked file descriptors
3618        if (intent != null && intent.hasFileDescriptors() == true) {
3619            throw new IllegalArgumentException("File descriptors passed in Intent");
3620        }
3621
3622        synchronized (this) {
3623            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3624            if (r == null) {
3625                ActivityOptions.abort(options);
3626                return false;
3627            }
3628            if (r.app == null || r.app.thread == null) {
3629                // The caller is not running...  d'oh!
3630                ActivityOptions.abort(options);
3631                return false;
3632            }
3633            intent = new Intent(intent);
3634            // The caller is not allowed to change the data.
3635            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3636            // And we are resetting to find the next component...
3637            intent.setComponent(null);
3638
3639            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3640
3641            ActivityInfo aInfo = null;
3642            try {
3643                List<ResolveInfo> resolves =
3644                    AppGlobals.getPackageManager().queryIntentActivities(
3645                            intent, r.resolvedType,
3646                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3647                            UserHandle.getCallingUserId());
3648
3649                // Look for the original activity in the list...
3650                final int N = resolves != null ? resolves.size() : 0;
3651                for (int i=0; i<N; i++) {
3652                    ResolveInfo rInfo = resolves.get(i);
3653                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3654                            && rInfo.activityInfo.name.equals(r.info.name)) {
3655                        // We found the current one...  the next matching is
3656                        // after it.
3657                        i++;
3658                        if (i<N) {
3659                            aInfo = resolves.get(i).activityInfo;
3660                        }
3661                        if (debug) {
3662                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3663                                    + "/" + r.info.name);
3664                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3665                                    + "/" + aInfo.name);
3666                        }
3667                        break;
3668                    }
3669                }
3670            } catch (RemoteException e) {
3671            }
3672
3673            if (aInfo == null) {
3674                // Nobody who is next!
3675                ActivityOptions.abort(options);
3676                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3677                return false;
3678            }
3679
3680            intent.setComponent(new ComponentName(
3681                    aInfo.applicationInfo.packageName, aInfo.name));
3682            intent.setFlags(intent.getFlags()&~(
3683                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3684                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3685                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3686                    Intent.FLAG_ACTIVITY_NEW_TASK));
3687
3688            // Okay now we need to start the new activity, replacing the
3689            // currently running activity.  This is a little tricky because
3690            // we want to start the new one as if the current one is finished,
3691            // but not finish the current one first so that there is no flicker.
3692            // And thus...
3693            final boolean wasFinishing = r.finishing;
3694            r.finishing = true;
3695
3696            // Propagate reply information over to the new activity.
3697            final ActivityRecord resultTo = r.resultTo;
3698            final String resultWho = r.resultWho;
3699            final int requestCode = r.requestCode;
3700            r.resultTo = null;
3701            if (resultTo != null) {
3702                resultTo.removeResultsLocked(r, resultWho, requestCode);
3703            }
3704
3705            final long origId = Binder.clearCallingIdentity();
3706            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3707                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3708                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3709                    options, false, null, null);
3710            Binder.restoreCallingIdentity(origId);
3711
3712            r.finishing = wasFinishing;
3713            if (res != ActivityManager.START_SUCCESS) {
3714                return false;
3715            }
3716            return true;
3717        }
3718    }
3719
3720    @Override
3721    public final int startActivityFromRecents(int taskId, Bundle options) {
3722        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3723            String msg = "Permission Denial: startActivityFromRecents called without " +
3724                    START_TASKS_FROM_RECENTS;
3725            Slog.w(TAG, msg);
3726            throw new SecurityException(msg);
3727        }
3728        final int callingUid;
3729        final String callingPackage;
3730        final Intent intent;
3731        final int userId;
3732        synchronized (this) {
3733            final TaskRecord task = recentTaskForIdLocked(taskId);
3734            if (task == null) {
3735                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3736            }
3737            callingUid = task.mCallingUid;
3738            callingPackage = task.mCallingPackage;
3739            intent = task.intent;
3740            userId = task.userId;
3741        }
3742        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3743                options, userId, null);
3744    }
3745
3746    final int startActivityInPackage(int uid, String callingPackage,
3747            Intent intent, String resolvedType, IBinder resultTo,
3748            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3749                    IActivityContainer container) {
3750
3751        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3752                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3753
3754        // TODO: Switch to user app stacks here.
3755        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3756                null, null, resultTo, resultWho, requestCode, startFlags,
3757                null, null, null, null, options, userId, container);
3758        return ret;
3759    }
3760
3761    @Override
3762    public final int startActivities(IApplicationThread caller, String callingPackage,
3763            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3764            int userId) {
3765        enforceNotIsolatedCaller("startActivities");
3766        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3767                false, ALLOW_FULL_ONLY, "startActivity", null);
3768        // TODO: Switch to user app stacks here.
3769        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3770                resolvedTypes, resultTo, options, userId);
3771        return ret;
3772    }
3773
3774    final int startActivitiesInPackage(int uid, String callingPackage,
3775            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3776            Bundle options, int userId) {
3777
3778        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3779                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3780        // TODO: Switch to user app stacks here.
3781        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3782                resultTo, options, userId);
3783        return ret;
3784    }
3785
3786    //explicitly remove thd old information in mRecentTasks when removing existing user.
3787    private void removeRecentTasksForUserLocked(int userId) {
3788        if(userId <= 0) {
3789            Slog.i(TAG, "Can't remove recent task on user " + userId);
3790            return;
3791        }
3792
3793        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3794            TaskRecord tr = mRecentTasks.get(i);
3795            if (tr.userId == userId) {
3796                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3797                        + " when finishing user" + userId);
3798                tr.disposeThumbnail();
3799                mRecentTasks.remove(i);
3800            }
3801        }
3802
3803        // Remove tasks from persistent storage.
3804        mTaskPersister.wakeup(null, true);
3805    }
3806
3807    final void addRecentTaskLocked(TaskRecord task) {
3808        final int N = mRecentTasks.size();
3809        // Quick case: check if the top-most recent task is the same.
3810        if (N > 0 && mRecentTasks.get(0) == task) {
3811            return;
3812        }
3813        // Another quick case: never add voice sessions.
3814        if (task.voiceSession != null) {
3815            return;
3816        }
3817
3818        trimRecentsForTask(task, true);
3819
3820        if (N >= MAX_RECENT_TASKS) {
3821            final TaskRecord tr = mRecentTasks.remove(N - 1);
3822            tr.disposeThumbnail();
3823            tr.closeRecentsChain();
3824        }
3825        mRecentTasks.add(0, task);
3826    }
3827
3828    /**
3829     * If needed, remove oldest existing entries in recents that are for the same kind
3830     * of task as the given one.
3831     */
3832    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
3833        int N = mRecentTasks.size();
3834        final Intent intent = task.intent;
3835        final boolean document = intent != null && intent.isDocument();
3836
3837        int maxRecents = task.maxRecents - 1;
3838        for (int i=0; i<N; i++) {
3839            final TaskRecord tr = mRecentTasks.get(i);
3840            if (task != tr) {
3841                if (task.userId != tr.userId) {
3842                    continue;
3843                }
3844                if (i > MAX_RECENT_BITMAPS) {
3845                    tr.freeLastThumbnail();
3846                }
3847                final Intent trIntent = tr.intent;
3848                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3849                    (intent == null || !intent.filterEquals(trIntent))) {
3850                    continue;
3851                }
3852                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3853                if (document && trIsDocument) {
3854                    // These are the same document activity (not necessarily the same doc).
3855                    if (maxRecents > 0) {
3856                        --maxRecents;
3857                        continue;
3858                    }
3859                    // Hit the maximum number of documents for this task. Fall through
3860                    // and remove this document from recents.
3861                } else if (document || trIsDocument) {
3862                    // Only one of these is a document. Not the droid we're looking for.
3863                    continue;
3864                }
3865            }
3866
3867            if (!doTrim) {
3868                // If the caller is not actually asking for a trim, just tell them we reached
3869                // a point where the trim would happen.
3870                return i;
3871            }
3872
3873            // Either task and tr are the same or, their affinities match or their intents match
3874            // and neither of them is a document, or they are documents using the same activity
3875            // and their maxRecents has been reached.
3876            tr.disposeThumbnail();
3877            mRecentTasks.remove(i);
3878            if (task != tr) {
3879                tr.closeRecentsChain();
3880            }
3881            i--;
3882            N--;
3883            if (task.intent == null) {
3884                // If the new recent task we are adding is not fully
3885                // specified, then replace it with the existing recent task.
3886                task = tr;
3887            }
3888            notifyTaskPersisterLocked(tr, false);
3889        }
3890
3891        return -1;
3892    }
3893
3894    @Override
3895    public void reportActivityFullyDrawn(IBinder token) {
3896        synchronized (this) {
3897            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3898            if (r == null) {
3899                return;
3900            }
3901            r.reportFullyDrawnLocked();
3902        }
3903    }
3904
3905    @Override
3906    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3907        synchronized (this) {
3908            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3909            if (r == null) {
3910                return;
3911            }
3912            final long origId = Binder.clearCallingIdentity();
3913            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3914            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3915                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3916            if (config != null) {
3917                r.frozenBeforeDestroy = true;
3918                if (!updateConfigurationLocked(config, r, false, false)) {
3919                    mStackSupervisor.resumeTopActivitiesLocked();
3920                }
3921            }
3922            Binder.restoreCallingIdentity(origId);
3923        }
3924    }
3925
3926    @Override
3927    public int getRequestedOrientation(IBinder token) {
3928        synchronized (this) {
3929            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3930            if (r == null) {
3931                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3932            }
3933            return mWindowManager.getAppOrientation(r.appToken);
3934        }
3935    }
3936
3937    /**
3938     * This is the internal entry point for handling Activity.finish().
3939     *
3940     * @param token The Binder token referencing the Activity we want to finish.
3941     * @param resultCode Result code, if any, from this Activity.
3942     * @param resultData Result data (Intent), if any, from this Activity.
3943     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3944     *            the root Activity in the task.
3945     *
3946     * @return Returns true if the activity successfully finished, or false if it is still running.
3947     */
3948    @Override
3949    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3950            boolean finishTask) {
3951        // Refuse possible leaked file descriptors
3952        if (resultData != null && resultData.hasFileDescriptors() == true) {
3953            throw new IllegalArgumentException("File descriptors passed in Intent");
3954        }
3955
3956        synchronized(this) {
3957            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3958            if (r == null) {
3959                return true;
3960            }
3961            // Keep track of the root activity of the task before we finish it
3962            TaskRecord tr = r.task;
3963            ActivityRecord rootR = tr.getRootActivity();
3964            // Do not allow task to finish in Lock Task mode.
3965            if (tr == mStackSupervisor.mLockTaskModeTask) {
3966                if (rootR == r) {
3967                    mStackSupervisor.showLockTaskToast();
3968                    return false;
3969                }
3970            }
3971            if (mController != null) {
3972                // Find the first activity that is not finishing.
3973                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3974                if (next != null) {
3975                    // ask watcher if this is allowed
3976                    boolean resumeOK = true;
3977                    try {
3978                        resumeOK = mController.activityResuming(next.packageName);
3979                    } catch (RemoteException e) {
3980                        mController = null;
3981                        Watchdog.getInstance().setActivityController(null);
3982                    }
3983
3984                    if (!resumeOK) {
3985                        return false;
3986                    }
3987                }
3988            }
3989            final long origId = Binder.clearCallingIdentity();
3990            try {
3991                boolean res;
3992                if (finishTask && r == rootR) {
3993                    // If requested, remove the task that is associated to this activity only if it
3994                    // was the root activity in the task.  The result code and data is ignored because
3995                    // we don't support returning them across task boundaries.
3996                    res = removeTaskByIdLocked(tr.taskId, 0);
3997                } else {
3998                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3999                            resultData, "app-request", true);
4000                }
4001                return res;
4002            } finally {
4003                Binder.restoreCallingIdentity(origId);
4004            }
4005        }
4006    }
4007
4008    @Override
4009    public final void finishHeavyWeightApp() {
4010        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4011                != PackageManager.PERMISSION_GRANTED) {
4012            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4013                    + Binder.getCallingPid()
4014                    + ", uid=" + Binder.getCallingUid()
4015                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4016            Slog.w(TAG, msg);
4017            throw new SecurityException(msg);
4018        }
4019
4020        synchronized(this) {
4021            if (mHeavyWeightProcess == null) {
4022                return;
4023            }
4024
4025            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4026                    mHeavyWeightProcess.activities);
4027            for (int i=0; i<activities.size(); i++) {
4028                ActivityRecord r = activities.get(i);
4029                if (!r.finishing) {
4030                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4031                            null, "finish-heavy", true);
4032                }
4033            }
4034
4035            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4036                    mHeavyWeightProcess.userId, 0));
4037            mHeavyWeightProcess = null;
4038        }
4039    }
4040
4041    @Override
4042    public void crashApplication(int uid, int initialPid, String packageName,
4043            String message) {
4044        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4045                != PackageManager.PERMISSION_GRANTED) {
4046            String msg = "Permission Denial: crashApplication() from pid="
4047                    + Binder.getCallingPid()
4048                    + ", uid=" + Binder.getCallingUid()
4049                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4050            Slog.w(TAG, msg);
4051            throw new SecurityException(msg);
4052        }
4053
4054        synchronized(this) {
4055            ProcessRecord proc = null;
4056
4057            // Figure out which process to kill.  We don't trust that initialPid
4058            // still has any relation to current pids, so must scan through the
4059            // list.
4060            synchronized (mPidsSelfLocked) {
4061                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4062                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4063                    if (p.uid != uid) {
4064                        continue;
4065                    }
4066                    if (p.pid == initialPid) {
4067                        proc = p;
4068                        break;
4069                    }
4070                    if (p.pkgList.containsKey(packageName)) {
4071                        proc = p;
4072                    }
4073                }
4074            }
4075
4076            if (proc == null) {
4077                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4078                        + " initialPid=" + initialPid
4079                        + " packageName=" + packageName);
4080                return;
4081            }
4082
4083            if (proc.thread != null) {
4084                if (proc.pid == Process.myPid()) {
4085                    Log.w(TAG, "crashApplication: trying to crash self!");
4086                    return;
4087                }
4088                long ident = Binder.clearCallingIdentity();
4089                try {
4090                    proc.thread.scheduleCrash(message);
4091                } catch (RemoteException e) {
4092                }
4093                Binder.restoreCallingIdentity(ident);
4094            }
4095        }
4096    }
4097
4098    @Override
4099    public final void finishSubActivity(IBinder token, String resultWho,
4100            int requestCode) {
4101        synchronized(this) {
4102            final long origId = Binder.clearCallingIdentity();
4103            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4104            if (r != null) {
4105                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4106            }
4107            Binder.restoreCallingIdentity(origId);
4108        }
4109    }
4110
4111    @Override
4112    public boolean finishActivityAffinity(IBinder token) {
4113        synchronized(this) {
4114            final long origId = Binder.clearCallingIdentity();
4115            try {
4116                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4117
4118                ActivityRecord rootR = r.task.getRootActivity();
4119                // Do not allow task to finish in Lock Task mode.
4120                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4121                    if (rootR == r) {
4122                        mStackSupervisor.showLockTaskToast();
4123                        return false;
4124                    }
4125                }
4126                boolean res = false;
4127                if (r != null) {
4128                    res = r.task.stack.finishActivityAffinityLocked(r);
4129                }
4130                return res;
4131            } finally {
4132                Binder.restoreCallingIdentity(origId);
4133            }
4134        }
4135    }
4136
4137    @Override
4138    public void finishVoiceTask(IVoiceInteractionSession session) {
4139        synchronized(this) {
4140            final long origId = Binder.clearCallingIdentity();
4141            try {
4142                mStackSupervisor.finishVoiceTask(session);
4143            } finally {
4144                Binder.restoreCallingIdentity(origId);
4145            }
4146        }
4147
4148    }
4149
4150    @Override
4151    public boolean willActivityBeVisible(IBinder token) {
4152        synchronized(this) {
4153            ActivityStack stack = ActivityRecord.getStackLocked(token);
4154            if (stack != null) {
4155                return stack.willActivityBeVisibleLocked(token);
4156            }
4157            return false;
4158        }
4159    }
4160
4161    @Override
4162    public void overridePendingTransition(IBinder token, String packageName,
4163            int enterAnim, int exitAnim) {
4164        synchronized(this) {
4165            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4166            if (self == null) {
4167                return;
4168            }
4169
4170            final long origId = Binder.clearCallingIdentity();
4171
4172            if (self.state == ActivityState.RESUMED
4173                    || self.state == ActivityState.PAUSING) {
4174                mWindowManager.overridePendingAppTransition(packageName,
4175                        enterAnim, exitAnim, null);
4176            }
4177
4178            Binder.restoreCallingIdentity(origId);
4179        }
4180    }
4181
4182    /**
4183     * Main function for removing an existing process from the activity manager
4184     * as a result of that process going away.  Clears out all connections
4185     * to the process.
4186     */
4187    private final void handleAppDiedLocked(ProcessRecord app,
4188            boolean restarting, boolean allowRestart) {
4189        int pid = app.pid;
4190        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4191        if (!restarting) {
4192            removeLruProcessLocked(app);
4193            if (pid > 0) {
4194                ProcessList.remove(pid);
4195            }
4196        }
4197
4198        if (mProfileProc == app) {
4199            clearProfilerLocked();
4200        }
4201
4202        // Remove this application's activities from active lists.
4203        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4204
4205        app.activities.clear();
4206
4207        if (app.instrumentationClass != null) {
4208            Slog.w(TAG, "Crash of app " + app.processName
4209                  + " running instrumentation " + app.instrumentationClass);
4210            Bundle info = new Bundle();
4211            info.putString("shortMsg", "Process crashed.");
4212            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4213        }
4214
4215        if (!restarting) {
4216            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4217                // If there was nothing to resume, and we are not already
4218                // restarting this process, but there is a visible activity that
4219                // is hosted by the process...  then make sure all visible
4220                // activities are running, taking care of restarting this
4221                // process.
4222                if (hasVisibleActivities) {
4223                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4224                }
4225            }
4226        }
4227    }
4228
4229    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4230        IBinder threadBinder = thread.asBinder();
4231        // Find the application record.
4232        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4233            ProcessRecord rec = mLruProcesses.get(i);
4234            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4235                return i;
4236            }
4237        }
4238        return -1;
4239    }
4240
4241    final ProcessRecord getRecordForAppLocked(
4242            IApplicationThread thread) {
4243        if (thread == null) {
4244            return null;
4245        }
4246
4247        int appIndex = getLRURecordIndexForAppLocked(thread);
4248        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4249    }
4250
4251    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4252        // If there are no longer any background processes running,
4253        // and the app that died was not running instrumentation,
4254        // then tell everyone we are now low on memory.
4255        boolean haveBg = false;
4256        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4257            ProcessRecord rec = mLruProcesses.get(i);
4258            if (rec.thread != null
4259                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4260                haveBg = true;
4261                break;
4262            }
4263        }
4264
4265        if (!haveBg) {
4266            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4267            if (doReport) {
4268                long now = SystemClock.uptimeMillis();
4269                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4270                    doReport = false;
4271                } else {
4272                    mLastMemUsageReportTime = now;
4273                }
4274            }
4275            final ArrayList<ProcessMemInfo> memInfos
4276                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4277            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4278            long now = SystemClock.uptimeMillis();
4279            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4280                ProcessRecord rec = mLruProcesses.get(i);
4281                if (rec == dyingProc || rec.thread == null) {
4282                    continue;
4283                }
4284                if (doReport) {
4285                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4286                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4287                }
4288                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4289                    // The low memory report is overriding any current
4290                    // state for a GC request.  Make sure to do
4291                    // heavy/important/visible/foreground processes first.
4292                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4293                        rec.lastRequestedGc = 0;
4294                    } else {
4295                        rec.lastRequestedGc = rec.lastLowMemory;
4296                    }
4297                    rec.reportLowMemory = true;
4298                    rec.lastLowMemory = now;
4299                    mProcessesToGc.remove(rec);
4300                    addProcessToGcListLocked(rec);
4301                }
4302            }
4303            if (doReport) {
4304                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4305                mHandler.sendMessage(msg);
4306            }
4307            scheduleAppGcsLocked();
4308        }
4309    }
4310
4311    final void appDiedLocked(ProcessRecord app) {
4312       appDiedLocked(app, app.pid, app.thread);
4313    }
4314
4315    final void appDiedLocked(ProcessRecord app, int pid,
4316            IApplicationThread thread) {
4317
4318        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4319        synchronized (stats) {
4320            stats.noteProcessDiedLocked(app.info.uid, pid);
4321        }
4322
4323        Process.killProcessGroup(app.info.uid, pid);
4324
4325        // Clean up already done if the process has been re-started.
4326        if (app.pid == pid && app.thread != null &&
4327                app.thread.asBinder() == thread.asBinder()) {
4328            boolean doLowMem = app.instrumentationClass == null;
4329            boolean doOomAdj = doLowMem;
4330            if (!app.killedByAm) {
4331                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4332                        + ") has died.");
4333                mAllowLowerMemLevel = true;
4334            } else {
4335                // Note that we always want to do oom adj to update our state with the
4336                // new number of procs.
4337                mAllowLowerMemLevel = false;
4338                doLowMem = false;
4339            }
4340            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4341            if (DEBUG_CLEANUP) Slog.v(
4342                TAG, "Dying app: " + app + ", pid: " + pid
4343                + ", thread: " + thread.asBinder());
4344            handleAppDiedLocked(app, false, true);
4345
4346            if (doOomAdj) {
4347                updateOomAdjLocked();
4348            }
4349            if (doLowMem) {
4350                doLowMemReportIfNeededLocked(app);
4351            }
4352        } else if (app.pid != pid) {
4353            // A new process has already been started.
4354            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4355                    + ") has died and restarted (pid " + app.pid + ").");
4356            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4357        } else if (DEBUG_PROCESSES) {
4358            Slog.d(TAG, "Received spurious death notification for thread "
4359                    + thread.asBinder());
4360        }
4361    }
4362
4363    /**
4364     * If a stack trace dump file is configured, dump process stack traces.
4365     * @param clearTraces causes the dump file to be erased prior to the new
4366     *    traces being written, if true; when false, the new traces will be
4367     *    appended to any existing file content.
4368     * @param firstPids of dalvik VM processes to dump stack traces for first
4369     * @param lastPids of dalvik VM processes to dump stack traces for last
4370     * @param nativeProcs optional list of native process names to dump stack crawls
4371     * @return file containing stack traces, or null if no dump file is configured
4372     */
4373    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4374            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4375        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4376        if (tracesPath == null || tracesPath.length() == 0) {
4377            return null;
4378        }
4379
4380        File tracesFile = new File(tracesPath);
4381        try {
4382            File tracesDir = tracesFile.getParentFile();
4383            if (!tracesDir.exists()) {
4384                tracesFile.mkdirs();
4385                if (!SELinux.restorecon(tracesDir)) {
4386                    return null;
4387                }
4388            }
4389            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4390
4391            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4392            tracesFile.createNewFile();
4393            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4394        } catch (IOException e) {
4395            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4396            return null;
4397        }
4398
4399        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4400        return tracesFile;
4401    }
4402
4403    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4404            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4405        // Use a FileObserver to detect when traces finish writing.
4406        // The order of traces is considered important to maintain for legibility.
4407        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4408            @Override
4409            public synchronized void onEvent(int event, String path) { notify(); }
4410        };
4411
4412        try {
4413            observer.startWatching();
4414
4415            // First collect all of the stacks of the most important pids.
4416            if (firstPids != null) {
4417                try {
4418                    int num = firstPids.size();
4419                    for (int i = 0; i < num; i++) {
4420                        synchronized (observer) {
4421                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4422                            observer.wait(200);  // Wait for write-close, give up after 200msec
4423                        }
4424                    }
4425                } catch (InterruptedException e) {
4426                    Log.wtf(TAG, e);
4427                }
4428            }
4429
4430            // Next collect the stacks of the native pids
4431            if (nativeProcs != null) {
4432                int[] pids = Process.getPidsForCommands(nativeProcs);
4433                if (pids != null) {
4434                    for (int pid : pids) {
4435                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4436                    }
4437                }
4438            }
4439
4440            // Lastly, measure CPU usage.
4441            if (processCpuTracker != null) {
4442                processCpuTracker.init();
4443                System.gc();
4444                processCpuTracker.update();
4445                try {
4446                    synchronized (processCpuTracker) {
4447                        processCpuTracker.wait(500); // measure over 1/2 second.
4448                    }
4449                } catch (InterruptedException e) {
4450                }
4451                processCpuTracker.update();
4452
4453                // We'll take the stack crawls of just the top apps using CPU.
4454                final int N = processCpuTracker.countWorkingStats();
4455                int numProcs = 0;
4456                for (int i=0; i<N && numProcs<5; i++) {
4457                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4458                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4459                        numProcs++;
4460                        try {
4461                            synchronized (observer) {
4462                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4463                                observer.wait(200);  // Wait for write-close, give up after 200msec
4464                            }
4465                        } catch (InterruptedException e) {
4466                            Log.wtf(TAG, e);
4467                        }
4468
4469                    }
4470                }
4471            }
4472        } finally {
4473            observer.stopWatching();
4474        }
4475    }
4476
4477    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4478        if (true || IS_USER_BUILD) {
4479            return;
4480        }
4481        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4482        if (tracesPath == null || tracesPath.length() == 0) {
4483            return;
4484        }
4485
4486        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4487        StrictMode.allowThreadDiskWrites();
4488        try {
4489            final File tracesFile = new File(tracesPath);
4490            final File tracesDir = tracesFile.getParentFile();
4491            final File tracesTmp = new File(tracesDir, "__tmp__");
4492            try {
4493                if (!tracesDir.exists()) {
4494                    tracesFile.mkdirs();
4495                    if (!SELinux.restorecon(tracesDir.getPath())) {
4496                        return;
4497                    }
4498                }
4499                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4500
4501                if (tracesFile.exists()) {
4502                    tracesTmp.delete();
4503                    tracesFile.renameTo(tracesTmp);
4504                }
4505                StringBuilder sb = new StringBuilder();
4506                Time tobj = new Time();
4507                tobj.set(System.currentTimeMillis());
4508                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4509                sb.append(": ");
4510                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4511                sb.append(" since ");
4512                sb.append(msg);
4513                FileOutputStream fos = new FileOutputStream(tracesFile);
4514                fos.write(sb.toString().getBytes());
4515                if (app == null) {
4516                    fos.write("\n*** No application process!".getBytes());
4517                }
4518                fos.close();
4519                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4520            } catch (IOException e) {
4521                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4522                return;
4523            }
4524
4525            if (app != null) {
4526                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4527                firstPids.add(app.pid);
4528                dumpStackTraces(tracesPath, firstPids, null, null, null);
4529            }
4530
4531            File lastTracesFile = null;
4532            File curTracesFile = null;
4533            for (int i=9; i>=0; i--) {
4534                String name = String.format(Locale.US, "slow%02d.txt", i);
4535                curTracesFile = new File(tracesDir, name);
4536                if (curTracesFile.exists()) {
4537                    if (lastTracesFile != null) {
4538                        curTracesFile.renameTo(lastTracesFile);
4539                    } else {
4540                        curTracesFile.delete();
4541                    }
4542                }
4543                lastTracesFile = curTracesFile;
4544            }
4545            tracesFile.renameTo(curTracesFile);
4546            if (tracesTmp.exists()) {
4547                tracesTmp.renameTo(tracesFile);
4548            }
4549        } finally {
4550            StrictMode.setThreadPolicy(oldPolicy);
4551        }
4552    }
4553
4554    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4555            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4556        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4557        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4558
4559        if (mController != null) {
4560            try {
4561                // 0 == continue, -1 = kill process immediately
4562                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4563                if (res < 0 && app.pid != MY_PID) {
4564                    Process.killProcess(app.pid);
4565                    Process.killProcessGroup(app.info.uid, app.pid);
4566                }
4567            } catch (RemoteException e) {
4568                mController = null;
4569                Watchdog.getInstance().setActivityController(null);
4570            }
4571        }
4572
4573        long anrTime = SystemClock.uptimeMillis();
4574        if (MONITOR_CPU_USAGE) {
4575            updateCpuStatsNow();
4576        }
4577
4578        synchronized (this) {
4579            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4580            if (mShuttingDown) {
4581                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4582                return;
4583            } else if (app.notResponding) {
4584                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4585                return;
4586            } else if (app.crashing) {
4587                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4588                return;
4589            }
4590
4591            // In case we come through here for the same app before completing
4592            // this one, mark as anring now so we will bail out.
4593            app.notResponding = true;
4594
4595            // Log the ANR to the event log.
4596            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4597                    app.processName, app.info.flags, annotation);
4598
4599            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4600            firstPids.add(app.pid);
4601
4602            int parentPid = app.pid;
4603            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4604            if (parentPid != app.pid) firstPids.add(parentPid);
4605
4606            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4607
4608            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4609                ProcessRecord r = mLruProcesses.get(i);
4610                if (r != null && r.thread != null) {
4611                    int pid = r.pid;
4612                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4613                        if (r.persistent) {
4614                            firstPids.add(pid);
4615                        } else {
4616                            lastPids.put(pid, Boolean.TRUE);
4617                        }
4618                    }
4619                }
4620            }
4621        }
4622
4623        // Log the ANR to the main log.
4624        StringBuilder info = new StringBuilder();
4625        info.setLength(0);
4626        info.append("ANR in ").append(app.processName);
4627        if (activity != null && activity.shortComponentName != null) {
4628            info.append(" (").append(activity.shortComponentName).append(")");
4629        }
4630        info.append("\n");
4631        info.append("PID: ").append(app.pid).append("\n");
4632        if (annotation != null) {
4633            info.append("Reason: ").append(annotation).append("\n");
4634        }
4635        if (parent != null && parent != activity) {
4636            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4637        }
4638
4639        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4640
4641        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4642                NATIVE_STACKS_OF_INTEREST);
4643
4644        String cpuInfo = null;
4645        if (MONITOR_CPU_USAGE) {
4646            updateCpuStatsNow();
4647            synchronized (mProcessCpuThread) {
4648                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4649            }
4650            info.append(processCpuTracker.printCurrentLoad());
4651            info.append(cpuInfo);
4652        }
4653
4654        info.append(processCpuTracker.printCurrentState(anrTime));
4655
4656        Slog.e(TAG, info.toString());
4657        if (tracesFile == null) {
4658            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4659            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4660        }
4661
4662        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4663                cpuInfo, tracesFile, null);
4664
4665        if (mController != null) {
4666            try {
4667                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4668                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4669                if (res != 0) {
4670                    if (res < 0 && app.pid != MY_PID) {
4671                        Process.killProcess(app.pid);
4672                        Process.killProcessGroup(app.info.uid, app.pid);
4673                    } else {
4674                        synchronized (this) {
4675                            mServices.scheduleServiceTimeoutLocked(app);
4676                        }
4677                    }
4678                    return;
4679                }
4680            } catch (RemoteException e) {
4681                mController = null;
4682                Watchdog.getInstance().setActivityController(null);
4683            }
4684        }
4685
4686        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4687        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4688                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4689
4690        synchronized (this) {
4691            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4692                killUnneededProcessLocked(app, "background ANR");
4693                return;
4694            }
4695
4696            // Set the app's notResponding state, and look up the errorReportReceiver
4697            makeAppNotRespondingLocked(app,
4698                    activity != null ? activity.shortComponentName : null,
4699                    annotation != null ? "ANR " + annotation : "ANR",
4700                    info.toString());
4701
4702            // Bring up the infamous App Not Responding dialog
4703            Message msg = Message.obtain();
4704            HashMap<String, Object> map = new HashMap<String, Object>();
4705            msg.what = SHOW_NOT_RESPONDING_MSG;
4706            msg.obj = map;
4707            msg.arg1 = aboveSystem ? 1 : 0;
4708            map.put("app", app);
4709            if (activity != null) {
4710                map.put("activity", activity);
4711            }
4712
4713            mHandler.sendMessage(msg);
4714        }
4715    }
4716
4717    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4718        if (!mLaunchWarningShown) {
4719            mLaunchWarningShown = true;
4720            mHandler.post(new Runnable() {
4721                @Override
4722                public void run() {
4723                    synchronized (ActivityManagerService.this) {
4724                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4725                        d.show();
4726                        mHandler.postDelayed(new Runnable() {
4727                            @Override
4728                            public void run() {
4729                                synchronized (ActivityManagerService.this) {
4730                                    d.dismiss();
4731                                    mLaunchWarningShown = false;
4732                                }
4733                            }
4734                        }, 4000);
4735                    }
4736                }
4737            });
4738        }
4739    }
4740
4741    @Override
4742    public boolean clearApplicationUserData(final String packageName,
4743            final IPackageDataObserver observer, int userId) {
4744        enforceNotIsolatedCaller("clearApplicationUserData");
4745        int uid = Binder.getCallingUid();
4746        int pid = Binder.getCallingPid();
4747        userId = handleIncomingUser(pid, uid,
4748                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4749        long callingId = Binder.clearCallingIdentity();
4750        try {
4751            IPackageManager pm = AppGlobals.getPackageManager();
4752            int pkgUid = -1;
4753            synchronized(this) {
4754                try {
4755                    pkgUid = pm.getPackageUid(packageName, userId);
4756                } catch (RemoteException e) {
4757                }
4758                if (pkgUid == -1) {
4759                    Slog.w(TAG, "Invalid packageName: " + packageName);
4760                    if (observer != null) {
4761                        try {
4762                            observer.onRemoveCompleted(packageName, false);
4763                        } catch (RemoteException e) {
4764                            Slog.i(TAG, "Observer no longer exists.");
4765                        }
4766                    }
4767                    return false;
4768                }
4769                if (uid == pkgUid || checkComponentPermission(
4770                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4771                        pid, uid, -1, true)
4772                        == PackageManager.PERMISSION_GRANTED) {
4773                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4774                } else {
4775                    throw new SecurityException("PID " + pid + " does not have permission "
4776                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4777                                    + " of package " + packageName);
4778                }
4779
4780                // Remove all tasks match the cleared application package and user
4781                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4782                    final TaskRecord tr = mRecentTasks.get(i);
4783                    final String taskPackageName =
4784                            tr.getBaseIntent().getComponent().getPackageName();
4785                    if (tr.userId != userId) continue;
4786                    if (!taskPackageName.equals(packageName)) continue;
4787                    removeTaskByIdLocked(tr.taskId, 0);
4788                }
4789            }
4790
4791            try {
4792                // Clear application user data
4793                pm.clearApplicationUserData(packageName, observer, userId);
4794
4795                synchronized(this) {
4796                    // Remove all permissions granted from/to this package
4797                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4798                }
4799
4800                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4801                        Uri.fromParts("package", packageName, null));
4802                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4803                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4804                        null, null, 0, null, null, null, false, false, userId);
4805            } catch (RemoteException e) {
4806            }
4807        } finally {
4808            Binder.restoreCallingIdentity(callingId);
4809        }
4810        return true;
4811    }
4812
4813    @Override
4814    public void killBackgroundProcesses(final String packageName, int userId) {
4815        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4816                != PackageManager.PERMISSION_GRANTED &&
4817                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4818                        != PackageManager.PERMISSION_GRANTED) {
4819            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4820                    + Binder.getCallingPid()
4821                    + ", uid=" + Binder.getCallingUid()
4822                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4823            Slog.w(TAG, msg);
4824            throw new SecurityException(msg);
4825        }
4826
4827        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4828                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4829        long callingId = Binder.clearCallingIdentity();
4830        try {
4831            IPackageManager pm = AppGlobals.getPackageManager();
4832            synchronized(this) {
4833                int appId = -1;
4834                try {
4835                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4836                } catch (RemoteException e) {
4837                }
4838                if (appId == -1) {
4839                    Slog.w(TAG, "Invalid packageName: " + packageName);
4840                    return;
4841                }
4842                killPackageProcessesLocked(packageName, appId, userId,
4843                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4844            }
4845        } finally {
4846            Binder.restoreCallingIdentity(callingId);
4847        }
4848    }
4849
4850    @Override
4851    public void killAllBackgroundProcesses() {
4852        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4853                != PackageManager.PERMISSION_GRANTED) {
4854            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4855                    + Binder.getCallingPid()
4856                    + ", uid=" + Binder.getCallingUid()
4857                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4858            Slog.w(TAG, msg);
4859            throw new SecurityException(msg);
4860        }
4861
4862        long callingId = Binder.clearCallingIdentity();
4863        try {
4864            synchronized(this) {
4865                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4866                final int NP = mProcessNames.getMap().size();
4867                for (int ip=0; ip<NP; ip++) {
4868                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4869                    final int NA = apps.size();
4870                    for (int ia=0; ia<NA; ia++) {
4871                        ProcessRecord app = apps.valueAt(ia);
4872                        if (app.persistent) {
4873                            // we don't kill persistent processes
4874                            continue;
4875                        }
4876                        if (app.removed) {
4877                            procs.add(app);
4878                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4879                            app.removed = true;
4880                            procs.add(app);
4881                        }
4882                    }
4883                }
4884
4885                int N = procs.size();
4886                for (int i=0; i<N; i++) {
4887                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4888                }
4889                mAllowLowerMemLevel = true;
4890                updateOomAdjLocked();
4891                doLowMemReportIfNeededLocked(null);
4892            }
4893        } finally {
4894            Binder.restoreCallingIdentity(callingId);
4895        }
4896    }
4897
4898    @Override
4899    public void forceStopPackage(final String packageName, int userId) {
4900        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4901                != PackageManager.PERMISSION_GRANTED) {
4902            String msg = "Permission Denial: forceStopPackage() from pid="
4903                    + Binder.getCallingPid()
4904                    + ", uid=" + Binder.getCallingUid()
4905                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4906            Slog.w(TAG, msg);
4907            throw new SecurityException(msg);
4908        }
4909        final int callingPid = Binder.getCallingPid();
4910        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4911                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4912        long callingId = Binder.clearCallingIdentity();
4913        try {
4914            IPackageManager pm = AppGlobals.getPackageManager();
4915            synchronized(this) {
4916                int[] users = userId == UserHandle.USER_ALL
4917                        ? getUsersLocked() : new int[] { userId };
4918                for (int user : users) {
4919                    int pkgUid = -1;
4920                    try {
4921                        pkgUid = pm.getPackageUid(packageName, user);
4922                    } catch (RemoteException e) {
4923                    }
4924                    if (pkgUid == -1) {
4925                        Slog.w(TAG, "Invalid packageName: " + packageName);
4926                        continue;
4927                    }
4928                    try {
4929                        pm.setPackageStoppedState(packageName, true, user);
4930                    } catch (RemoteException e) {
4931                    } catch (IllegalArgumentException e) {
4932                        Slog.w(TAG, "Failed trying to unstop package "
4933                                + packageName + ": " + e);
4934                    }
4935                    if (isUserRunningLocked(user, false)) {
4936                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4937                    }
4938                }
4939            }
4940        } finally {
4941            Binder.restoreCallingIdentity(callingId);
4942        }
4943    }
4944
4945    @Override
4946    public void addPackageDependency(String packageName) {
4947        synchronized (this) {
4948            int callingPid = Binder.getCallingPid();
4949            if (callingPid == Process.myPid()) {
4950                //  Yeah, um, no.
4951                Slog.w(TAG, "Can't addPackageDependency on system process");
4952                return;
4953            }
4954            ProcessRecord proc;
4955            synchronized (mPidsSelfLocked) {
4956                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4957            }
4958            if (proc != null) {
4959                if (proc.pkgDeps == null) {
4960                    proc.pkgDeps = new ArraySet<String>(1);
4961                }
4962                proc.pkgDeps.add(packageName);
4963            }
4964        }
4965    }
4966
4967    /*
4968     * The pkg name and app id have to be specified.
4969     */
4970    @Override
4971    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4972        if (pkg == null) {
4973            return;
4974        }
4975        // Make sure the uid is valid.
4976        if (appid < 0) {
4977            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4978            return;
4979        }
4980        int callerUid = Binder.getCallingUid();
4981        // Only the system server can kill an application
4982        if (callerUid == Process.SYSTEM_UID) {
4983            // Post an aysnc message to kill the application
4984            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4985            msg.arg1 = appid;
4986            msg.arg2 = 0;
4987            Bundle bundle = new Bundle();
4988            bundle.putString("pkg", pkg);
4989            bundle.putString("reason", reason);
4990            msg.obj = bundle;
4991            mHandler.sendMessage(msg);
4992        } else {
4993            throw new SecurityException(callerUid + " cannot kill pkg: " +
4994                    pkg);
4995        }
4996    }
4997
4998    @Override
4999    public void closeSystemDialogs(String reason) {
5000        enforceNotIsolatedCaller("closeSystemDialogs");
5001
5002        final int pid = Binder.getCallingPid();
5003        final int uid = Binder.getCallingUid();
5004        final long origId = Binder.clearCallingIdentity();
5005        try {
5006            synchronized (this) {
5007                // Only allow this from foreground processes, so that background
5008                // applications can't abuse it to prevent system UI from being shown.
5009                if (uid >= Process.FIRST_APPLICATION_UID) {
5010                    ProcessRecord proc;
5011                    synchronized (mPidsSelfLocked) {
5012                        proc = mPidsSelfLocked.get(pid);
5013                    }
5014                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5015                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5016                                + " from background process " + proc);
5017                        return;
5018                    }
5019                }
5020                closeSystemDialogsLocked(reason);
5021            }
5022        } finally {
5023            Binder.restoreCallingIdentity(origId);
5024        }
5025    }
5026
5027    void closeSystemDialogsLocked(String reason) {
5028        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5029        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5030                | Intent.FLAG_RECEIVER_FOREGROUND);
5031        if (reason != null) {
5032            intent.putExtra("reason", reason);
5033        }
5034        mWindowManager.closeSystemDialogs(reason);
5035
5036        mStackSupervisor.closeSystemDialogsLocked();
5037
5038        broadcastIntentLocked(null, null, intent, null,
5039                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5040                Process.SYSTEM_UID, UserHandle.USER_ALL);
5041    }
5042
5043    @Override
5044    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5045        enforceNotIsolatedCaller("getProcessMemoryInfo");
5046        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5047        for (int i=pids.length-1; i>=0; i--) {
5048            ProcessRecord proc;
5049            int oomAdj;
5050            synchronized (this) {
5051                synchronized (mPidsSelfLocked) {
5052                    proc = mPidsSelfLocked.get(pids[i]);
5053                    oomAdj = proc != null ? proc.setAdj : 0;
5054                }
5055            }
5056            infos[i] = new Debug.MemoryInfo();
5057            Debug.getMemoryInfo(pids[i], infos[i]);
5058            if (proc != null) {
5059                synchronized (this) {
5060                    if (proc.thread != null && proc.setAdj == oomAdj) {
5061                        // Record this for posterity if the process has been stable.
5062                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5063                                infos[i].getTotalUss(), false, proc.pkgList);
5064                    }
5065                }
5066            }
5067        }
5068        return infos;
5069    }
5070
5071    @Override
5072    public long[] getProcessPss(int[] pids) {
5073        enforceNotIsolatedCaller("getProcessPss");
5074        long[] pss = new long[pids.length];
5075        for (int i=pids.length-1; i>=0; i--) {
5076            ProcessRecord proc;
5077            int oomAdj;
5078            synchronized (this) {
5079                synchronized (mPidsSelfLocked) {
5080                    proc = mPidsSelfLocked.get(pids[i]);
5081                    oomAdj = proc != null ? proc.setAdj : 0;
5082                }
5083            }
5084            long[] tmpUss = new long[1];
5085            pss[i] = Debug.getPss(pids[i], tmpUss);
5086            if (proc != null) {
5087                synchronized (this) {
5088                    if (proc.thread != null && proc.setAdj == oomAdj) {
5089                        // Record this for posterity if the process has been stable.
5090                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5091                    }
5092                }
5093            }
5094        }
5095        return pss;
5096    }
5097
5098    @Override
5099    public void killApplicationProcess(String processName, int uid) {
5100        if (processName == null) {
5101            return;
5102        }
5103
5104        int callerUid = Binder.getCallingUid();
5105        // Only the system server can kill an application
5106        if (callerUid == Process.SYSTEM_UID) {
5107            synchronized (this) {
5108                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5109                if (app != null && app.thread != null) {
5110                    try {
5111                        app.thread.scheduleSuicide();
5112                    } catch (RemoteException e) {
5113                        // If the other end already died, then our work here is done.
5114                    }
5115                } else {
5116                    Slog.w(TAG, "Process/uid not found attempting kill of "
5117                            + processName + " / " + uid);
5118                }
5119            }
5120        } else {
5121            throw new SecurityException(callerUid + " cannot kill app process: " +
5122                    processName);
5123        }
5124    }
5125
5126    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5127        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5128                false, true, false, false, UserHandle.getUserId(uid), reason);
5129        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5130                Uri.fromParts("package", packageName, null));
5131        if (!mProcessesReady) {
5132            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5133                    | Intent.FLAG_RECEIVER_FOREGROUND);
5134        }
5135        intent.putExtra(Intent.EXTRA_UID, uid);
5136        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5137        broadcastIntentLocked(null, null, intent,
5138                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5139                false, false,
5140                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5141    }
5142
5143    private void forceStopUserLocked(int userId, String reason) {
5144        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5145        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5146        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5147                | Intent.FLAG_RECEIVER_FOREGROUND);
5148        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5149        broadcastIntentLocked(null, null, intent,
5150                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5151                false, false,
5152                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5153    }
5154
5155    private final boolean killPackageProcessesLocked(String packageName, int appId,
5156            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5157            boolean doit, boolean evenPersistent, String reason) {
5158        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5159
5160        // Remove all processes this package may have touched: all with the
5161        // same UID (except for the system or root user), and all whose name
5162        // matches the package name.
5163        final int NP = mProcessNames.getMap().size();
5164        for (int ip=0; ip<NP; ip++) {
5165            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5166            final int NA = apps.size();
5167            for (int ia=0; ia<NA; ia++) {
5168                ProcessRecord app = apps.valueAt(ia);
5169                if (app.persistent && !evenPersistent) {
5170                    // we don't kill persistent processes
5171                    continue;
5172                }
5173                if (app.removed) {
5174                    if (doit) {
5175                        procs.add(app);
5176                    }
5177                    continue;
5178                }
5179
5180                // Skip process if it doesn't meet our oom adj requirement.
5181                if (app.setAdj < minOomAdj) {
5182                    continue;
5183                }
5184
5185                // If no package is specified, we call all processes under the
5186                // give user id.
5187                if (packageName == null) {
5188                    if (app.userId != userId) {
5189                        continue;
5190                    }
5191                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5192                        continue;
5193                    }
5194                // Package has been specified, we want to hit all processes
5195                // that match it.  We need to qualify this by the processes
5196                // that are running under the specified app and user ID.
5197                } else {
5198                    final boolean isDep = app.pkgDeps != null
5199                            && app.pkgDeps.contains(packageName);
5200                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5201                        continue;
5202                    }
5203                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5204                        continue;
5205                    }
5206                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5207                        continue;
5208                    }
5209                }
5210
5211                // Process has passed all conditions, kill it!
5212                if (!doit) {
5213                    return true;
5214                }
5215                app.removed = true;
5216                procs.add(app);
5217            }
5218        }
5219
5220        int N = procs.size();
5221        for (int i=0; i<N; i++) {
5222            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5223        }
5224        updateOomAdjLocked();
5225        return N > 0;
5226    }
5227
5228    private final boolean forceStopPackageLocked(String name, int appId,
5229            boolean callerWillRestart, boolean purgeCache, boolean doit,
5230            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5231        int i;
5232        int N;
5233
5234        if (userId == UserHandle.USER_ALL && name == null) {
5235            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5236        }
5237
5238        if (appId < 0 && name != null) {
5239            try {
5240                appId = UserHandle.getAppId(
5241                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5242            } catch (RemoteException e) {
5243            }
5244        }
5245
5246        if (doit) {
5247            if (name != null) {
5248                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5249                        + " user=" + userId + ": " + reason);
5250            } else {
5251                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5252            }
5253
5254            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5255            for (int ip=pmap.size()-1; ip>=0; ip--) {
5256                SparseArray<Long> ba = pmap.valueAt(ip);
5257                for (i=ba.size()-1; i>=0; i--) {
5258                    boolean remove = false;
5259                    final int entUid = ba.keyAt(i);
5260                    if (name != null) {
5261                        if (userId == UserHandle.USER_ALL) {
5262                            if (UserHandle.getAppId(entUid) == appId) {
5263                                remove = true;
5264                            }
5265                        } else {
5266                            if (entUid == UserHandle.getUid(userId, appId)) {
5267                                remove = true;
5268                            }
5269                        }
5270                    } else if (UserHandle.getUserId(entUid) == userId) {
5271                        remove = true;
5272                    }
5273                    if (remove) {
5274                        ba.removeAt(i);
5275                    }
5276                }
5277                if (ba.size() == 0) {
5278                    pmap.removeAt(ip);
5279                }
5280            }
5281        }
5282
5283        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5284                -100, callerWillRestart, true, doit, evenPersistent,
5285                name == null ? ("stop user " + userId) : ("stop " + name));
5286
5287        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5288            if (!doit) {
5289                return true;
5290            }
5291            didSomething = true;
5292        }
5293
5294        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5295            if (!doit) {
5296                return true;
5297            }
5298            didSomething = true;
5299        }
5300
5301        if (name == null) {
5302            // Remove all sticky broadcasts from this user.
5303            mStickyBroadcasts.remove(userId);
5304        }
5305
5306        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5307        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5308                userId, providers)) {
5309            if (!doit) {
5310                return true;
5311            }
5312            didSomething = true;
5313        }
5314        N = providers.size();
5315        for (i=0; i<N; i++) {
5316            removeDyingProviderLocked(null, providers.get(i), true);
5317        }
5318
5319        // Remove transient permissions granted from/to this package/user
5320        removeUriPermissionsForPackageLocked(name, userId, false);
5321
5322        if (name == null || uninstalling) {
5323            // Remove pending intents.  For now we only do this when force
5324            // stopping users, because we have some problems when doing this
5325            // for packages -- app widgets are not currently cleaned up for
5326            // such packages, so they can be left with bad pending intents.
5327            if (mIntentSenderRecords.size() > 0) {
5328                Iterator<WeakReference<PendingIntentRecord>> it
5329                        = mIntentSenderRecords.values().iterator();
5330                while (it.hasNext()) {
5331                    WeakReference<PendingIntentRecord> wpir = it.next();
5332                    if (wpir == null) {
5333                        it.remove();
5334                        continue;
5335                    }
5336                    PendingIntentRecord pir = wpir.get();
5337                    if (pir == null) {
5338                        it.remove();
5339                        continue;
5340                    }
5341                    if (name == null) {
5342                        // Stopping user, remove all objects for the user.
5343                        if (pir.key.userId != userId) {
5344                            // Not the same user, skip it.
5345                            continue;
5346                        }
5347                    } else {
5348                        if (UserHandle.getAppId(pir.uid) != appId) {
5349                            // Different app id, skip it.
5350                            continue;
5351                        }
5352                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5353                            // Different user, skip it.
5354                            continue;
5355                        }
5356                        if (!pir.key.packageName.equals(name)) {
5357                            // Different package, skip it.
5358                            continue;
5359                        }
5360                    }
5361                    if (!doit) {
5362                        return true;
5363                    }
5364                    didSomething = true;
5365                    it.remove();
5366                    pir.canceled = true;
5367                    if (pir.key.activity != null) {
5368                        pir.key.activity.pendingResults.remove(pir.ref);
5369                    }
5370                }
5371            }
5372        }
5373
5374        if (doit) {
5375            if (purgeCache && name != null) {
5376                AttributeCache ac = AttributeCache.instance();
5377                if (ac != null) {
5378                    ac.removePackage(name);
5379                }
5380            }
5381            if (mBooted) {
5382                mStackSupervisor.resumeTopActivitiesLocked();
5383                mStackSupervisor.scheduleIdleLocked();
5384            }
5385        }
5386
5387        return didSomething;
5388    }
5389
5390    private final boolean removeProcessLocked(ProcessRecord app,
5391            boolean callerWillRestart, boolean allowRestart, String reason) {
5392        final String name = app.processName;
5393        final int uid = app.uid;
5394        if (DEBUG_PROCESSES) Slog.d(
5395            TAG, "Force removing proc " + app.toShortString() + " (" + name
5396            + "/" + uid + ")");
5397
5398        mProcessNames.remove(name, uid);
5399        mIsolatedProcesses.remove(app.uid);
5400        if (mHeavyWeightProcess == app) {
5401            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5402                    mHeavyWeightProcess.userId, 0));
5403            mHeavyWeightProcess = null;
5404        }
5405        boolean needRestart = false;
5406        if (app.pid > 0 && app.pid != MY_PID) {
5407            int pid = app.pid;
5408            synchronized (mPidsSelfLocked) {
5409                mPidsSelfLocked.remove(pid);
5410                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5411            }
5412            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5413            if (app.isolated) {
5414                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5415            }
5416            killUnneededProcessLocked(app, reason);
5417            Process.killProcessGroup(app.info.uid, app.pid);
5418            handleAppDiedLocked(app, true, allowRestart);
5419            removeLruProcessLocked(app);
5420
5421            if (app.persistent && !app.isolated) {
5422                if (!callerWillRestart) {
5423                    addAppLocked(app.info, false, null /* ABI override */);
5424                } else {
5425                    needRestart = true;
5426                }
5427            }
5428        } else {
5429            mRemovedProcesses.add(app);
5430        }
5431
5432        return needRestart;
5433    }
5434
5435    private final void processStartTimedOutLocked(ProcessRecord app) {
5436        final int pid = app.pid;
5437        boolean gone = false;
5438        synchronized (mPidsSelfLocked) {
5439            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5440            if (knownApp != null && knownApp.thread == null) {
5441                mPidsSelfLocked.remove(pid);
5442                gone = true;
5443            }
5444        }
5445
5446        if (gone) {
5447            Slog.w(TAG, "Process " + app + " failed to attach");
5448            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5449                    pid, app.uid, app.processName);
5450            mProcessNames.remove(app.processName, app.uid);
5451            mIsolatedProcesses.remove(app.uid);
5452            if (mHeavyWeightProcess == app) {
5453                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5454                        mHeavyWeightProcess.userId, 0));
5455                mHeavyWeightProcess = null;
5456            }
5457            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5458            if (app.isolated) {
5459                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5460            }
5461            // Take care of any launching providers waiting for this process.
5462            checkAppInLaunchingProvidersLocked(app, true);
5463            // Take care of any services that are waiting for the process.
5464            mServices.processStartTimedOutLocked(app);
5465            killUnneededProcessLocked(app, "start timeout");
5466            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5467                Slog.w(TAG, "Unattached app died before backup, skipping");
5468                try {
5469                    IBackupManager bm = IBackupManager.Stub.asInterface(
5470                            ServiceManager.getService(Context.BACKUP_SERVICE));
5471                    bm.agentDisconnected(app.info.packageName);
5472                } catch (RemoteException e) {
5473                    // Can't happen; the backup manager is local
5474                }
5475            }
5476            if (isPendingBroadcastProcessLocked(pid)) {
5477                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5478                skipPendingBroadcastLocked(pid);
5479            }
5480        } else {
5481            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5482        }
5483    }
5484
5485    private final boolean attachApplicationLocked(IApplicationThread thread,
5486            int pid) {
5487
5488        // Find the application record that is being attached...  either via
5489        // the pid if we are running in multiple processes, or just pull the
5490        // next app record if we are emulating process with anonymous threads.
5491        ProcessRecord app;
5492        if (pid != MY_PID && pid >= 0) {
5493            synchronized (mPidsSelfLocked) {
5494                app = mPidsSelfLocked.get(pid);
5495            }
5496        } else {
5497            app = null;
5498        }
5499
5500        if (app == null) {
5501            Slog.w(TAG, "No pending application record for pid " + pid
5502                    + " (IApplicationThread " + thread + "); dropping process");
5503            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5504            if (pid > 0 && pid != MY_PID) {
5505                Process.killProcessQuiet(pid);
5506                //TODO: Process.killProcessGroup(app.info.uid, pid);
5507            } else {
5508                try {
5509                    thread.scheduleExit();
5510                } catch (Exception e) {
5511                    // Ignore exceptions.
5512                }
5513            }
5514            return false;
5515        }
5516
5517        // If this application record is still attached to a previous
5518        // process, clean it up now.
5519        if (app.thread != null) {
5520            handleAppDiedLocked(app, true, true);
5521        }
5522
5523        // Tell the process all about itself.
5524
5525        if (localLOGV) Slog.v(
5526                TAG, "Binding process pid " + pid + " to record " + app);
5527
5528        final String processName = app.processName;
5529        try {
5530            AppDeathRecipient adr = new AppDeathRecipient(
5531                    app, pid, thread);
5532            thread.asBinder().linkToDeath(adr, 0);
5533            app.deathRecipient = adr;
5534        } catch (RemoteException e) {
5535            app.resetPackageList(mProcessStats);
5536            startProcessLocked(app, "link fail", processName);
5537            return false;
5538        }
5539
5540        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5541
5542        app.makeActive(thread, mProcessStats);
5543        app.curAdj = app.setAdj = -100;
5544        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5545        app.forcingToForeground = null;
5546        updateProcessForegroundLocked(app, false, false);
5547        app.hasShownUi = false;
5548        app.debugging = false;
5549        app.cached = false;
5550
5551        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5552
5553        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5554        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5555
5556        if (!normalMode) {
5557            Slog.i(TAG, "Launching preboot mode app: " + app);
5558        }
5559
5560        if (localLOGV) Slog.v(
5561            TAG, "New app record " + app
5562            + " thread=" + thread.asBinder() + " pid=" + pid);
5563        try {
5564            int testMode = IApplicationThread.DEBUG_OFF;
5565            if (mDebugApp != null && mDebugApp.equals(processName)) {
5566                testMode = mWaitForDebugger
5567                    ? IApplicationThread.DEBUG_WAIT
5568                    : IApplicationThread.DEBUG_ON;
5569                app.debugging = true;
5570                if (mDebugTransient) {
5571                    mDebugApp = mOrigDebugApp;
5572                    mWaitForDebugger = mOrigWaitForDebugger;
5573                }
5574            }
5575            String profileFile = app.instrumentationProfileFile;
5576            ParcelFileDescriptor profileFd = null;
5577            boolean profileAutoStop = false;
5578            if (mProfileApp != null && mProfileApp.equals(processName)) {
5579                mProfileProc = app;
5580                profileFile = mProfileFile;
5581                profileFd = mProfileFd;
5582                profileAutoStop = mAutoStopProfiler;
5583            }
5584            boolean enableOpenGlTrace = false;
5585            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5586                enableOpenGlTrace = true;
5587                mOpenGlTraceApp = null;
5588            }
5589
5590            // If the app is being launched for restore or full backup, set it up specially
5591            boolean isRestrictedBackupMode = false;
5592            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5593                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5594                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5595                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5596            }
5597
5598            ensurePackageDexOpt(app.instrumentationInfo != null
5599                    ? app.instrumentationInfo.packageName
5600                    : app.info.packageName);
5601            if (app.instrumentationClass != null) {
5602                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5603            }
5604            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5605                    + processName + " with config " + mConfiguration);
5606            ApplicationInfo appInfo = app.instrumentationInfo != null
5607                    ? app.instrumentationInfo : app.info;
5608            app.compat = compatibilityInfoForPackageLocked(appInfo);
5609            if (profileFd != null) {
5610                profileFd = profileFd.dup();
5611            }
5612            thread.bindApplication(processName, appInfo, providers,
5613                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5614                    app.instrumentationArguments, app.instrumentationWatcher,
5615                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5616                    isRestrictedBackupMode || !normalMode, app.persistent,
5617                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5618                    mCoreSettingsObserver.getCoreSettingsLocked());
5619            updateLruProcessLocked(app, false, null);
5620            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5621        } catch (Exception e) {
5622            // todo: Yikes!  What should we do?  For now we will try to
5623            // start another process, but that could easily get us in
5624            // an infinite loop of restarting processes...
5625            Slog.w(TAG, "Exception thrown during bind!", e);
5626
5627            app.resetPackageList(mProcessStats);
5628            app.unlinkDeathRecipient();
5629            startProcessLocked(app, "bind fail", processName);
5630            return false;
5631        }
5632
5633        // Remove this record from the list of starting applications.
5634        mPersistentStartingProcesses.remove(app);
5635        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5636                "Attach application locked removing on hold: " + app);
5637        mProcessesOnHold.remove(app);
5638
5639        boolean badApp = false;
5640        boolean didSomething = false;
5641
5642        // See if the top visible activity is waiting to run in this process...
5643        if (normalMode) {
5644            try {
5645                if (mStackSupervisor.attachApplicationLocked(app)) {
5646                    didSomething = true;
5647                }
5648            } catch (Exception e) {
5649                badApp = true;
5650            }
5651        }
5652
5653        // Find any services that should be running in this process...
5654        if (!badApp) {
5655            try {
5656                didSomething |= mServices.attachApplicationLocked(app, processName);
5657            } catch (Exception e) {
5658                badApp = true;
5659            }
5660        }
5661
5662        // Check if a next-broadcast receiver is in this process...
5663        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5664            try {
5665                didSomething |= sendPendingBroadcastsLocked(app);
5666            } catch (Exception e) {
5667                // If the app died trying to launch the receiver we declare it 'bad'
5668                badApp = true;
5669            }
5670        }
5671
5672        // Check whether the next backup agent is in this process...
5673        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5674            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5675            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5676            try {
5677                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5678                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5679                        mBackupTarget.backupMode);
5680            } catch (Exception e) {
5681                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5682                e.printStackTrace();
5683            }
5684        }
5685
5686        if (badApp) {
5687            // todo: Also need to kill application to deal with all
5688            // kinds of exceptions.
5689            handleAppDiedLocked(app, false, true);
5690            return false;
5691        }
5692
5693        if (!didSomething) {
5694            updateOomAdjLocked();
5695        }
5696
5697        return true;
5698    }
5699
5700    @Override
5701    public final void attachApplication(IApplicationThread thread) {
5702        synchronized (this) {
5703            int callingPid = Binder.getCallingPid();
5704            final long origId = Binder.clearCallingIdentity();
5705            attachApplicationLocked(thread, callingPid);
5706            Binder.restoreCallingIdentity(origId);
5707        }
5708    }
5709
5710    @Override
5711    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5712        final long origId = Binder.clearCallingIdentity();
5713        synchronized (this) {
5714            ActivityStack stack = ActivityRecord.getStackLocked(token);
5715            if (stack != null) {
5716                ActivityRecord r =
5717                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5718                if (stopProfiling) {
5719                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5720                        try {
5721                            mProfileFd.close();
5722                        } catch (IOException e) {
5723                        }
5724                        clearProfilerLocked();
5725                    }
5726                }
5727            }
5728        }
5729        Binder.restoreCallingIdentity(origId);
5730    }
5731
5732    void postEnableScreenAfterBootLocked() {
5733        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5734    }
5735
5736    void enableScreenAfterBoot() {
5737        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5738                SystemClock.uptimeMillis());
5739        mWindowManager.enableScreenAfterBoot();
5740
5741        synchronized (this) {
5742            updateEventDispatchingLocked();
5743        }
5744    }
5745
5746    @Override
5747    public void showBootMessage(final CharSequence msg, final boolean always) {
5748        enforceNotIsolatedCaller("showBootMessage");
5749        mWindowManager.showBootMessage(msg, always);
5750    }
5751
5752    @Override
5753    public void keyguardWaitingForActivityDrawn() {
5754        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5755        final long token = Binder.clearCallingIdentity();
5756        try {
5757            synchronized (this) {
5758                if (DEBUG_LOCKSCREEN) logLockScreen("");
5759                mWindowManager.keyguardWaitingForActivityDrawn();
5760            }
5761        } finally {
5762            Binder.restoreCallingIdentity(token);
5763        }
5764    }
5765
5766    final void finishBooting() {
5767        // Register receivers to handle package update events
5768        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5769
5770        // Let system services know.
5771        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5772
5773        synchronized (this) {
5774            // Ensure that any processes we had put on hold are now started
5775            // up.
5776            final int NP = mProcessesOnHold.size();
5777            if (NP > 0) {
5778                ArrayList<ProcessRecord> procs =
5779                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5780                for (int ip=0; ip<NP; ip++) {
5781                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5782                            + procs.get(ip));
5783                    startProcessLocked(procs.get(ip), "on-hold", null);
5784                }
5785            }
5786
5787            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5788                // Start looking for apps that are abusing wake locks.
5789                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5790                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5791                // Tell anyone interested that we are done booting!
5792                SystemProperties.set("sys.boot_completed", "1");
5793                SystemProperties.set("dev.bootcomplete", "1");
5794                for (int i=0; i<mStartedUsers.size(); i++) {
5795                    UserStartedState uss = mStartedUsers.valueAt(i);
5796                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5797                        uss.mState = UserStartedState.STATE_RUNNING;
5798                        final int userId = mStartedUsers.keyAt(i);
5799                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5800                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5801                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5802                        broadcastIntentLocked(null, null, intent, null,
5803                                new IIntentReceiver.Stub() {
5804                                    @Override
5805                                    public void performReceive(Intent intent, int resultCode,
5806                                            String data, Bundle extras, boolean ordered,
5807                                            boolean sticky, int sendingUser) {
5808                                        synchronized (ActivityManagerService.this) {
5809                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5810                                                    true, false);
5811                                        }
5812                                    }
5813                                },
5814                                0, null, null,
5815                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5816                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5817                                userId);
5818                    }
5819                }
5820                scheduleStartProfilesLocked();
5821            }
5822        }
5823    }
5824
5825    final void ensureBootCompleted() {
5826        boolean booting;
5827        boolean enableScreen;
5828        synchronized (this) {
5829            booting = mBooting;
5830            mBooting = false;
5831            enableScreen = !mBooted;
5832            mBooted = true;
5833        }
5834
5835        if (booting) {
5836            finishBooting();
5837        }
5838
5839        if (enableScreen) {
5840            enableScreenAfterBoot();
5841        }
5842    }
5843
5844    @Override
5845    public final void activityResumed(IBinder token) {
5846        final long origId = Binder.clearCallingIdentity();
5847        synchronized(this) {
5848            ActivityStack stack = ActivityRecord.getStackLocked(token);
5849            if (stack != null) {
5850                ActivityRecord.activityResumedLocked(token);
5851            }
5852        }
5853        Binder.restoreCallingIdentity(origId);
5854    }
5855
5856    @Override
5857    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5858        final long origId = Binder.clearCallingIdentity();
5859        synchronized(this) {
5860            ActivityStack stack = ActivityRecord.getStackLocked(token);
5861            if (stack != null) {
5862                stack.activityPausedLocked(token, false, persistentState);
5863            }
5864        }
5865        Binder.restoreCallingIdentity(origId);
5866    }
5867
5868    @Override
5869    public final void activityStopped(IBinder token, Bundle icicle,
5870            PersistableBundle persistentState, CharSequence description) {
5871        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5872
5873        // Refuse possible leaked file descriptors
5874        if (icicle != null && icicle.hasFileDescriptors()) {
5875            throw new IllegalArgumentException("File descriptors passed in Bundle");
5876        }
5877
5878        final long origId = Binder.clearCallingIdentity();
5879
5880        synchronized (this) {
5881            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5882            if (r != null) {
5883                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5884            }
5885        }
5886
5887        trimApplications();
5888
5889        Binder.restoreCallingIdentity(origId);
5890    }
5891
5892    @Override
5893    public final void activityDestroyed(IBinder token) {
5894        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5895        synchronized (this) {
5896            ActivityStack stack = ActivityRecord.getStackLocked(token);
5897            if (stack != null) {
5898                stack.activityDestroyedLocked(token);
5899            }
5900        }
5901    }
5902
5903    @Override
5904    public final void backgroundResourcesReleased(IBinder token) {
5905        final long origId = Binder.clearCallingIdentity();
5906        try {
5907            synchronized (this) {
5908                ActivityStack stack = ActivityRecord.getStackLocked(token);
5909                if (stack != null) {
5910                    stack.backgroundResourcesReleased(token);
5911                }
5912            }
5913        } finally {
5914            Binder.restoreCallingIdentity(origId);
5915        }
5916    }
5917
5918    @Override
5919    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5920        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5921    }
5922
5923    @Override
5924    public final void notifyEnterAnimationComplete(IBinder token) {
5925        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5926    }
5927
5928    @Override
5929    public String getCallingPackage(IBinder token) {
5930        synchronized (this) {
5931            ActivityRecord r = getCallingRecordLocked(token);
5932            return r != null ? r.info.packageName : null;
5933        }
5934    }
5935
5936    @Override
5937    public ComponentName getCallingActivity(IBinder token) {
5938        synchronized (this) {
5939            ActivityRecord r = getCallingRecordLocked(token);
5940            return r != null ? r.intent.getComponent() : null;
5941        }
5942    }
5943
5944    private ActivityRecord getCallingRecordLocked(IBinder token) {
5945        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5946        if (r == null) {
5947            return null;
5948        }
5949        return r.resultTo;
5950    }
5951
5952    @Override
5953    public ComponentName getActivityClassForToken(IBinder token) {
5954        synchronized(this) {
5955            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5956            if (r == null) {
5957                return null;
5958            }
5959            return r.intent.getComponent();
5960        }
5961    }
5962
5963    @Override
5964    public String getPackageForToken(IBinder token) {
5965        synchronized(this) {
5966            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5967            if (r == null) {
5968                return null;
5969            }
5970            return r.packageName;
5971        }
5972    }
5973
5974    @Override
5975    public IIntentSender getIntentSender(int type,
5976            String packageName, IBinder token, String resultWho,
5977            int requestCode, Intent[] intents, String[] resolvedTypes,
5978            int flags, Bundle options, int userId) {
5979        enforceNotIsolatedCaller("getIntentSender");
5980        // Refuse possible leaked file descriptors
5981        if (intents != null) {
5982            if (intents.length < 1) {
5983                throw new IllegalArgumentException("Intents array length must be >= 1");
5984            }
5985            for (int i=0; i<intents.length; i++) {
5986                Intent intent = intents[i];
5987                if (intent != null) {
5988                    if (intent.hasFileDescriptors()) {
5989                        throw new IllegalArgumentException("File descriptors passed in Intent");
5990                    }
5991                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5992                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5993                        throw new IllegalArgumentException(
5994                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5995                    }
5996                    intents[i] = new Intent(intent);
5997                }
5998            }
5999            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6000                throw new IllegalArgumentException(
6001                        "Intent array length does not match resolvedTypes length");
6002            }
6003        }
6004        if (options != null) {
6005            if (options.hasFileDescriptors()) {
6006                throw new IllegalArgumentException("File descriptors passed in options");
6007            }
6008        }
6009
6010        synchronized(this) {
6011            int callingUid = Binder.getCallingUid();
6012            int origUserId = userId;
6013            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6014                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6015                    ALLOW_NON_FULL, "getIntentSender", null);
6016            if (origUserId == UserHandle.USER_CURRENT) {
6017                // We don't want to evaluate this until the pending intent is
6018                // actually executed.  However, we do want to always do the
6019                // security checking for it above.
6020                userId = UserHandle.USER_CURRENT;
6021            }
6022            try {
6023                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6024                    int uid = AppGlobals.getPackageManager()
6025                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6026                    if (!UserHandle.isSameApp(callingUid, uid)) {
6027                        String msg = "Permission Denial: getIntentSender() from pid="
6028                            + Binder.getCallingPid()
6029                            + ", uid=" + Binder.getCallingUid()
6030                            + ", (need uid=" + uid + ")"
6031                            + " is not allowed to send as package " + packageName;
6032                        Slog.w(TAG, msg);
6033                        throw new SecurityException(msg);
6034                    }
6035                }
6036
6037                return getIntentSenderLocked(type, packageName, callingUid, userId,
6038                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6039
6040            } catch (RemoteException e) {
6041                throw new SecurityException(e);
6042            }
6043        }
6044    }
6045
6046    IIntentSender getIntentSenderLocked(int type, String packageName,
6047            int callingUid, int userId, IBinder token, String resultWho,
6048            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6049            Bundle options) {
6050        if (DEBUG_MU)
6051            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6052        ActivityRecord activity = null;
6053        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6054            activity = ActivityRecord.isInStackLocked(token);
6055            if (activity == null) {
6056                return null;
6057            }
6058            if (activity.finishing) {
6059                return null;
6060            }
6061        }
6062
6063        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6064        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6065        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6066        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6067                |PendingIntent.FLAG_UPDATE_CURRENT);
6068
6069        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6070                type, packageName, activity, resultWho,
6071                requestCode, intents, resolvedTypes, flags, options, userId);
6072        WeakReference<PendingIntentRecord> ref;
6073        ref = mIntentSenderRecords.get(key);
6074        PendingIntentRecord rec = ref != null ? ref.get() : null;
6075        if (rec != null) {
6076            if (!cancelCurrent) {
6077                if (updateCurrent) {
6078                    if (rec.key.requestIntent != null) {
6079                        rec.key.requestIntent.replaceExtras(intents != null ?
6080                                intents[intents.length - 1] : null);
6081                    }
6082                    if (intents != null) {
6083                        intents[intents.length-1] = rec.key.requestIntent;
6084                        rec.key.allIntents = intents;
6085                        rec.key.allResolvedTypes = resolvedTypes;
6086                    } else {
6087                        rec.key.allIntents = null;
6088                        rec.key.allResolvedTypes = null;
6089                    }
6090                }
6091                return rec;
6092            }
6093            rec.canceled = true;
6094            mIntentSenderRecords.remove(key);
6095        }
6096        if (noCreate) {
6097            return rec;
6098        }
6099        rec = new PendingIntentRecord(this, key, callingUid);
6100        mIntentSenderRecords.put(key, rec.ref);
6101        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6102            if (activity.pendingResults == null) {
6103                activity.pendingResults
6104                        = new HashSet<WeakReference<PendingIntentRecord>>();
6105            }
6106            activity.pendingResults.add(rec.ref);
6107        }
6108        return rec;
6109    }
6110
6111    @Override
6112    public void cancelIntentSender(IIntentSender sender) {
6113        if (!(sender instanceof PendingIntentRecord)) {
6114            return;
6115        }
6116        synchronized(this) {
6117            PendingIntentRecord rec = (PendingIntentRecord)sender;
6118            try {
6119                int uid = AppGlobals.getPackageManager()
6120                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6121                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6122                    String msg = "Permission Denial: cancelIntentSender() from pid="
6123                        + Binder.getCallingPid()
6124                        + ", uid=" + Binder.getCallingUid()
6125                        + " is not allowed to cancel packges "
6126                        + rec.key.packageName;
6127                    Slog.w(TAG, msg);
6128                    throw new SecurityException(msg);
6129                }
6130            } catch (RemoteException e) {
6131                throw new SecurityException(e);
6132            }
6133            cancelIntentSenderLocked(rec, true);
6134        }
6135    }
6136
6137    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6138        rec.canceled = true;
6139        mIntentSenderRecords.remove(rec.key);
6140        if (cleanActivity && rec.key.activity != null) {
6141            rec.key.activity.pendingResults.remove(rec.ref);
6142        }
6143    }
6144
6145    @Override
6146    public String getPackageForIntentSender(IIntentSender pendingResult) {
6147        if (!(pendingResult instanceof PendingIntentRecord)) {
6148            return null;
6149        }
6150        try {
6151            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6152            return res.key.packageName;
6153        } catch (ClassCastException e) {
6154        }
6155        return null;
6156    }
6157
6158    @Override
6159    public int getUidForIntentSender(IIntentSender sender) {
6160        if (sender instanceof PendingIntentRecord) {
6161            try {
6162                PendingIntentRecord res = (PendingIntentRecord)sender;
6163                return res.uid;
6164            } catch (ClassCastException e) {
6165            }
6166        }
6167        return -1;
6168    }
6169
6170    @Override
6171    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6172        if (!(pendingResult instanceof PendingIntentRecord)) {
6173            return false;
6174        }
6175        try {
6176            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6177            if (res.key.allIntents == null) {
6178                return false;
6179            }
6180            for (int i=0; i<res.key.allIntents.length; i++) {
6181                Intent intent = res.key.allIntents[i];
6182                if (intent.getPackage() != null && intent.getComponent() != null) {
6183                    return false;
6184                }
6185            }
6186            return true;
6187        } catch (ClassCastException e) {
6188        }
6189        return false;
6190    }
6191
6192    @Override
6193    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6194        if (!(pendingResult instanceof PendingIntentRecord)) {
6195            return false;
6196        }
6197        try {
6198            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6199            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6200                return true;
6201            }
6202            return false;
6203        } catch (ClassCastException e) {
6204        }
6205        return false;
6206    }
6207
6208    @Override
6209    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6210        if (!(pendingResult instanceof PendingIntentRecord)) {
6211            return null;
6212        }
6213        try {
6214            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6215            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6216        } catch (ClassCastException e) {
6217        }
6218        return null;
6219    }
6220
6221    @Override
6222    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6223        if (!(pendingResult instanceof PendingIntentRecord)) {
6224            return null;
6225        }
6226        try {
6227            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6228            Intent intent = res.key.requestIntent;
6229            if (intent != null) {
6230                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6231                        || res.lastTagPrefix.equals(prefix))) {
6232                    return res.lastTag;
6233                }
6234                res.lastTagPrefix = prefix;
6235                StringBuilder sb = new StringBuilder(128);
6236                if (prefix != null) {
6237                    sb.append(prefix);
6238                }
6239                if (intent.getAction() != null) {
6240                    sb.append(intent.getAction());
6241                } else if (intent.getComponent() != null) {
6242                    intent.getComponent().appendShortString(sb);
6243                } else {
6244                    sb.append("?");
6245                }
6246                return res.lastTag = sb.toString();
6247            }
6248        } catch (ClassCastException e) {
6249        }
6250        return null;
6251    }
6252
6253    @Override
6254    public void setProcessLimit(int max) {
6255        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6256                "setProcessLimit()");
6257        synchronized (this) {
6258            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6259            mProcessLimitOverride = max;
6260        }
6261        trimApplications();
6262    }
6263
6264    @Override
6265    public int getProcessLimit() {
6266        synchronized (this) {
6267            return mProcessLimitOverride;
6268        }
6269    }
6270
6271    void foregroundTokenDied(ForegroundToken token) {
6272        synchronized (ActivityManagerService.this) {
6273            synchronized (mPidsSelfLocked) {
6274                ForegroundToken cur
6275                    = mForegroundProcesses.get(token.pid);
6276                if (cur != token) {
6277                    return;
6278                }
6279                mForegroundProcesses.remove(token.pid);
6280                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6281                if (pr == null) {
6282                    return;
6283                }
6284                pr.forcingToForeground = null;
6285                updateProcessForegroundLocked(pr, false, false);
6286            }
6287            updateOomAdjLocked();
6288        }
6289    }
6290
6291    @Override
6292    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6293        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6294                "setProcessForeground()");
6295        synchronized(this) {
6296            boolean changed = false;
6297
6298            synchronized (mPidsSelfLocked) {
6299                ProcessRecord pr = mPidsSelfLocked.get(pid);
6300                if (pr == null && isForeground) {
6301                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6302                    return;
6303                }
6304                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6305                if (oldToken != null) {
6306                    oldToken.token.unlinkToDeath(oldToken, 0);
6307                    mForegroundProcesses.remove(pid);
6308                    if (pr != null) {
6309                        pr.forcingToForeground = null;
6310                    }
6311                    changed = true;
6312                }
6313                if (isForeground && token != null) {
6314                    ForegroundToken newToken = new ForegroundToken() {
6315                        @Override
6316                        public void binderDied() {
6317                            foregroundTokenDied(this);
6318                        }
6319                    };
6320                    newToken.pid = pid;
6321                    newToken.token = token;
6322                    try {
6323                        token.linkToDeath(newToken, 0);
6324                        mForegroundProcesses.put(pid, newToken);
6325                        pr.forcingToForeground = token;
6326                        changed = true;
6327                    } catch (RemoteException e) {
6328                        // If the process died while doing this, we will later
6329                        // do the cleanup with the process death link.
6330                    }
6331                }
6332            }
6333
6334            if (changed) {
6335                updateOomAdjLocked();
6336            }
6337        }
6338    }
6339
6340    // =========================================================
6341    // PERMISSIONS
6342    // =========================================================
6343
6344    static class PermissionController extends IPermissionController.Stub {
6345        ActivityManagerService mActivityManagerService;
6346        PermissionController(ActivityManagerService activityManagerService) {
6347            mActivityManagerService = activityManagerService;
6348        }
6349
6350        @Override
6351        public boolean checkPermission(String permission, int pid, int uid) {
6352            return mActivityManagerService.checkPermission(permission, pid,
6353                    uid) == PackageManager.PERMISSION_GRANTED;
6354        }
6355    }
6356
6357    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6358        @Override
6359        public int checkComponentPermission(String permission, int pid, int uid,
6360                int owningUid, boolean exported) {
6361            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6362                    owningUid, exported);
6363        }
6364
6365        @Override
6366        public Object getAMSLock() {
6367            return ActivityManagerService.this;
6368        }
6369    }
6370
6371    /**
6372     * This can be called with or without the global lock held.
6373     */
6374    int checkComponentPermission(String permission, int pid, int uid,
6375            int owningUid, boolean exported) {
6376        // We might be performing an operation on behalf of an indirect binder
6377        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6378        // client identity accordingly before proceeding.
6379        Identity tlsIdentity = sCallerIdentity.get();
6380        if (tlsIdentity != null) {
6381            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6382                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6383            uid = tlsIdentity.uid;
6384            pid = tlsIdentity.pid;
6385        }
6386
6387        if (pid == MY_PID) {
6388            return PackageManager.PERMISSION_GRANTED;
6389        }
6390
6391        return ActivityManager.checkComponentPermission(permission, uid,
6392                owningUid, exported);
6393    }
6394
6395    /**
6396     * As the only public entry point for permissions checking, this method
6397     * can enforce the semantic that requesting a check on a null global
6398     * permission is automatically denied.  (Internally a null permission
6399     * string is used when calling {@link #checkComponentPermission} in cases
6400     * when only uid-based security is needed.)
6401     *
6402     * This can be called with or without the global lock held.
6403     */
6404    @Override
6405    public int checkPermission(String permission, int pid, int uid) {
6406        if (permission == null) {
6407            return PackageManager.PERMISSION_DENIED;
6408        }
6409        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6410    }
6411
6412    /**
6413     * Binder IPC calls go through the public entry point.
6414     * This can be called with or without the global lock held.
6415     */
6416    int checkCallingPermission(String permission) {
6417        return checkPermission(permission,
6418                Binder.getCallingPid(),
6419                UserHandle.getAppId(Binder.getCallingUid()));
6420    }
6421
6422    /**
6423     * This can be called with or without the global lock held.
6424     */
6425    void enforceCallingPermission(String permission, String func) {
6426        if (checkCallingPermission(permission)
6427                == PackageManager.PERMISSION_GRANTED) {
6428            return;
6429        }
6430
6431        String msg = "Permission Denial: " + func + " from pid="
6432                + Binder.getCallingPid()
6433                + ", uid=" + Binder.getCallingUid()
6434                + " requires " + permission;
6435        Slog.w(TAG, msg);
6436        throw new SecurityException(msg);
6437    }
6438
6439    /**
6440     * Determine if UID is holding permissions required to access {@link Uri} in
6441     * the given {@link ProviderInfo}. Final permission checking is always done
6442     * in {@link ContentProvider}.
6443     */
6444    private final boolean checkHoldingPermissionsLocked(
6445            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6446        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6447                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6448        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6449            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6450                    != PERMISSION_GRANTED) {
6451                return false;
6452            }
6453        }
6454        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6455    }
6456
6457    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6458            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6459        if (pi.applicationInfo.uid == uid) {
6460            return true;
6461        } else if (!pi.exported) {
6462            return false;
6463        }
6464
6465        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6466        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6467        try {
6468            // check if target holds top-level <provider> permissions
6469            if (!readMet && pi.readPermission != null && considerUidPermissions
6470                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6471                readMet = true;
6472            }
6473            if (!writeMet && pi.writePermission != null && considerUidPermissions
6474                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6475                writeMet = true;
6476            }
6477
6478            // track if unprotected read/write is allowed; any denied
6479            // <path-permission> below removes this ability
6480            boolean allowDefaultRead = pi.readPermission == null;
6481            boolean allowDefaultWrite = pi.writePermission == null;
6482
6483            // check if target holds any <path-permission> that match uri
6484            final PathPermission[] pps = pi.pathPermissions;
6485            if (pps != null) {
6486                final String path = grantUri.uri.getPath();
6487                int i = pps.length;
6488                while (i > 0 && (!readMet || !writeMet)) {
6489                    i--;
6490                    PathPermission pp = pps[i];
6491                    if (pp.match(path)) {
6492                        if (!readMet) {
6493                            final String pprperm = pp.getReadPermission();
6494                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6495                                    + pprperm + " for " + pp.getPath()
6496                                    + ": match=" + pp.match(path)
6497                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6498                            if (pprperm != null) {
6499                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6500                                        == PERMISSION_GRANTED) {
6501                                    readMet = true;
6502                                } else {
6503                                    allowDefaultRead = false;
6504                                }
6505                            }
6506                        }
6507                        if (!writeMet) {
6508                            final String ppwperm = pp.getWritePermission();
6509                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6510                                    + ppwperm + " for " + pp.getPath()
6511                                    + ": match=" + pp.match(path)
6512                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6513                            if (ppwperm != null) {
6514                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6515                                        == PERMISSION_GRANTED) {
6516                                    writeMet = true;
6517                                } else {
6518                                    allowDefaultWrite = false;
6519                                }
6520                            }
6521                        }
6522                    }
6523                }
6524            }
6525
6526            // grant unprotected <provider> read/write, if not blocked by
6527            // <path-permission> above
6528            if (allowDefaultRead) readMet = true;
6529            if (allowDefaultWrite) writeMet = true;
6530
6531        } catch (RemoteException e) {
6532            return false;
6533        }
6534
6535        return readMet && writeMet;
6536    }
6537
6538    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6539        ProviderInfo pi = null;
6540        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6541        if (cpr != null) {
6542            pi = cpr.info;
6543        } else {
6544            try {
6545                pi = AppGlobals.getPackageManager().resolveContentProvider(
6546                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6547            } catch (RemoteException ex) {
6548            }
6549        }
6550        return pi;
6551    }
6552
6553    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6554        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6555        if (targetUris != null) {
6556            return targetUris.get(grantUri);
6557        }
6558        return null;
6559    }
6560
6561    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6562            String targetPkg, int targetUid, GrantUri grantUri) {
6563        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6564        if (targetUris == null) {
6565            targetUris = Maps.newArrayMap();
6566            mGrantedUriPermissions.put(targetUid, targetUris);
6567        }
6568
6569        UriPermission perm = targetUris.get(grantUri);
6570        if (perm == null) {
6571            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6572            targetUris.put(grantUri, perm);
6573        }
6574
6575        return perm;
6576    }
6577
6578    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6579            final int modeFlags) {
6580        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6581        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6582                : UriPermission.STRENGTH_OWNED;
6583
6584        // Root gets to do everything.
6585        if (uid == 0) {
6586            return true;
6587        }
6588
6589        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6590        if (perms == null) return false;
6591
6592        // First look for exact match
6593        final UriPermission exactPerm = perms.get(grantUri);
6594        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6595            return true;
6596        }
6597
6598        // No exact match, look for prefixes
6599        final int N = perms.size();
6600        for (int i = 0; i < N; i++) {
6601            final UriPermission perm = perms.valueAt(i);
6602            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6603                    && perm.getStrength(modeFlags) >= minStrength) {
6604                return true;
6605            }
6606        }
6607
6608        return false;
6609    }
6610
6611    @Override
6612    public int checkUriPermission(Uri uri, int pid, int uid,
6613            final int modeFlags, int userId) {
6614        enforceNotIsolatedCaller("checkUriPermission");
6615
6616        // Another redirected-binder-call permissions check as in
6617        // {@link checkComponentPermission}.
6618        Identity tlsIdentity = sCallerIdentity.get();
6619        if (tlsIdentity != null) {
6620            uid = tlsIdentity.uid;
6621            pid = tlsIdentity.pid;
6622        }
6623
6624        // Our own process gets to do everything.
6625        if (pid == MY_PID) {
6626            return PackageManager.PERMISSION_GRANTED;
6627        }
6628        synchronized (this) {
6629            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6630                    ? PackageManager.PERMISSION_GRANTED
6631                    : PackageManager.PERMISSION_DENIED;
6632        }
6633    }
6634
6635    /**
6636     * Check if the targetPkg can be granted permission to access uri by
6637     * the callingUid using the given modeFlags.  Throws a security exception
6638     * if callingUid is not allowed to do this.  Returns the uid of the target
6639     * if the URI permission grant should be performed; returns -1 if it is not
6640     * needed (for example targetPkg already has permission to access the URI).
6641     * If you already know the uid of the target, you can supply it in
6642     * lastTargetUid else set that to -1.
6643     */
6644    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6645            final int modeFlags, int lastTargetUid) {
6646        if (!Intent.isAccessUriMode(modeFlags)) {
6647            return -1;
6648        }
6649
6650        if (targetPkg != null) {
6651            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6652                    "Checking grant " + targetPkg + " permission to " + grantUri);
6653        }
6654
6655        final IPackageManager pm = AppGlobals.getPackageManager();
6656
6657        // If this is not a content: uri, we can't do anything with it.
6658        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6659            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6660                    "Can't grant URI permission for non-content URI: " + grantUri);
6661            return -1;
6662        }
6663
6664        final String authority = grantUri.uri.getAuthority();
6665        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6666        if (pi == null) {
6667            Slog.w(TAG, "No content provider found for permission check: " +
6668                    grantUri.uri.toSafeString());
6669            return -1;
6670        }
6671
6672        int targetUid = lastTargetUid;
6673        if (targetUid < 0 && targetPkg != null) {
6674            try {
6675                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6676                if (targetUid < 0) {
6677                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6678                            "Can't grant URI permission no uid for: " + targetPkg);
6679                    return -1;
6680                }
6681            } catch (RemoteException ex) {
6682                return -1;
6683            }
6684        }
6685
6686        if (targetUid >= 0) {
6687            // First...  does the target actually need this permission?
6688            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6689                // No need to grant the target this permission.
6690                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6691                        "Target " + targetPkg + " already has full permission to " + grantUri);
6692                return -1;
6693            }
6694        } else {
6695            // First...  there is no target package, so can anyone access it?
6696            boolean allowed = pi.exported;
6697            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6698                if (pi.readPermission != null) {
6699                    allowed = false;
6700                }
6701            }
6702            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6703                if (pi.writePermission != null) {
6704                    allowed = false;
6705                }
6706            }
6707            if (allowed) {
6708                return -1;
6709            }
6710        }
6711
6712        /* There is a special cross user grant if:
6713         * - The target is on another user.
6714         * - Apps on the current user can access the uri without any uid permissions.
6715         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6716         * grant uri permissions.
6717         */
6718        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6719                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6720                modeFlags, false /*without considering the uid permissions*/);
6721
6722        // Second...  is the provider allowing granting of URI permissions?
6723        if (!specialCrossUserGrant) {
6724            if (!pi.grantUriPermissions) {
6725                throw new SecurityException("Provider " + pi.packageName
6726                        + "/" + pi.name
6727                        + " does not allow granting of Uri permissions (uri "
6728                        + grantUri + ")");
6729            }
6730            if (pi.uriPermissionPatterns != null) {
6731                final int N = pi.uriPermissionPatterns.length;
6732                boolean allowed = false;
6733                for (int i=0; i<N; i++) {
6734                    if (pi.uriPermissionPatterns[i] != null
6735                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6736                        allowed = true;
6737                        break;
6738                    }
6739                }
6740                if (!allowed) {
6741                    throw new SecurityException("Provider " + pi.packageName
6742                            + "/" + pi.name
6743                            + " does not allow granting of permission to path of Uri "
6744                            + grantUri);
6745                }
6746            }
6747        }
6748
6749        // Third...  does the caller itself have permission to access
6750        // this uri?
6751        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6752            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6753                // Require they hold a strong enough Uri permission
6754                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6755                    throw new SecurityException("Uid " + callingUid
6756                            + " does not have permission to uri " + grantUri);
6757                }
6758            }
6759        }
6760        return targetUid;
6761    }
6762
6763    @Override
6764    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6765            final int modeFlags, int userId) {
6766        enforceNotIsolatedCaller("checkGrantUriPermission");
6767        synchronized(this) {
6768            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6769                    new GrantUri(userId, uri, false), modeFlags, -1);
6770        }
6771    }
6772
6773    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6774            final int modeFlags, UriPermissionOwner owner) {
6775        if (!Intent.isAccessUriMode(modeFlags)) {
6776            return;
6777        }
6778
6779        // So here we are: the caller has the assumed permission
6780        // to the uri, and the target doesn't.  Let's now give this to
6781        // the target.
6782
6783        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6784                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6785
6786        final String authority = grantUri.uri.getAuthority();
6787        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6788        if (pi == null) {
6789            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6790            return;
6791        }
6792
6793        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6794            grantUri.prefix = true;
6795        }
6796        final UriPermission perm = findOrCreateUriPermissionLocked(
6797                pi.packageName, targetPkg, targetUid, grantUri);
6798        perm.grantModes(modeFlags, owner);
6799    }
6800
6801    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6802            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6803        if (targetPkg == null) {
6804            throw new NullPointerException("targetPkg");
6805        }
6806        int targetUid;
6807        final IPackageManager pm = AppGlobals.getPackageManager();
6808        try {
6809            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6810        } catch (RemoteException ex) {
6811            return;
6812        }
6813
6814        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6815                targetUid);
6816        if (targetUid < 0) {
6817            return;
6818        }
6819
6820        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6821                owner);
6822    }
6823
6824    static class NeededUriGrants extends ArrayList<GrantUri> {
6825        final String targetPkg;
6826        final int targetUid;
6827        final int flags;
6828
6829        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6830            this.targetPkg = targetPkg;
6831            this.targetUid = targetUid;
6832            this.flags = flags;
6833        }
6834    }
6835
6836    /**
6837     * Like checkGrantUriPermissionLocked, but takes an Intent.
6838     */
6839    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6840            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6841        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6842                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6843                + " clip=" + (intent != null ? intent.getClipData() : null)
6844                + " from " + intent + "; flags=0x"
6845                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6846
6847        if (targetPkg == null) {
6848            throw new NullPointerException("targetPkg");
6849        }
6850
6851        if (intent == null) {
6852            return null;
6853        }
6854        Uri data = intent.getData();
6855        ClipData clip = intent.getClipData();
6856        if (data == null && clip == null) {
6857            return null;
6858        }
6859        // Default userId for uris in the intent (if they don't specify it themselves)
6860        int contentUserHint = intent.getContentUserHint();
6861        if (contentUserHint == UserHandle.USER_CURRENT) {
6862            contentUserHint = UserHandle.getUserId(callingUid);
6863        }
6864        final IPackageManager pm = AppGlobals.getPackageManager();
6865        int targetUid;
6866        if (needed != null) {
6867            targetUid = needed.targetUid;
6868        } else {
6869            try {
6870                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6871            } catch (RemoteException ex) {
6872                return null;
6873            }
6874            if (targetUid < 0) {
6875                if (DEBUG_URI_PERMISSION) {
6876                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6877                            + " on user " + targetUserId);
6878                }
6879                return null;
6880            }
6881        }
6882        if (data != null) {
6883            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6884            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6885                    targetUid);
6886            if (targetUid > 0) {
6887                if (needed == null) {
6888                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6889                }
6890                needed.add(grantUri);
6891            }
6892        }
6893        if (clip != null) {
6894            for (int i=0; i<clip.getItemCount(); i++) {
6895                Uri uri = clip.getItemAt(i).getUri();
6896                if (uri != null) {
6897                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6898                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6899                            targetUid);
6900                    if (targetUid > 0) {
6901                        if (needed == null) {
6902                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6903                        }
6904                        needed.add(grantUri);
6905                    }
6906                } else {
6907                    Intent clipIntent = clip.getItemAt(i).getIntent();
6908                    if (clipIntent != null) {
6909                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6910                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6911                        if (newNeeded != null) {
6912                            needed = newNeeded;
6913                        }
6914                    }
6915                }
6916            }
6917        }
6918
6919        return needed;
6920    }
6921
6922    /**
6923     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6924     */
6925    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6926            UriPermissionOwner owner) {
6927        if (needed != null) {
6928            for (int i=0; i<needed.size(); i++) {
6929                GrantUri grantUri = needed.get(i);
6930                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6931                        grantUri, needed.flags, owner);
6932            }
6933        }
6934    }
6935
6936    void grantUriPermissionFromIntentLocked(int callingUid,
6937            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6938        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6939                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6940        if (needed == null) {
6941            return;
6942        }
6943
6944        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6945    }
6946
6947    @Override
6948    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6949            final int modeFlags, int userId) {
6950        enforceNotIsolatedCaller("grantUriPermission");
6951        GrantUri grantUri = new GrantUri(userId, uri, false);
6952        synchronized(this) {
6953            final ProcessRecord r = getRecordForAppLocked(caller);
6954            if (r == null) {
6955                throw new SecurityException("Unable to find app for caller "
6956                        + caller
6957                        + " when granting permission to uri " + grantUri);
6958            }
6959            if (targetPkg == null) {
6960                throw new IllegalArgumentException("null target");
6961            }
6962            if (grantUri == null) {
6963                throw new IllegalArgumentException("null uri");
6964            }
6965
6966            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6967                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6968                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6969                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6970
6971            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6972                    UserHandle.getUserId(r.uid));
6973        }
6974    }
6975
6976    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6977        if (perm.modeFlags == 0) {
6978            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6979                    perm.targetUid);
6980            if (perms != null) {
6981                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6982                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6983
6984                perms.remove(perm.uri);
6985                if (perms.isEmpty()) {
6986                    mGrantedUriPermissions.remove(perm.targetUid);
6987                }
6988            }
6989        }
6990    }
6991
6992    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6993        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6994
6995        final IPackageManager pm = AppGlobals.getPackageManager();
6996        final String authority = grantUri.uri.getAuthority();
6997        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6998        if (pi == null) {
6999            Slog.w(TAG, "No content provider found for permission revoke: "
7000                    + grantUri.toSafeString());
7001            return;
7002        }
7003
7004        // Does the caller have this permission on the URI?
7005        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7006            // Right now, if you are not the original owner of the permission,
7007            // you are not allowed to revoke it.
7008            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7009                throw new SecurityException("Uid " + callingUid
7010                        + " does not have permission to uri " + grantUri);
7011            //}
7012        }
7013
7014        boolean persistChanged = false;
7015
7016        // Go through all of the permissions and remove any that match.
7017        int N = mGrantedUriPermissions.size();
7018        for (int i = 0; i < N; i++) {
7019            final int targetUid = mGrantedUriPermissions.keyAt(i);
7020            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7021
7022            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7023                final UriPermission perm = it.next();
7024                if (perm.uri.sourceUserId == grantUri.sourceUserId
7025                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7026                    if (DEBUG_URI_PERMISSION)
7027                        Slog.v(TAG,
7028                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7029                    persistChanged |= perm.revokeModes(
7030                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7031                    if (perm.modeFlags == 0) {
7032                        it.remove();
7033                    }
7034                }
7035            }
7036
7037            if (perms.isEmpty()) {
7038                mGrantedUriPermissions.remove(targetUid);
7039                N--;
7040                i--;
7041            }
7042        }
7043
7044        if (persistChanged) {
7045            schedulePersistUriGrants();
7046        }
7047    }
7048
7049    @Override
7050    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7051            int userId) {
7052        enforceNotIsolatedCaller("revokeUriPermission");
7053        synchronized(this) {
7054            final ProcessRecord r = getRecordForAppLocked(caller);
7055            if (r == null) {
7056                throw new SecurityException("Unable to find app for caller "
7057                        + caller
7058                        + " when revoking permission to uri " + uri);
7059            }
7060            if (uri == null) {
7061                Slog.w(TAG, "revokeUriPermission: null uri");
7062                return;
7063            }
7064
7065            if (!Intent.isAccessUriMode(modeFlags)) {
7066                return;
7067            }
7068
7069            final IPackageManager pm = AppGlobals.getPackageManager();
7070            final String authority = uri.getAuthority();
7071            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7072            if (pi == null) {
7073                Slog.w(TAG, "No content provider found for permission revoke: "
7074                        + uri.toSafeString());
7075                return;
7076            }
7077
7078            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7079        }
7080    }
7081
7082    /**
7083     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7084     * given package.
7085     *
7086     * @param packageName Package name to match, or {@code null} to apply to all
7087     *            packages.
7088     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7089     *            to all users.
7090     * @param persistable If persistable grants should be removed.
7091     */
7092    private void removeUriPermissionsForPackageLocked(
7093            String packageName, int userHandle, boolean persistable) {
7094        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7095            throw new IllegalArgumentException("Must narrow by either package or user");
7096        }
7097
7098        boolean persistChanged = false;
7099
7100        int N = mGrantedUriPermissions.size();
7101        for (int i = 0; i < N; i++) {
7102            final int targetUid = mGrantedUriPermissions.keyAt(i);
7103            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7104
7105            // Only inspect grants matching user
7106            if (userHandle == UserHandle.USER_ALL
7107                    || userHandle == UserHandle.getUserId(targetUid)) {
7108                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7109                    final UriPermission perm = it.next();
7110
7111                    // Only inspect grants matching package
7112                    if (packageName == null || perm.sourcePkg.equals(packageName)
7113                            || perm.targetPkg.equals(packageName)) {
7114                        persistChanged |= perm.revokeModes(
7115                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7116
7117                        // Only remove when no modes remain; any persisted grants
7118                        // will keep this alive.
7119                        if (perm.modeFlags == 0) {
7120                            it.remove();
7121                        }
7122                    }
7123                }
7124
7125                if (perms.isEmpty()) {
7126                    mGrantedUriPermissions.remove(targetUid);
7127                    N--;
7128                    i--;
7129                }
7130            }
7131        }
7132
7133        if (persistChanged) {
7134            schedulePersistUriGrants();
7135        }
7136    }
7137
7138    @Override
7139    public IBinder newUriPermissionOwner(String name) {
7140        enforceNotIsolatedCaller("newUriPermissionOwner");
7141        synchronized(this) {
7142            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7143            return owner.getExternalTokenLocked();
7144        }
7145    }
7146
7147    @Override
7148    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7149            final int modeFlags, int sourceUserId, int targetUserId) {
7150        synchronized(this) {
7151            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7152            if (owner == null) {
7153                throw new IllegalArgumentException("Unknown owner: " + token);
7154            }
7155            if (fromUid != Binder.getCallingUid()) {
7156                if (Binder.getCallingUid() != Process.myUid()) {
7157                    // Only system code can grant URI permissions on behalf
7158                    // of other users.
7159                    throw new SecurityException("nice try");
7160                }
7161            }
7162            if (targetPkg == null) {
7163                throw new IllegalArgumentException("null target");
7164            }
7165            if (uri == null) {
7166                throw new IllegalArgumentException("null uri");
7167            }
7168
7169            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7170                    modeFlags, owner, targetUserId);
7171        }
7172    }
7173
7174    @Override
7175    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7176        synchronized(this) {
7177            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7178            if (owner == null) {
7179                throw new IllegalArgumentException("Unknown owner: " + token);
7180            }
7181
7182            if (uri == null) {
7183                owner.removeUriPermissionsLocked(mode);
7184            } else {
7185                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7186            }
7187        }
7188    }
7189
7190    private void schedulePersistUriGrants() {
7191        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7192            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7193                    10 * DateUtils.SECOND_IN_MILLIS);
7194        }
7195    }
7196
7197    private void writeGrantedUriPermissions() {
7198        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7199
7200        // Snapshot permissions so we can persist without lock
7201        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7202        synchronized (this) {
7203            final int size = mGrantedUriPermissions.size();
7204            for (int i = 0; i < size; i++) {
7205                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7206                for (UriPermission perm : perms.values()) {
7207                    if (perm.persistedModeFlags != 0) {
7208                        persist.add(perm.snapshot());
7209                    }
7210                }
7211            }
7212        }
7213
7214        FileOutputStream fos = null;
7215        try {
7216            fos = mGrantFile.startWrite();
7217
7218            XmlSerializer out = new FastXmlSerializer();
7219            out.setOutput(fos, "utf-8");
7220            out.startDocument(null, true);
7221            out.startTag(null, TAG_URI_GRANTS);
7222            for (UriPermission.Snapshot perm : persist) {
7223                out.startTag(null, TAG_URI_GRANT);
7224                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7225                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7226                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7227                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7228                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7229                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7230                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7231                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7232                out.endTag(null, TAG_URI_GRANT);
7233            }
7234            out.endTag(null, TAG_URI_GRANTS);
7235            out.endDocument();
7236
7237            mGrantFile.finishWrite(fos);
7238        } catch (IOException e) {
7239            if (fos != null) {
7240                mGrantFile.failWrite(fos);
7241            }
7242        }
7243    }
7244
7245    private void readGrantedUriPermissionsLocked() {
7246        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7247
7248        final long now = System.currentTimeMillis();
7249
7250        FileInputStream fis = null;
7251        try {
7252            fis = mGrantFile.openRead();
7253            final XmlPullParser in = Xml.newPullParser();
7254            in.setInput(fis, null);
7255
7256            int type;
7257            while ((type = in.next()) != END_DOCUMENT) {
7258                final String tag = in.getName();
7259                if (type == START_TAG) {
7260                    if (TAG_URI_GRANT.equals(tag)) {
7261                        final int sourceUserId;
7262                        final int targetUserId;
7263                        final int userHandle = readIntAttribute(in,
7264                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7265                        if (userHandle != UserHandle.USER_NULL) {
7266                            // For backwards compatibility.
7267                            sourceUserId = userHandle;
7268                            targetUserId = userHandle;
7269                        } else {
7270                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7271                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7272                        }
7273                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7274                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7275                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7276                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7277                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7278                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7279
7280                        // Sanity check that provider still belongs to source package
7281                        final ProviderInfo pi = getProviderInfoLocked(
7282                                uri.getAuthority(), sourceUserId);
7283                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7284                            int targetUid = -1;
7285                            try {
7286                                targetUid = AppGlobals.getPackageManager()
7287                                        .getPackageUid(targetPkg, targetUserId);
7288                            } catch (RemoteException e) {
7289                            }
7290                            if (targetUid != -1) {
7291                                final UriPermission perm = findOrCreateUriPermissionLocked(
7292                                        sourcePkg, targetPkg, targetUid,
7293                                        new GrantUri(sourceUserId, uri, prefix));
7294                                perm.initPersistedModes(modeFlags, createdTime);
7295                            }
7296                        } else {
7297                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7298                                    + " but instead found " + pi);
7299                        }
7300                    }
7301                }
7302            }
7303        } catch (FileNotFoundException e) {
7304            // Missing grants is okay
7305        } catch (IOException e) {
7306            Log.wtf(TAG, "Failed reading Uri grants", e);
7307        } catch (XmlPullParserException e) {
7308            Log.wtf(TAG, "Failed reading Uri grants", e);
7309        } finally {
7310            IoUtils.closeQuietly(fis);
7311        }
7312    }
7313
7314    @Override
7315    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7316        enforceNotIsolatedCaller("takePersistableUriPermission");
7317
7318        Preconditions.checkFlagsArgument(modeFlags,
7319                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7320
7321        synchronized (this) {
7322            final int callingUid = Binder.getCallingUid();
7323            boolean persistChanged = false;
7324            GrantUri grantUri = new GrantUri(userId, uri, false);
7325
7326            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7327                    new GrantUri(userId, uri, false));
7328            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7329                    new GrantUri(userId, uri, true));
7330
7331            final boolean exactValid = (exactPerm != null)
7332                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7333            final boolean prefixValid = (prefixPerm != null)
7334                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7335
7336            if (!(exactValid || prefixValid)) {
7337                throw new SecurityException("No persistable permission grants found for UID "
7338                        + callingUid + " and Uri " + grantUri.toSafeString());
7339            }
7340
7341            if (exactValid) {
7342                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7343            }
7344            if (prefixValid) {
7345                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7346            }
7347
7348            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7349
7350            if (persistChanged) {
7351                schedulePersistUriGrants();
7352            }
7353        }
7354    }
7355
7356    @Override
7357    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7358        enforceNotIsolatedCaller("releasePersistableUriPermission");
7359
7360        Preconditions.checkFlagsArgument(modeFlags,
7361                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7362
7363        synchronized (this) {
7364            final int callingUid = Binder.getCallingUid();
7365            boolean persistChanged = false;
7366
7367            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7368                    new GrantUri(userId, uri, false));
7369            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7370                    new GrantUri(userId, uri, true));
7371            if (exactPerm == null && prefixPerm == null) {
7372                throw new SecurityException("No permission grants found for UID " + callingUid
7373                        + " and Uri " + uri.toSafeString());
7374            }
7375
7376            if (exactPerm != null) {
7377                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7378                removeUriPermissionIfNeededLocked(exactPerm);
7379            }
7380            if (prefixPerm != null) {
7381                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7382                removeUriPermissionIfNeededLocked(prefixPerm);
7383            }
7384
7385            if (persistChanged) {
7386                schedulePersistUriGrants();
7387            }
7388        }
7389    }
7390
7391    /**
7392     * Prune any older {@link UriPermission} for the given UID until outstanding
7393     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7394     *
7395     * @return if any mutations occured that require persisting.
7396     */
7397    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7398        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7399        if (perms == null) return false;
7400        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7401
7402        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7403        for (UriPermission perm : perms.values()) {
7404            if (perm.persistedModeFlags != 0) {
7405                persisted.add(perm);
7406            }
7407        }
7408
7409        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7410        if (trimCount <= 0) return false;
7411
7412        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7413        for (int i = 0; i < trimCount; i++) {
7414            final UriPermission perm = persisted.get(i);
7415
7416            if (DEBUG_URI_PERMISSION) {
7417                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7418            }
7419
7420            perm.releasePersistableModes(~0);
7421            removeUriPermissionIfNeededLocked(perm);
7422        }
7423
7424        return true;
7425    }
7426
7427    @Override
7428    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7429            String packageName, boolean incoming) {
7430        enforceNotIsolatedCaller("getPersistedUriPermissions");
7431        Preconditions.checkNotNull(packageName, "packageName");
7432
7433        final int callingUid = Binder.getCallingUid();
7434        final IPackageManager pm = AppGlobals.getPackageManager();
7435        try {
7436            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7437            if (packageUid != callingUid) {
7438                throw new SecurityException(
7439                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7440            }
7441        } catch (RemoteException e) {
7442            throw new SecurityException("Failed to verify package name ownership");
7443        }
7444
7445        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7446        synchronized (this) {
7447            if (incoming) {
7448                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7449                        callingUid);
7450                if (perms == null) {
7451                    Slog.w(TAG, "No permission grants found for " + packageName);
7452                } else {
7453                    for (UriPermission perm : perms.values()) {
7454                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7455                            result.add(perm.buildPersistedPublicApiObject());
7456                        }
7457                    }
7458                }
7459            } else {
7460                final int size = mGrantedUriPermissions.size();
7461                for (int i = 0; i < size; i++) {
7462                    final ArrayMap<GrantUri, UriPermission> perms =
7463                            mGrantedUriPermissions.valueAt(i);
7464                    for (UriPermission perm : perms.values()) {
7465                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7466                            result.add(perm.buildPersistedPublicApiObject());
7467                        }
7468                    }
7469                }
7470            }
7471        }
7472        return new ParceledListSlice<android.content.UriPermission>(result);
7473    }
7474
7475    @Override
7476    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7477        synchronized (this) {
7478            ProcessRecord app =
7479                who != null ? getRecordForAppLocked(who) : null;
7480            if (app == null) return;
7481
7482            Message msg = Message.obtain();
7483            msg.what = WAIT_FOR_DEBUGGER_MSG;
7484            msg.obj = app;
7485            msg.arg1 = waiting ? 1 : 0;
7486            mHandler.sendMessage(msg);
7487        }
7488    }
7489
7490    @Override
7491    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7492        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7493        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7494        outInfo.availMem = Process.getFreeMemory();
7495        outInfo.totalMem = Process.getTotalMemory();
7496        outInfo.threshold = homeAppMem;
7497        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7498        outInfo.hiddenAppThreshold = cachedAppMem;
7499        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7500                ProcessList.SERVICE_ADJ);
7501        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7502                ProcessList.VISIBLE_APP_ADJ);
7503        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7504                ProcessList.FOREGROUND_APP_ADJ);
7505    }
7506
7507    // =========================================================
7508    // TASK MANAGEMENT
7509    // =========================================================
7510
7511    @Override
7512    public List<IAppTask> getAppTasks() {
7513        final PackageManager pm = mContext.getPackageManager();
7514        int callingUid = Binder.getCallingUid();
7515        long ident = Binder.clearCallingIdentity();
7516
7517        // Compose the list of packages for this id to test against
7518        HashSet<String> packages = new HashSet<String>();
7519        String[] uidPackages = pm.getPackagesForUid(callingUid);
7520        for (int i = 0; i < uidPackages.length; i++) {
7521            packages.add(uidPackages[i]);
7522        }
7523
7524        synchronized(this) {
7525            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7526            try {
7527                if (localLOGV) Slog.v(TAG, "getAppTasks");
7528
7529                final int N = mRecentTasks.size();
7530                for (int i = 0; i < N; i++) {
7531                    TaskRecord tr = mRecentTasks.get(i);
7532                    // Skip tasks that do not match the package name
7533                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7534                        ActivityManager.RecentTaskInfo taskInfo =
7535                                createRecentTaskInfoFromTaskRecord(tr);
7536                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7537                        list.add(taskImpl);
7538                    }
7539                }
7540            } finally {
7541                Binder.restoreCallingIdentity(ident);
7542            }
7543            return list;
7544        }
7545    }
7546
7547    @Override
7548    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7549        final int callingUid = Binder.getCallingUid();
7550        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7551
7552        synchronized(this) {
7553            if (localLOGV) Slog.v(
7554                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7555
7556            final boolean allowed = checkCallingPermission(
7557                    android.Manifest.permission.GET_TASKS)
7558                    == PackageManager.PERMISSION_GRANTED;
7559            if (!allowed) {
7560                Slog.w(TAG, "getTasks: caller " + callingUid
7561                        + " does not hold GET_TASKS; limiting output");
7562            }
7563
7564            // TODO: Improve with MRU list from all ActivityStacks.
7565            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7566        }
7567
7568        return list;
7569    }
7570
7571    TaskRecord getMostRecentTask() {
7572        return mRecentTasks.get(0);
7573    }
7574
7575    /**
7576     * Creates a new RecentTaskInfo from a TaskRecord.
7577     */
7578    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7579        // Update the task description to reflect any changes in the task stack
7580        tr.updateTaskDescription();
7581
7582        // Compose the recent task info
7583        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7584        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7585        rti.persistentId = tr.taskId;
7586        rti.baseIntent = new Intent(tr.getBaseIntent());
7587        rti.origActivity = tr.origActivity;
7588        rti.description = tr.lastDescription;
7589        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7590        rti.userId = tr.userId;
7591        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7592        rti.firstActiveTime = tr.firstActiveTime;
7593        rti.lastActiveTime = tr.lastActiveTime;
7594        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7595        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7596        return rti;
7597    }
7598
7599    @Override
7600    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7601        final int callingUid = Binder.getCallingUid();
7602        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7603                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7604
7605        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7606        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7607        synchronized (this) {
7608            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7609                    == PackageManager.PERMISSION_GRANTED;
7610            if (!allowed) {
7611                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7612                        + " does not hold GET_TASKS; limiting output");
7613            }
7614            final boolean detailed = checkCallingPermission(
7615                    android.Manifest.permission.GET_DETAILED_TASKS)
7616                    == PackageManager.PERMISSION_GRANTED;
7617
7618            IPackageManager pm = AppGlobals.getPackageManager();
7619
7620            final int N = mRecentTasks.size();
7621            ArrayList<ActivityManager.RecentTaskInfo> res
7622                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7623                            maxNum < N ? maxNum : N);
7624
7625            final Set<Integer> includedUsers;
7626            if (includeProfiles) {
7627                includedUsers = getProfileIdsLocked(userId);
7628            } else {
7629                includedUsers = new HashSet<Integer>();
7630            }
7631            includedUsers.add(Integer.valueOf(userId));
7632
7633            // Regroup affiliated tasks together.
7634            for (int i = 0; i < N; ) {
7635                TaskRecord task = mRecentTasks.remove(i);
7636                if (mTmpRecents.contains(task)) {
7637                    continue;
7638                }
7639                int affiliatedTaskId = task.mAffiliatedTaskId;
7640                while (true) {
7641                    TaskRecord next = task.mNextAffiliate;
7642                    if (next == null) {
7643                        break;
7644                    }
7645                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7646                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7647                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7648                        task.setNextAffiliate(null);
7649                        if (next.mPrevAffiliate == task) {
7650                            next.setPrevAffiliate(null);
7651                        }
7652                        break;
7653                    }
7654                    if (next.mPrevAffiliate != task) {
7655                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7656                                next.mPrevAffiliate + " task=" + task);
7657                        next.setPrevAffiliate(null);
7658                        break;
7659                    }
7660                    if (!mRecentTasks.contains(next)) {
7661                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7662                        task.setNextAffiliate(null);
7663                        if (next.mPrevAffiliate == task) {
7664                            next.setPrevAffiliate(null);
7665                        }
7666                        break;
7667                    }
7668                    task = next;
7669                }
7670                // task is now the end of the list
7671                do {
7672                    mRecentTasks.remove(task);
7673                    mRecentTasks.add(i++, task);
7674                    mTmpRecents.add(task);
7675                } while ((task = task.mPrevAffiliate) != null);
7676            }
7677            mTmpRecents.clear();
7678            // mRecentTasks is now in sorted, affiliated order.
7679
7680            for (int i=0; i<N && maxNum > 0; i++) {
7681                TaskRecord tr = mRecentTasks.get(i);
7682                // Only add calling user or related users recent tasks
7683                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7684                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7685                    continue;
7686                }
7687
7688                // Return the entry if desired by the caller.  We always return
7689                // the first entry, because callers always expect this to be the
7690                // foreground app.  We may filter others if the caller has
7691                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7692                // we should exclude the entry.
7693
7694                if (i == 0
7695                        || withExcluded
7696                        || (tr.intent == null)
7697                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7698                                == 0)) {
7699                    if (!allowed) {
7700                        // If the caller doesn't have the GET_TASKS permission, then only
7701                        // allow them to see a small subset of tasks -- their own and home.
7702                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7703                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7704                            continue;
7705                        }
7706                    }
7707                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7708                        // Don't include auto remove tasks that are finished or finishing.
7709                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7710                                + tr);
7711                        continue;
7712                    }
7713
7714                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7715                    if (!detailed) {
7716                        rti.baseIntent.replaceExtras((Bundle)null);
7717                    }
7718
7719                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7720                        // Check whether this activity is currently available.
7721                        try {
7722                            if (rti.origActivity != null) {
7723                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7724                                        == null) {
7725                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail orig act: "
7726                                            + tr);
7727                                    continue;
7728                                }
7729                            } else if (rti.baseIntent != null) {
7730                                if (pm.queryIntentActivities(rti.baseIntent,
7731                                        null, 0, userId) == null) {
7732                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail intent: "
7733                                            + tr);
7734                                    continue;
7735                                }
7736                            }
7737                        } catch (RemoteException e) {
7738                            // Will never happen.
7739                        }
7740                    }
7741
7742                    res.add(rti);
7743                    maxNum--;
7744                }
7745            }
7746            return res;
7747        }
7748    }
7749
7750    private TaskRecord recentTaskForIdLocked(int id) {
7751        final int N = mRecentTasks.size();
7752            for (int i=0; i<N; i++) {
7753                TaskRecord tr = mRecentTasks.get(i);
7754                if (tr.taskId == id) {
7755                    return tr;
7756                }
7757            }
7758            return null;
7759    }
7760
7761    @Override
7762    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7763        synchronized (this) {
7764            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7765                    "getTaskThumbnail()");
7766            TaskRecord tr = recentTaskForIdLocked(id);
7767            if (tr != null) {
7768                return tr.getTaskThumbnailLocked();
7769            }
7770        }
7771        return null;
7772    }
7773
7774    @Override
7775    public int addAppTask(IBinder activityToken, Intent intent,
7776            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7777        final int callingUid = Binder.getCallingUid();
7778        final long callingIdent = Binder.clearCallingIdentity();
7779
7780        try {
7781            synchronized (this) {
7782                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7783                if (r == null) {
7784                    throw new IllegalArgumentException("Activity does not exist; token="
7785                            + activityToken);
7786                }
7787                ComponentName comp = intent.getComponent();
7788                if (comp == null) {
7789                    throw new IllegalArgumentException("Intent " + intent
7790                            + " must specify explicit component");
7791                }
7792                if (thumbnail.getWidth() != mThumbnailWidth
7793                        || thumbnail.getHeight() != mThumbnailHeight) {
7794                    throw new IllegalArgumentException("Bad thumbnail size: got "
7795                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7796                            + mThumbnailWidth + "x" + mThumbnailHeight);
7797                }
7798                if (intent.getSelector() != null) {
7799                    intent.setSelector(null);
7800                }
7801                if (intent.getSourceBounds() != null) {
7802                    intent.setSourceBounds(null);
7803                }
7804                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7805                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7806                        // The caller has added this as an auto-remove task...  that makes no
7807                        // sense, so turn off auto-remove.
7808                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7809                    }
7810                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7811                    // Must be a new task.
7812                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7813                }
7814                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7815                    mLastAddedTaskActivity = null;
7816                }
7817                ActivityInfo ainfo = mLastAddedTaskActivity;
7818                if (ainfo == null) {
7819                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7820                            comp, 0, UserHandle.getUserId(callingUid));
7821                    if (ainfo.applicationInfo.uid != callingUid) {
7822                        throw new SecurityException(
7823                                "Can't add task for another application: target uid="
7824                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7825                    }
7826                }
7827
7828                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7829                        intent, description);
7830
7831                int trimIdx = trimRecentsForTask(task, false);
7832                if (trimIdx >= 0) {
7833                    // If this would have caused a trim, then we'll abort because that
7834                    // means it would be added at the end of the list but then just removed.
7835                    return -1;
7836                }
7837
7838                final int N = mRecentTasks.size();
7839                if (N >= (MAX_RECENT_TASKS-1)) {
7840                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7841                    tr.disposeThumbnail();
7842                    tr.closeRecentsChain();
7843                }
7844
7845                mRecentTasks.add(task);
7846                r.task.stack.addTask(task, false, false);
7847
7848                task.setLastThumbnail(thumbnail);
7849                task.freeLastThumbnail();
7850
7851                return task.taskId;
7852            }
7853        } finally {
7854            Binder.restoreCallingIdentity(callingIdent);
7855        }
7856    }
7857
7858    @Override
7859    public Point getAppTaskThumbnailSize() {
7860        synchronized (this) {
7861            return new Point(mThumbnailWidth,  mThumbnailHeight);
7862        }
7863    }
7864
7865    @Override
7866    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7867        synchronized (this) {
7868            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7869            if (r != null) {
7870                r.taskDescription = td;
7871                r.task.updateTaskDescription();
7872            }
7873        }
7874    }
7875
7876    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7877        if (!pr.killedByAm) {
7878            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7879            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7880                    pr.processName, pr.setAdj, reason);
7881            pr.killedByAm = true;
7882            Process.killProcessQuiet(pr.pid);
7883            Process.killProcessGroup(pr.info.uid, pr.pid);
7884        }
7885    }
7886
7887    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7888        tr.disposeThumbnail();
7889        mRecentTasks.remove(tr);
7890        tr.closeRecentsChain();
7891        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7892        Intent baseIntent = new Intent(
7893                tr.intent != null ? tr.intent : tr.affinityIntent);
7894        ComponentName component = baseIntent.getComponent();
7895        if (component == null) {
7896            Slog.w(TAG, "Now component for base intent of task: " + tr);
7897            return;
7898        }
7899
7900        // Find any running services associated with this app.
7901        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7902
7903        if (killProcesses) {
7904            // Find any running processes associated with this app.
7905            final String pkg = component.getPackageName();
7906            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7907            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7908            for (int i=0; i<pmap.size(); i++) {
7909                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7910                for (int j=0; j<uids.size(); j++) {
7911                    ProcessRecord proc = uids.valueAt(j);
7912                    if (proc.userId != tr.userId) {
7913                        continue;
7914                    }
7915                    if (!proc.pkgList.containsKey(pkg)) {
7916                        continue;
7917                    }
7918                    procs.add(proc);
7919                }
7920            }
7921
7922            // Kill the running processes.
7923            for (int i=0; i<procs.size(); i++) {
7924                ProcessRecord pr = procs.get(i);
7925                if (pr == mHomeProcess) {
7926                    // Don't kill the home process along with tasks from the same package.
7927                    continue;
7928                }
7929                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7930                    killUnneededProcessLocked(pr, "remove task");
7931                } else {
7932                    pr.waitingToKill = "remove task";
7933                }
7934            }
7935        }
7936    }
7937
7938    /**
7939     * Removes the task with the specified task id.
7940     *
7941     * @param taskId Identifier of the task to be removed.
7942     * @param flags Additional operational flags.  May be 0 or
7943     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7944     * @return Returns true if the given task was found and removed.
7945     */
7946    private boolean removeTaskByIdLocked(int taskId, int flags) {
7947        TaskRecord tr = recentTaskForIdLocked(taskId);
7948        if (tr != null) {
7949            tr.removeTaskActivitiesLocked();
7950            cleanUpRemovedTaskLocked(tr, flags);
7951            if (tr.isPersistable) {
7952                notifyTaskPersisterLocked(null, true);
7953            }
7954            return true;
7955        }
7956        return false;
7957    }
7958
7959    @Override
7960    public boolean removeTask(int taskId, int flags) {
7961        synchronized (this) {
7962            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7963                    "removeTask()");
7964            long ident = Binder.clearCallingIdentity();
7965            try {
7966                return removeTaskByIdLocked(taskId, flags);
7967            } finally {
7968                Binder.restoreCallingIdentity(ident);
7969            }
7970        }
7971    }
7972
7973    /**
7974     * TODO: Add mController hook
7975     */
7976    @Override
7977    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7978        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7979                "moveTaskToFront()");
7980
7981        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7982        synchronized(this) {
7983            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7984                    Binder.getCallingUid(), "Task to front")) {
7985                ActivityOptions.abort(options);
7986                return;
7987            }
7988            final long origId = Binder.clearCallingIdentity();
7989            try {
7990                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7991                if (task == null) {
7992                    return;
7993                }
7994                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7995                    mStackSupervisor.showLockTaskToast();
7996                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7997                    return;
7998                }
7999                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8000                if (prev != null && prev.isRecentsActivity()) {
8001                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8002                }
8003                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8004            } finally {
8005                Binder.restoreCallingIdentity(origId);
8006            }
8007            ActivityOptions.abort(options);
8008        }
8009    }
8010
8011    @Override
8012    public void moveTaskToBack(int taskId) {
8013        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8014                "moveTaskToBack()");
8015
8016        synchronized(this) {
8017            TaskRecord tr = recentTaskForIdLocked(taskId);
8018            if (tr != null) {
8019                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8020                ActivityStack stack = tr.stack;
8021                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8022                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8023                            Binder.getCallingUid(), "Task to back")) {
8024                        return;
8025                    }
8026                }
8027                final long origId = Binder.clearCallingIdentity();
8028                try {
8029                    stack.moveTaskToBackLocked(taskId, null);
8030                } finally {
8031                    Binder.restoreCallingIdentity(origId);
8032                }
8033            }
8034        }
8035    }
8036
8037    /**
8038     * Moves an activity, and all of the other activities within the same task, to the bottom
8039     * of the history stack.  The activity's order within the task is unchanged.
8040     *
8041     * @param token A reference to the activity we wish to move
8042     * @param nonRoot If false then this only works if the activity is the root
8043     *                of a task; if true it will work for any activity in a task.
8044     * @return Returns true if the move completed, false if not.
8045     */
8046    @Override
8047    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8048        enforceNotIsolatedCaller("moveActivityTaskToBack");
8049        synchronized(this) {
8050            final long origId = Binder.clearCallingIdentity();
8051            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8052            if (taskId >= 0) {
8053                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8054            }
8055            Binder.restoreCallingIdentity(origId);
8056        }
8057        return false;
8058    }
8059
8060    @Override
8061    public void moveTaskBackwards(int task) {
8062        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8063                "moveTaskBackwards()");
8064
8065        synchronized(this) {
8066            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8067                    Binder.getCallingUid(), "Task backwards")) {
8068                return;
8069            }
8070            final long origId = Binder.clearCallingIdentity();
8071            moveTaskBackwardsLocked(task);
8072            Binder.restoreCallingIdentity(origId);
8073        }
8074    }
8075
8076    private final void moveTaskBackwardsLocked(int task) {
8077        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8078    }
8079
8080    @Override
8081    public IBinder getHomeActivityToken() throws RemoteException {
8082        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8083                "getHomeActivityToken()");
8084        synchronized (this) {
8085            return mStackSupervisor.getHomeActivityToken();
8086        }
8087    }
8088
8089    @Override
8090    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8091            IActivityContainerCallback callback) throws RemoteException {
8092        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8093                "createActivityContainer()");
8094        synchronized (this) {
8095            if (parentActivityToken == null) {
8096                throw new IllegalArgumentException("parent token must not be null");
8097            }
8098            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8099            if (r == null) {
8100                return null;
8101            }
8102            if (callback == null) {
8103                throw new IllegalArgumentException("callback must not be null");
8104            }
8105            return mStackSupervisor.createActivityContainer(r, callback);
8106        }
8107    }
8108
8109    @Override
8110    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8111        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8112                "deleteActivityContainer()");
8113        synchronized (this) {
8114            mStackSupervisor.deleteActivityContainer(container);
8115        }
8116    }
8117
8118    @Override
8119    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8120            throws RemoteException {
8121        synchronized (this) {
8122            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8123            if (stack != null) {
8124                return stack.mActivityContainer;
8125            }
8126            return null;
8127        }
8128    }
8129
8130    @Override
8131    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8132        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8133                "moveTaskToStack()");
8134        if (stackId == HOME_STACK_ID) {
8135            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8136                    new RuntimeException("here").fillInStackTrace());
8137        }
8138        synchronized (this) {
8139            long ident = Binder.clearCallingIdentity();
8140            try {
8141                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8142                        + stackId + " toTop=" + toTop);
8143                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8144            } finally {
8145                Binder.restoreCallingIdentity(ident);
8146            }
8147        }
8148    }
8149
8150    @Override
8151    public void resizeStack(int stackBoxId, Rect bounds) {
8152        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8153                "resizeStackBox()");
8154        long ident = Binder.clearCallingIdentity();
8155        try {
8156            mWindowManager.resizeStack(stackBoxId, bounds);
8157        } finally {
8158            Binder.restoreCallingIdentity(ident);
8159        }
8160    }
8161
8162    @Override
8163    public List<StackInfo> getAllStackInfos() {
8164        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8165                "getAllStackInfos()");
8166        long ident = Binder.clearCallingIdentity();
8167        try {
8168            synchronized (this) {
8169                return mStackSupervisor.getAllStackInfosLocked();
8170            }
8171        } finally {
8172            Binder.restoreCallingIdentity(ident);
8173        }
8174    }
8175
8176    @Override
8177    public StackInfo getStackInfo(int stackId) {
8178        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8179                "getStackInfo()");
8180        long ident = Binder.clearCallingIdentity();
8181        try {
8182            synchronized (this) {
8183                return mStackSupervisor.getStackInfoLocked(stackId);
8184            }
8185        } finally {
8186            Binder.restoreCallingIdentity(ident);
8187        }
8188    }
8189
8190    @Override
8191    public boolean isInHomeStack(int taskId) {
8192        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8193                "getStackInfo()");
8194        long ident = Binder.clearCallingIdentity();
8195        try {
8196            synchronized (this) {
8197                TaskRecord tr = recentTaskForIdLocked(taskId);
8198                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8199            }
8200        } finally {
8201            Binder.restoreCallingIdentity(ident);
8202        }
8203    }
8204
8205    @Override
8206    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8207        synchronized(this) {
8208            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8209        }
8210    }
8211
8212    private boolean isLockTaskAuthorized(String pkg) {
8213        final DevicePolicyManager dpm = (DevicePolicyManager)
8214                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8215        try {
8216            int uid = mContext.getPackageManager().getPackageUid(pkg,
8217                    Binder.getCallingUserHandle().getIdentifier());
8218            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8219        } catch (NameNotFoundException e) {
8220            return false;
8221        }
8222    }
8223
8224    void startLockTaskMode(TaskRecord task) {
8225        final String pkg;
8226        synchronized (this) {
8227            pkg = task.intent.getComponent().getPackageName();
8228        }
8229        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8230        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8231            final TaskRecord taskRecord = task;
8232            mHandler.post(new Runnable() {
8233                @Override
8234                public void run() {
8235                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8236                }
8237            });
8238            return;
8239        }
8240        long ident = Binder.clearCallingIdentity();
8241        try {
8242            synchronized (this) {
8243                // Since we lost lock on task, make sure it is still there.
8244                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8245                if (task != null) {
8246                    if (!isSystemInitiated
8247                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8248                        throw new IllegalArgumentException("Invalid task, not in foreground");
8249                    }
8250                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8251                }
8252            }
8253        } finally {
8254            Binder.restoreCallingIdentity(ident);
8255        }
8256    }
8257
8258    @Override
8259    public void startLockTaskMode(int taskId) {
8260        final TaskRecord task;
8261        long ident = Binder.clearCallingIdentity();
8262        try {
8263            synchronized (this) {
8264                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8265            }
8266        } finally {
8267            Binder.restoreCallingIdentity(ident);
8268        }
8269        if (task != null) {
8270            startLockTaskMode(task);
8271        }
8272    }
8273
8274    @Override
8275    public void startLockTaskMode(IBinder token) {
8276        final TaskRecord task;
8277        long ident = Binder.clearCallingIdentity();
8278        try {
8279            synchronized (this) {
8280                final ActivityRecord r = ActivityRecord.forToken(token);
8281                if (r == null) {
8282                    return;
8283                }
8284                task = r.task;
8285            }
8286        } finally {
8287            Binder.restoreCallingIdentity(ident);
8288        }
8289        if (task != null) {
8290            startLockTaskMode(task);
8291        }
8292    }
8293
8294    @Override
8295    public void startLockTaskModeOnCurrent() throws RemoteException {
8296        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8297        ActivityRecord r = null;
8298        synchronized (this) {
8299            r = mStackSupervisor.topRunningActivityLocked();
8300        }
8301        startLockTaskMode(r.task);
8302    }
8303
8304    @Override
8305    public void stopLockTaskMode() {
8306        // Verify that the user matches the package of the intent for the TaskRecord
8307        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8308        // and stopLockTaskMode.
8309        final int callingUid = Binder.getCallingUid();
8310        if (callingUid != Process.SYSTEM_UID) {
8311            try {
8312                String pkg =
8313                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8314                int uid = mContext.getPackageManager().getPackageUid(pkg,
8315                        Binder.getCallingUserHandle().getIdentifier());
8316                if (uid != callingUid) {
8317                    throw new SecurityException("Invalid uid, expected " + uid);
8318                }
8319            } catch (NameNotFoundException e) {
8320                Log.d(TAG, "stopLockTaskMode " + e);
8321                return;
8322            }
8323        }
8324        long ident = Binder.clearCallingIdentity();
8325        try {
8326            Log.d(TAG, "stopLockTaskMode");
8327            // Stop lock task
8328            synchronized (this) {
8329                mStackSupervisor.setLockTaskModeLocked(null, false);
8330            }
8331        } finally {
8332            Binder.restoreCallingIdentity(ident);
8333        }
8334    }
8335
8336    @Override
8337    public void stopLockTaskModeOnCurrent() throws RemoteException {
8338        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8339        long ident = Binder.clearCallingIdentity();
8340        try {
8341            stopLockTaskMode();
8342        } finally {
8343            Binder.restoreCallingIdentity(ident);
8344        }
8345    }
8346
8347    @Override
8348    public boolean isInLockTaskMode() {
8349        synchronized (this) {
8350            return mStackSupervisor.isInLockTaskMode();
8351        }
8352    }
8353
8354    // =========================================================
8355    // CONTENT PROVIDERS
8356    // =========================================================
8357
8358    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8359        List<ProviderInfo> providers = null;
8360        try {
8361            providers = AppGlobals.getPackageManager().
8362                queryContentProviders(app.processName, app.uid,
8363                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8364        } catch (RemoteException ex) {
8365        }
8366        if (DEBUG_MU)
8367            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8368        int userId = app.userId;
8369        if (providers != null) {
8370            int N = providers.size();
8371            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8372            for (int i=0; i<N; i++) {
8373                ProviderInfo cpi =
8374                    (ProviderInfo)providers.get(i);
8375                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8376                        cpi.name, cpi.flags);
8377                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8378                    // This is a singleton provider, but a user besides the
8379                    // default user is asking to initialize a process it runs
8380                    // in...  well, no, it doesn't actually run in this process,
8381                    // it runs in the process of the default user.  Get rid of it.
8382                    providers.remove(i);
8383                    N--;
8384                    i--;
8385                    continue;
8386                }
8387
8388                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8389                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8390                if (cpr == null) {
8391                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8392                    mProviderMap.putProviderByClass(comp, cpr);
8393                }
8394                if (DEBUG_MU)
8395                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8396                app.pubProviders.put(cpi.name, cpr);
8397                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8398                    // Don't add this if it is a platform component that is marked
8399                    // to run in multiple processes, because this is actually
8400                    // part of the framework so doesn't make sense to track as a
8401                    // separate apk in the process.
8402                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8403                            mProcessStats);
8404                }
8405                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8406            }
8407        }
8408        return providers;
8409    }
8410
8411    /**
8412     * Check if {@link ProcessRecord} has a possible chance at accessing the
8413     * given {@link ProviderInfo}. Final permission checking is always done
8414     * in {@link ContentProvider}.
8415     */
8416    private final String checkContentProviderPermissionLocked(
8417            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8418        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8419        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8420        boolean checkedGrants = false;
8421        if (checkUser) {
8422            // Looking for cross-user grants before enforcing the typical cross-users permissions
8423            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8424            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8425                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8426                    return null;
8427                }
8428                checkedGrants = true;
8429            }
8430            userId = handleIncomingUser(callingPid, callingUid, userId,
8431                    false, ALLOW_NON_FULL,
8432                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8433            if (userId != tmpTargetUserId) {
8434                // When we actually went to determine the final targer user ID, this ended
8435                // up different than our initial check for the authority.  This is because
8436                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8437                // SELF.  So we need to re-check the grants again.
8438                checkedGrants = false;
8439            }
8440        }
8441        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8442                cpi.applicationInfo.uid, cpi.exported)
8443                == PackageManager.PERMISSION_GRANTED) {
8444            return null;
8445        }
8446        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8447                cpi.applicationInfo.uid, cpi.exported)
8448                == PackageManager.PERMISSION_GRANTED) {
8449            return null;
8450        }
8451
8452        PathPermission[] pps = cpi.pathPermissions;
8453        if (pps != null) {
8454            int i = pps.length;
8455            while (i > 0) {
8456                i--;
8457                PathPermission pp = pps[i];
8458                String pprperm = pp.getReadPermission();
8459                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8460                        cpi.applicationInfo.uid, cpi.exported)
8461                        == PackageManager.PERMISSION_GRANTED) {
8462                    return null;
8463                }
8464                String ppwperm = pp.getWritePermission();
8465                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8466                        cpi.applicationInfo.uid, cpi.exported)
8467                        == PackageManager.PERMISSION_GRANTED) {
8468                    return null;
8469                }
8470            }
8471        }
8472        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8473            return null;
8474        }
8475
8476        String msg;
8477        if (!cpi.exported) {
8478            msg = "Permission Denial: opening provider " + cpi.name
8479                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8480                    + ", uid=" + callingUid + ") that is not exported from uid "
8481                    + cpi.applicationInfo.uid;
8482        } else {
8483            msg = "Permission Denial: opening provider " + cpi.name
8484                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8485                    + ", uid=" + callingUid + ") requires "
8486                    + cpi.readPermission + " or " + cpi.writePermission;
8487        }
8488        Slog.w(TAG, msg);
8489        return msg;
8490    }
8491
8492    /**
8493     * Returns if the ContentProvider has granted a uri to callingUid
8494     */
8495    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8496        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8497        if (perms != null) {
8498            for (int i=perms.size()-1; i>=0; i--) {
8499                GrantUri grantUri = perms.keyAt(i);
8500                if (grantUri.sourceUserId == userId || !checkUser) {
8501                    if (matchesProvider(grantUri.uri, cpi)) {
8502                        return true;
8503                    }
8504                }
8505            }
8506        }
8507        return false;
8508    }
8509
8510    /**
8511     * Returns true if the uri authority is one of the authorities specified in the provider.
8512     */
8513    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8514        String uriAuth = uri.getAuthority();
8515        String cpiAuth = cpi.authority;
8516        if (cpiAuth.indexOf(';') == -1) {
8517            return cpiAuth.equals(uriAuth);
8518        }
8519        String[] cpiAuths = cpiAuth.split(";");
8520        int length = cpiAuths.length;
8521        for (int i = 0; i < length; i++) {
8522            if (cpiAuths[i].equals(uriAuth)) return true;
8523        }
8524        return false;
8525    }
8526
8527    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8528            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8529        if (r != null) {
8530            for (int i=0; i<r.conProviders.size(); i++) {
8531                ContentProviderConnection conn = r.conProviders.get(i);
8532                if (conn.provider == cpr) {
8533                    if (DEBUG_PROVIDER) Slog.v(TAG,
8534                            "Adding provider requested by "
8535                            + r.processName + " from process "
8536                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8537                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8538                    if (stable) {
8539                        conn.stableCount++;
8540                        conn.numStableIncs++;
8541                    } else {
8542                        conn.unstableCount++;
8543                        conn.numUnstableIncs++;
8544                    }
8545                    return conn;
8546                }
8547            }
8548            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8549            if (stable) {
8550                conn.stableCount = 1;
8551                conn.numStableIncs = 1;
8552            } else {
8553                conn.unstableCount = 1;
8554                conn.numUnstableIncs = 1;
8555            }
8556            cpr.connections.add(conn);
8557            r.conProviders.add(conn);
8558            return conn;
8559        }
8560        cpr.addExternalProcessHandleLocked(externalProcessToken);
8561        return null;
8562    }
8563
8564    boolean decProviderCountLocked(ContentProviderConnection conn,
8565            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8566        if (conn != null) {
8567            cpr = conn.provider;
8568            if (DEBUG_PROVIDER) Slog.v(TAG,
8569                    "Removing provider requested by "
8570                    + conn.client.processName + " from process "
8571                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8572                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8573            if (stable) {
8574                conn.stableCount--;
8575            } else {
8576                conn.unstableCount--;
8577            }
8578            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8579                cpr.connections.remove(conn);
8580                conn.client.conProviders.remove(conn);
8581                return true;
8582            }
8583            return false;
8584        }
8585        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8586        return false;
8587    }
8588
8589    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8590            String name, IBinder token, boolean stable, int userId) {
8591        ContentProviderRecord cpr;
8592        ContentProviderConnection conn = null;
8593        ProviderInfo cpi = null;
8594
8595        synchronized(this) {
8596            ProcessRecord r = null;
8597            if (caller != null) {
8598                r = getRecordForAppLocked(caller);
8599                if (r == null) {
8600                    throw new SecurityException(
8601                            "Unable to find app for caller " + caller
8602                          + " (pid=" + Binder.getCallingPid()
8603                          + ") when getting content provider " + name);
8604                }
8605            }
8606
8607            boolean checkCrossUser = true;
8608
8609            // First check if this content provider has been published...
8610            cpr = mProviderMap.getProviderByName(name, userId);
8611            // If that didn't work, check if it exists for user 0 and then
8612            // verify that it's a singleton provider before using it.
8613            if (cpr == null && userId != UserHandle.USER_OWNER) {
8614                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8615                if (cpr != null) {
8616                    cpi = cpr.info;
8617                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8618                            cpi.name, cpi.flags)
8619                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8620                        userId = UserHandle.USER_OWNER;
8621                        checkCrossUser = false;
8622                    } else {
8623                        cpr = null;
8624                        cpi = null;
8625                    }
8626                }
8627            }
8628
8629            boolean providerRunning = cpr != null;
8630            if (providerRunning) {
8631                cpi = cpr.info;
8632                String msg;
8633                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8634                        != null) {
8635                    throw new SecurityException(msg);
8636                }
8637
8638                if (r != null && cpr.canRunHere(r)) {
8639                    // This provider has been published or is in the process
8640                    // of being published...  but it is also allowed to run
8641                    // in the caller's process, so don't make a connection
8642                    // and just let the caller instantiate its own instance.
8643                    ContentProviderHolder holder = cpr.newHolder(null);
8644                    // don't give caller the provider object, it needs
8645                    // to make its own.
8646                    holder.provider = null;
8647                    return holder;
8648                }
8649
8650                final long origId = Binder.clearCallingIdentity();
8651
8652                // In this case the provider instance already exists, so we can
8653                // return it right away.
8654                conn = incProviderCountLocked(r, cpr, token, stable);
8655                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8656                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8657                        // If this is a perceptible app accessing the provider,
8658                        // make sure to count it as being accessed and thus
8659                        // back up on the LRU list.  This is good because
8660                        // content providers are often expensive to start.
8661                        updateLruProcessLocked(cpr.proc, false, null);
8662                    }
8663                }
8664
8665                if (cpr.proc != null) {
8666                    if (false) {
8667                        if (cpr.name.flattenToShortString().equals(
8668                                "com.android.providers.calendar/.CalendarProvider2")) {
8669                            Slog.v(TAG, "****************** KILLING "
8670                                + cpr.name.flattenToShortString());
8671                            Process.killProcess(cpr.proc.pid);
8672                        }
8673                    }
8674                    boolean success = updateOomAdjLocked(cpr.proc);
8675                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8676                    // NOTE: there is still a race here where a signal could be
8677                    // pending on the process even though we managed to update its
8678                    // adj level.  Not sure what to do about this, but at least
8679                    // the race is now smaller.
8680                    if (!success) {
8681                        // Uh oh...  it looks like the provider's process
8682                        // has been killed on us.  We need to wait for a new
8683                        // process to be started, and make sure its death
8684                        // doesn't kill our process.
8685                        Slog.i(TAG,
8686                                "Existing provider " + cpr.name.flattenToShortString()
8687                                + " is crashing; detaching " + r);
8688                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8689                        appDiedLocked(cpr.proc);
8690                        if (!lastRef) {
8691                            // This wasn't the last ref our process had on
8692                            // the provider...  we have now been killed, bail.
8693                            return null;
8694                        }
8695                        providerRunning = false;
8696                        conn = null;
8697                    }
8698                }
8699
8700                Binder.restoreCallingIdentity(origId);
8701            }
8702
8703            boolean singleton;
8704            if (!providerRunning) {
8705                try {
8706                    cpi = AppGlobals.getPackageManager().
8707                        resolveContentProvider(name,
8708                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8709                } catch (RemoteException ex) {
8710                }
8711                if (cpi == null) {
8712                    return null;
8713                }
8714                // If the provider is a singleton AND
8715                // (it's a call within the same user || the provider is a
8716                // privileged app)
8717                // Then allow connecting to the singleton provider
8718                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8719                        cpi.name, cpi.flags)
8720                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8721                if (singleton) {
8722                    userId = UserHandle.USER_OWNER;
8723                }
8724                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8725
8726                String msg;
8727                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8728                        != null) {
8729                    throw new SecurityException(msg);
8730                }
8731
8732                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8733                        && !cpi.processName.equals("system")) {
8734                    // If this content provider does not run in the system
8735                    // process, and the system is not yet ready to run other
8736                    // processes, then fail fast instead of hanging.
8737                    throw new IllegalArgumentException(
8738                            "Attempt to launch content provider before system ready");
8739                }
8740
8741                // Make sure that the user who owns this provider is started.  If not,
8742                // we don't want to allow it to run.
8743                if (mStartedUsers.get(userId) == null) {
8744                    Slog.w(TAG, "Unable to launch app "
8745                            + cpi.applicationInfo.packageName + "/"
8746                            + cpi.applicationInfo.uid + " for provider "
8747                            + name + ": user " + userId + " is stopped");
8748                    return null;
8749                }
8750
8751                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8752                cpr = mProviderMap.getProviderByClass(comp, userId);
8753                final boolean firstClass = cpr == null;
8754                if (firstClass) {
8755                    try {
8756                        ApplicationInfo ai =
8757                            AppGlobals.getPackageManager().
8758                                getApplicationInfo(
8759                                        cpi.applicationInfo.packageName,
8760                                        STOCK_PM_FLAGS, userId);
8761                        if (ai == null) {
8762                            Slog.w(TAG, "No package info for content provider "
8763                                    + cpi.name);
8764                            return null;
8765                        }
8766                        ai = getAppInfoForUser(ai, userId);
8767                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8768                    } catch (RemoteException ex) {
8769                        // pm is in same process, this will never happen.
8770                    }
8771                }
8772
8773                if (r != null && cpr.canRunHere(r)) {
8774                    // If this is a multiprocess provider, then just return its
8775                    // info and allow the caller to instantiate it.  Only do
8776                    // this if the provider is the same user as the caller's
8777                    // process, or can run as root (so can be in any process).
8778                    return cpr.newHolder(null);
8779                }
8780
8781                if (DEBUG_PROVIDER) {
8782                    RuntimeException e = new RuntimeException("here");
8783                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8784                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8785                }
8786
8787                // This is single process, and our app is now connecting to it.
8788                // See if we are already in the process of launching this
8789                // provider.
8790                final int N = mLaunchingProviders.size();
8791                int i;
8792                for (i=0; i<N; i++) {
8793                    if (mLaunchingProviders.get(i) == cpr) {
8794                        break;
8795                    }
8796                }
8797
8798                // If the provider is not already being launched, then get it
8799                // started.
8800                if (i >= N) {
8801                    final long origId = Binder.clearCallingIdentity();
8802
8803                    try {
8804                        // Content provider is now in use, its package can't be stopped.
8805                        try {
8806                            AppGlobals.getPackageManager().setPackageStoppedState(
8807                                    cpr.appInfo.packageName, false, userId);
8808                        } catch (RemoteException e) {
8809                        } catch (IllegalArgumentException e) {
8810                            Slog.w(TAG, "Failed trying to unstop package "
8811                                    + cpr.appInfo.packageName + ": " + e);
8812                        }
8813
8814                        // Use existing process if already started
8815                        ProcessRecord proc = getProcessRecordLocked(
8816                                cpi.processName, cpr.appInfo.uid, false);
8817                        if (proc != null && proc.thread != null) {
8818                            if (DEBUG_PROVIDER) {
8819                                Slog.d(TAG, "Installing in existing process " + proc);
8820                            }
8821                            proc.pubProviders.put(cpi.name, cpr);
8822                            try {
8823                                proc.thread.scheduleInstallProvider(cpi);
8824                            } catch (RemoteException e) {
8825                            }
8826                        } else {
8827                            proc = startProcessLocked(cpi.processName,
8828                                    cpr.appInfo, false, 0, "content provider",
8829                                    new ComponentName(cpi.applicationInfo.packageName,
8830                                            cpi.name), false, false, false);
8831                            if (proc == null) {
8832                                Slog.w(TAG, "Unable to launch app "
8833                                        + cpi.applicationInfo.packageName + "/"
8834                                        + cpi.applicationInfo.uid + " for provider "
8835                                        + name + ": process is bad");
8836                                return null;
8837                            }
8838                        }
8839                        cpr.launchingApp = proc;
8840                        mLaunchingProviders.add(cpr);
8841                    } finally {
8842                        Binder.restoreCallingIdentity(origId);
8843                    }
8844                }
8845
8846                // Make sure the provider is published (the same provider class
8847                // may be published under multiple names).
8848                if (firstClass) {
8849                    mProviderMap.putProviderByClass(comp, cpr);
8850                }
8851
8852                mProviderMap.putProviderByName(name, cpr);
8853                conn = incProviderCountLocked(r, cpr, token, stable);
8854                if (conn != null) {
8855                    conn.waiting = true;
8856                }
8857            }
8858        }
8859
8860        // Wait for the provider to be published...
8861        synchronized (cpr) {
8862            while (cpr.provider == null) {
8863                if (cpr.launchingApp == null) {
8864                    Slog.w(TAG, "Unable to launch app "
8865                            + cpi.applicationInfo.packageName + "/"
8866                            + cpi.applicationInfo.uid + " for provider "
8867                            + name + ": launching app became null");
8868                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8869                            UserHandle.getUserId(cpi.applicationInfo.uid),
8870                            cpi.applicationInfo.packageName,
8871                            cpi.applicationInfo.uid, name);
8872                    return null;
8873                }
8874                try {
8875                    if (DEBUG_MU) {
8876                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8877                                + cpr.launchingApp);
8878                    }
8879                    if (conn != null) {
8880                        conn.waiting = true;
8881                    }
8882                    cpr.wait();
8883                } catch (InterruptedException ex) {
8884                } finally {
8885                    if (conn != null) {
8886                        conn.waiting = false;
8887                    }
8888                }
8889            }
8890        }
8891        return cpr != null ? cpr.newHolder(conn) : null;
8892    }
8893
8894    @Override
8895    public final ContentProviderHolder getContentProvider(
8896            IApplicationThread caller, String name, int userId, boolean stable) {
8897        enforceNotIsolatedCaller("getContentProvider");
8898        if (caller == null) {
8899            String msg = "null IApplicationThread when getting content provider "
8900                    + name;
8901            Slog.w(TAG, msg);
8902            throw new SecurityException(msg);
8903        }
8904        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8905        // with cross-user grant.
8906        return getContentProviderImpl(caller, name, null, stable, userId);
8907    }
8908
8909    public ContentProviderHolder getContentProviderExternal(
8910            String name, int userId, IBinder token) {
8911        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8912            "Do not have permission in call getContentProviderExternal()");
8913        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8914                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8915        return getContentProviderExternalUnchecked(name, token, userId);
8916    }
8917
8918    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8919            IBinder token, int userId) {
8920        return getContentProviderImpl(null, name, token, true, userId);
8921    }
8922
8923    /**
8924     * Drop a content provider from a ProcessRecord's bookkeeping
8925     */
8926    public void removeContentProvider(IBinder connection, boolean stable) {
8927        enforceNotIsolatedCaller("removeContentProvider");
8928        long ident = Binder.clearCallingIdentity();
8929        try {
8930            synchronized (this) {
8931                ContentProviderConnection conn;
8932                try {
8933                    conn = (ContentProviderConnection)connection;
8934                } catch (ClassCastException e) {
8935                    String msg ="removeContentProvider: " + connection
8936                            + " not a ContentProviderConnection";
8937                    Slog.w(TAG, msg);
8938                    throw new IllegalArgumentException(msg);
8939                }
8940                if (conn == null) {
8941                    throw new NullPointerException("connection is null");
8942                }
8943                if (decProviderCountLocked(conn, null, null, stable)) {
8944                    updateOomAdjLocked();
8945                }
8946            }
8947        } finally {
8948            Binder.restoreCallingIdentity(ident);
8949        }
8950    }
8951
8952    public void removeContentProviderExternal(String name, IBinder token) {
8953        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8954            "Do not have permission in call removeContentProviderExternal()");
8955        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8956    }
8957
8958    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8959        synchronized (this) {
8960            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8961            if(cpr == null) {
8962                //remove from mProvidersByClass
8963                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8964                return;
8965            }
8966
8967            //update content provider record entry info
8968            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8969            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8970            if (localCpr.hasExternalProcessHandles()) {
8971                if (localCpr.removeExternalProcessHandleLocked(token)) {
8972                    updateOomAdjLocked();
8973                } else {
8974                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8975                            + " with no external reference for token: "
8976                            + token + ".");
8977                }
8978            } else {
8979                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8980                        + " with no external references.");
8981            }
8982        }
8983    }
8984
8985    public final void publishContentProviders(IApplicationThread caller,
8986            List<ContentProviderHolder> providers) {
8987        if (providers == null) {
8988            return;
8989        }
8990
8991        enforceNotIsolatedCaller("publishContentProviders");
8992        synchronized (this) {
8993            final ProcessRecord r = getRecordForAppLocked(caller);
8994            if (DEBUG_MU)
8995                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8996            if (r == null) {
8997                throw new SecurityException(
8998                        "Unable to find app for caller " + caller
8999                      + " (pid=" + Binder.getCallingPid()
9000                      + ") when publishing content providers");
9001            }
9002
9003            final long origId = Binder.clearCallingIdentity();
9004
9005            final int N = providers.size();
9006            for (int i=0; i<N; i++) {
9007                ContentProviderHolder src = providers.get(i);
9008                if (src == null || src.info == null || src.provider == null) {
9009                    continue;
9010                }
9011                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9012                if (DEBUG_MU)
9013                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9014                if (dst != null) {
9015                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9016                    mProviderMap.putProviderByClass(comp, dst);
9017                    String names[] = dst.info.authority.split(";");
9018                    for (int j = 0; j < names.length; j++) {
9019                        mProviderMap.putProviderByName(names[j], dst);
9020                    }
9021
9022                    int NL = mLaunchingProviders.size();
9023                    int j;
9024                    for (j=0; j<NL; j++) {
9025                        if (mLaunchingProviders.get(j) == dst) {
9026                            mLaunchingProviders.remove(j);
9027                            j--;
9028                            NL--;
9029                        }
9030                    }
9031                    synchronized (dst) {
9032                        dst.provider = src.provider;
9033                        dst.proc = r;
9034                        dst.notifyAll();
9035                    }
9036                    updateOomAdjLocked(r);
9037                }
9038            }
9039
9040            Binder.restoreCallingIdentity(origId);
9041        }
9042    }
9043
9044    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9045        ContentProviderConnection conn;
9046        try {
9047            conn = (ContentProviderConnection)connection;
9048        } catch (ClassCastException e) {
9049            String msg ="refContentProvider: " + connection
9050                    + " not a ContentProviderConnection";
9051            Slog.w(TAG, msg);
9052            throw new IllegalArgumentException(msg);
9053        }
9054        if (conn == null) {
9055            throw new NullPointerException("connection is null");
9056        }
9057
9058        synchronized (this) {
9059            if (stable > 0) {
9060                conn.numStableIncs += stable;
9061            }
9062            stable = conn.stableCount + stable;
9063            if (stable < 0) {
9064                throw new IllegalStateException("stableCount < 0: " + stable);
9065            }
9066
9067            if (unstable > 0) {
9068                conn.numUnstableIncs += unstable;
9069            }
9070            unstable = conn.unstableCount + unstable;
9071            if (unstable < 0) {
9072                throw new IllegalStateException("unstableCount < 0: " + unstable);
9073            }
9074
9075            if ((stable+unstable) <= 0) {
9076                throw new IllegalStateException("ref counts can't go to zero here: stable="
9077                        + stable + " unstable=" + unstable);
9078            }
9079            conn.stableCount = stable;
9080            conn.unstableCount = unstable;
9081            return !conn.dead;
9082        }
9083    }
9084
9085    public void unstableProviderDied(IBinder connection) {
9086        ContentProviderConnection conn;
9087        try {
9088            conn = (ContentProviderConnection)connection;
9089        } catch (ClassCastException e) {
9090            String msg ="refContentProvider: " + connection
9091                    + " not a ContentProviderConnection";
9092            Slog.w(TAG, msg);
9093            throw new IllegalArgumentException(msg);
9094        }
9095        if (conn == null) {
9096            throw new NullPointerException("connection is null");
9097        }
9098
9099        // Safely retrieve the content provider associated with the connection.
9100        IContentProvider provider;
9101        synchronized (this) {
9102            provider = conn.provider.provider;
9103        }
9104
9105        if (provider == null) {
9106            // Um, yeah, we're way ahead of you.
9107            return;
9108        }
9109
9110        // Make sure the caller is being honest with us.
9111        if (provider.asBinder().pingBinder()) {
9112            // Er, no, still looks good to us.
9113            synchronized (this) {
9114                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9115                        + " says " + conn + " died, but we don't agree");
9116                return;
9117            }
9118        }
9119
9120        // Well look at that!  It's dead!
9121        synchronized (this) {
9122            if (conn.provider.provider != provider) {
9123                // But something changed...  good enough.
9124                return;
9125            }
9126
9127            ProcessRecord proc = conn.provider.proc;
9128            if (proc == null || proc.thread == null) {
9129                // Seems like the process is already cleaned up.
9130                return;
9131            }
9132
9133            // As far as we're concerned, this is just like receiving a
9134            // death notification...  just a bit prematurely.
9135            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9136                    + ") early provider death");
9137            final long ident = Binder.clearCallingIdentity();
9138            try {
9139                appDiedLocked(proc);
9140            } finally {
9141                Binder.restoreCallingIdentity(ident);
9142            }
9143        }
9144    }
9145
9146    @Override
9147    public void appNotRespondingViaProvider(IBinder connection) {
9148        enforceCallingPermission(
9149                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9150
9151        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9152        if (conn == null) {
9153            Slog.w(TAG, "ContentProviderConnection is null");
9154            return;
9155        }
9156
9157        final ProcessRecord host = conn.provider.proc;
9158        if (host == null) {
9159            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9160            return;
9161        }
9162
9163        final long token = Binder.clearCallingIdentity();
9164        try {
9165            appNotResponding(host, null, null, false, "ContentProvider not responding");
9166        } finally {
9167            Binder.restoreCallingIdentity(token);
9168        }
9169    }
9170
9171    public final void installSystemProviders() {
9172        List<ProviderInfo> providers;
9173        synchronized (this) {
9174            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9175            providers = generateApplicationProvidersLocked(app);
9176            if (providers != null) {
9177                for (int i=providers.size()-1; i>=0; i--) {
9178                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9179                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9180                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9181                                + ": not system .apk");
9182                        providers.remove(i);
9183                    }
9184                }
9185            }
9186        }
9187        if (providers != null) {
9188            mSystemThread.installSystemProviders(providers);
9189        }
9190
9191        mCoreSettingsObserver = new CoreSettingsObserver(this);
9192
9193        //mUsageStatsService.monitorPackages();
9194    }
9195
9196    /**
9197     * Allows apps to retrieve the MIME type of a URI.
9198     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9199     * users, then it does not need permission to access the ContentProvider.
9200     * Either, it needs cross-user uri grants.
9201     *
9202     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9203     *
9204     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9205     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9206     */
9207    public String getProviderMimeType(Uri uri, int userId) {
9208        enforceNotIsolatedCaller("getProviderMimeType");
9209        final String name = uri.getAuthority();
9210        int callingUid = Binder.getCallingUid();
9211        int callingPid = Binder.getCallingPid();
9212        long ident = 0;
9213        boolean clearedIdentity = false;
9214        userId = unsafeConvertIncomingUser(userId);
9215        if (UserHandle.getUserId(callingUid) != userId) {
9216            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9217                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9218                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9219                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9220                clearedIdentity = true;
9221                ident = Binder.clearCallingIdentity();
9222            }
9223        }
9224        ContentProviderHolder holder = null;
9225        try {
9226            holder = getContentProviderExternalUnchecked(name, null, userId);
9227            if (holder != null) {
9228                return holder.provider.getType(uri);
9229            }
9230        } catch (RemoteException e) {
9231            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9232            return null;
9233        } finally {
9234            // We need to clear the identity to call removeContentProviderExternalUnchecked
9235            if (!clearedIdentity) {
9236                ident = Binder.clearCallingIdentity();
9237            }
9238            try {
9239                if (holder != null) {
9240                    removeContentProviderExternalUnchecked(name, null, userId);
9241                }
9242            } finally {
9243                Binder.restoreCallingIdentity(ident);
9244            }
9245        }
9246
9247        return null;
9248    }
9249
9250    // =========================================================
9251    // GLOBAL MANAGEMENT
9252    // =========================================================
9253
9254    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9255            boolean isolated, int isolatedUid) {
9256        String proc = customProcess != null ? customProcess : info.processName;
9257        BatteryStatsImpl.Uid.Proc ps = null;
9258        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9259        int uid = info.uid;
9260        if (isolated) {
9261            if (isolatedUid == 0) {
9262                int userId = UserHandle.getUserId(uid);
9263                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9264                while (true) {
9265                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9266                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9267                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9268                    }
9269                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9270                    mNextIsolatedProcessUid++;
9271                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9272                        // No process for this uid, use it.
9273                        break;
9274                    }
9275                    stepsLeft--;
9276                    if (stepsLeft <= 0) {
9277                        return null;
9278                    }
9279                }
9280            } else {
9281                // Special case for startIsolatedProcess (internal only), where
9282                // the uid of the isolated process is specified by the caller.
9283                uid = isolatedUid;
9284            }
9285        }
9286        return new ProcessRecord(stats, info, proc, uid);
9287    }
9288
9289    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9290            String abiOverride) {
9291        ProcessRecord app;
9292        if (!isolated) {
9293            app = getProcessRecordLocked(info.processName, info.uid, true);
9294        } else {
9295            app = null;
9296        }
9297
9298        if (app == null) {
9299            app = newProcessRecordLocked(info, null, isolated, 0);
9300            mProcessNames.put(info.processName, app.uid, app);
9301            if (isolated) {
9302                mIsolatedProcesses.put(app.uid, app);
9303            }
9304            updateLruProcessLocked(app, false, null);
9305            updateOomAdjLocked();
9306        }
9307
9308        // This package really, really can not be stopped.
9309        try {
9310            AppGlobals.getPackageManager().setPackageStoppedState(
9311                    info.packageName, false, UserHandle.getUserId(app.uid));
9312        } catch (RemoteException e) {
9313        } catch (IllegalArgumentException e) {
9314            Slog.w(TAG, "Failed trying to unstop package "
9315                    + info.packageName + ": " + e);
9316        }
9317
9318        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9319                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9320            app.persistent = true;
9321            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9322        }
9323        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9324            mPersistentStartingProcesses.add(app);
9325            startProcessLocked(app, "added application", app.processName, abiOverride,
9326                    null /* entryPoint */, null /* entryPointArgs */);
9327        }
9328
9329        return app;
9330    }
9331
9332    public void unhandledBack() {
9333        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9334                "unhandledBack()");
9335
9336        synchronized(this) {
9337            final long origId = Binder.clearCallingIdentity();
9338            try {
9339                getFocusedStack().unhandledBackLocked();
9340            } finally {
9341                Binder.restoreCallingIdentity(origId);
9342            }
9343        }
9344    }
9345
9346    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9347        enforceNotIsolatedCaller("openContentUri");
9348        final int userId = UserHandle.getCallingUserId();
9349        String name = uri.getAuthority();
9350        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9351        ParcelFileDescriptor pfd = null;
9352        if (cph != null) {
9353            // We record the binder invoker's uid in thread-local storage before
9354            // going to the content provider to open the file.  Later, in the code
9355            // that handles all permissions checks, we look for this uid and use
9356            // that rather than the Activity Manager's own uid.  The effect is that
9357            // we do the check against the caller's permissions even though it looks
9358            // to the content provider like the Activity Manager itself is making
9359            // the request.
9360            sCallerIdentity.set(new Identity(
9361                    Binder.getCallingPid(), Binder.getCallingUid()));
9362            try {
9363                pfd = cph.provider.openFile(null, uri, "r", null);
9364            } catch (FileNotFoundException e) {
9365                // do nothing; pfd will be returned null
9366            } finally {
9367                // Ensure that whatever happens, we clean up the identity state
9368                sCallerIdentity.remove();
9369            }
9370
9371            // We've got the fd now, so we're done with the provider.
9372            removeContentProviderExternalUnchecked(name, null, userId);
9373        } else {
9374            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9375        }
9376        return pfd;
9377    }
9378
9379    // Actually is sleeping or shutting down or whatever else in the future
9380    // is an inactive state.
9381    public boolean isSleepingOrShuttingDown() {
9382        return mSleeping || mShuttingDown;
9383    }
9384
9385    public boolean isSleeping() {
9386        return mSleeping;
9387    }
9388
9389    void goingToSleep() {
9390        synchronized(this) {
9391            mWentToSleep = true;
9392            updateEventDispatchingLocked();
9393            goToSleepIfNeededLocked();
9394        }
9395    }
9396
9397    void finishRunningVoiceLocked() {
9398        if (mRunningVoice) {
9399            mRunningVoice = false;
9400            goToSleepIfNeededLocked();
9401        }
9402    }
9403
9404    void goToSleepIfNeededLocked() {
9405        if (mWentToSleep && !mRunningVoice) {
9406            if (!mSleeping) {
9407                mSleeping = true;
9408                mStackSupervisor.goingToSleepLocked();
9409
9410                // Initialize the wake times of all processes.
9411                checkExcessivePowerUsageLocked(false);
9412                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9413                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9414                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9415            }
9416        }
9417    }
9418
9419    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9420        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9421            // Never persist the home stack.
9422            return;
9423        }
9424        mTaskPersister.wakeup(task, flush);
9425    }
9426
9427    @Override
9428    public boolean shutdown(int timeout) {
9429        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9430                != PackageManager.PERMISSION_GRANTED) {
9431            throw new SecurityException("Requires permission "
9432                    + android.Manifest.permission.SHUTDOWN);
9433        }
9434
9435        boolean timedout = false;
9436
9437        synchronized(this) {
9438            mShuttingDown = true;
9439            updateEventDispatchingLocked();
9440            timedout = mStackSupervisor.shutdownLocked(timeout);
9441        }
9442
9443        mAppOpsService.shutdown();
9444        if (mUsageStatsService != null) {
9445            mUsageStatsService.prepareShutdown();
9446        }
9447        mBatteryStatsService.shutdown();
9448        synchronized (this) {
9449            mProcessStats.shutdownLocked();
9450        }
9451        notifyTaskPersisterLocked(null, true);
9452
9453        return timedout;
9454    }
9455
9456    public final void activitySlept(IBinder token) {
9457        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9458
9459        final long origId = Binder.clearCallingIdentity();
9460
9461        synchronized (this) {
9462            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9463            if (r != null) {
9464                mStackSupervisor.activitySleptLocked(r);
9465            }
9466        }
9467
9468        Binder.restoreCallingIdentity(origId);
9469    }
9470
9471    void logLockScreen(String msg) {
9472        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9473                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9474                mWentToSleep + " mSleeping=" + mSleeping);
9475    }
9476
9477    private void comeOutOfSleepIfNeededLocked() {
9478        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9479            if (mSleeping) {
9480                mSleeping = false;
9481                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9482            }
9483        }
9484    }
9485
9486    void wakingUp() {
9487        synchronized(this) {
9488            mWentToSleep = false;
9489            updateEventDispatchingLocked();
9490            comeOutOfSleepIfNeededLocked();
9491        }
9492    }
9493
9494    void startRunningVoiceLocked() {
9495        if (!mRunningVoice) {
9496            mRunningVoice = true;
9497            comeOutOfSleepIfNeededLocked();
9498        }
9499    }
9500
9501    private void updateEventDispatchingLocked() {
9502        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9503    }
9504
9505    public void setLockScreenShown(boolean shown) {
9506        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9507                != PackageManager.PERMISSION_GRANTED) {
9508            throw new SecurityException("Requires permission "
9509                    + android.Manifest.permission.DEVICE_POWER);
9510        }
9511
9512        synchronized(this) {
9513            long ident = Binder.clearCallingIdentity();
9514            try {
9515                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9516                mLockScreenShown = shown;
9517                comeOutOfSleepIfNeededLocked();
9518            } finally {
9519                Binder.restoreCallingIdentity(ident);
9520            }
9521        }
9522    }
9523
9524    @Override
9525    public void stopAppSwitches() {
9526        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9527                != PackageManager.PERMISSION_GRANTED) {
9528            throw new SecurityException("Requires permission "
9529                    + android.Manifest.permission.STOP_APP_SWITCHES);
9530        }
9531
9532        synchronized(this) {
9533            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9534                    + APP_SWITCH_DELAY_TIME;
9535            mDidAppSwitch = false;
9536            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9537            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9538            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9539        }
9540    }
9541
9542    public void resumeAppSwitches() {
9543        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9544                != PackageManager.PERMISSION_GRANTED) {
9545            throw new SecurityException("Requires permission "
9546                    + android.Manifest.permission.STOP_APP_SWITCHES);
9547        }
9548
9549        synchronized(this) {
9550            // Note that we don't execute any pending app switches... we will
9551            // let those wait until either the timeout, or the next start
9552            // activity request.
9553            mAppSwitchesAllowedTime = 0;
9554        }
9555    }
9556
9557    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9558            String name) {
9559        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9560            return true;
9561        }
9562
9563        final int perm = checkComponentPermission(
9564                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9565                callingUid, -1, true);
9566        if (perm == PackageManager.PERMISSION_GRANTED) {
9567            return true;
9568        }
9569
9570        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9571        return false;
9572    }
9573
9574    public void setDebugApp(String packageName, boolean waitForDebugger,
9575            boolean persistent) {
9576        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9577                "setDebugApp()");
9578
9579        long ident = Binder.clearCallingIdentity();
9580        try {
9581            // Note that this is not really thread safe if there are multiple
9582            // callers into it at the same time, but that's not a situation we
9583            // care about.
9584            if (persistent) {
9585                final ContentResolver resolver = mContext.getContentResolver();
9586                Settings.Global.putString(
9587                    resolver, Settings.Global.DEBUG_APP,
9588                    packageName);
9589                Settings.Global.putInt(
9590                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9591                    waitForDebugger ? 1 : 0);
9592            }
9593
9594            synchronized (this) {
9595                if (!persistent) {
9596                    mOrigDebugApp = mDebugApp;
9597                    mOrigWaitForDebugger = mWaitForDebugger;
9598                }
9599                mDebugApp = packageName;
9600                mWaitForDebugger = waitForDebugger;
9601                mDebugTransient = !persistent;
9602                if (packageName != null) {
9603                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9604                            false, UserHandle.USER_ALL, "set debug app");
9605                }
9606            }
9607        } finally {
9608            Binder.restoreCallingIdentity(ident);
9609        }
9610    }
9611
9612    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9613        synchronized (this) {
9614            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9615            if (!isDebuggable) {
9616                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9617                    throw new SecurityException("Process not debuggable: " + app.packageName);
9618                }
9619            }
9620
9621            mOpenGlTraceApp = processName;
9622        }
9623    }
9624
9625    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9626            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9627        synchronized (this) {
9628            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9629            if (!isDebuggable) {
9630                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9631                    throw new SecurityException("Process not debuggable: " + app.packageName);
9632                }
9633            }
9634            mProfileApp = processName;
9635            mProfileFile = profileFile;
9636            if (mProfileFd != null) {
9637                try {
9638                    mProfileFd.close();
9639                } catch (IOException e) {
9640                }
9641                mProfileFd = null;
9642            }
9643            mProfileFd = profileFd;
9644            mProfileType = 0;
9645            mAutoStopProfiler = autoStopProfiler;
9646        }
9647    }
9648
9649    @Override
9650    public void setAlwaysFinish(boolean enabled) {
9651        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9652                "setAlwaysFinish()");
9653
9654        Settings.Global.putInt(
9655                mContext.getContentResolver(),
9656                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9657
9658        synchronized (this) {
9659            mAlwaysFinishActivities = enabled;
9660        }
9661    }
9662
9663    @Override
9664    public void setActivityController(IActivityController controller) {
9665        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9666                "setActivityController()");
9667        synchronized (this) {
9668            mController = controller;
9669            Watchdog.getInstance().setActivityController(controller);
9670        }
9671    }
9672
9673    @Override
9674    public void setUserIsMonkey(boolean userIsMonkey) {
9675        synchronized (this) {
9676            synchronized (mPidsSelfLocked) {
9677                final int callingPid = Binder.getCallingPid();
9678                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9679                if (precessRecord == null) {
9680                    throw new SecurityException("Unknown process: " + callingPid);
9681                }
9682                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9683                    throw new SecurityException("Only an instrumentation process "
9684                            + "with a UiAutomation can call setUserIsMonkey");
9685                }
9686            }
9687            mUserIsMonkey = userIsMonkey;
9688        }
9689    }
9690
9691    @Override
9692    public boolean isUserAMonkey() {
9693        synchronized (this) {
9694            // If there is a controller also implies the user is a monkey.
9695            return (mUserIsMonkey || mController != null);
9696        }
9697    }
9698
9699    public void requestBugReport() {
9700        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9701        SystemProperties.set("ctl.start", "bugreport");
9702    }
9703
9704    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9705        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9706    }
9707
9708    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9709        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9710            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9711        }
9712        return KEY_DISPATCHING_TIMEOUT;
9713    }
9714
9715    @Override
9716    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9717        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9718                != PackageManager.PERMISSION_GRANTED) {
9719            throw new SecurityException("Requires permission "
9720                    + android.Manifest.permission.FILTER_EVENTS);
9721        }
9722        ProcessRecord proc;
9723        long timeout;
9724        synchronized (this) {
9725            synchronized (mPidsSelfLocked) {
9726                proc = mPidsSelfLocked.get(pid);
9727            }
9728            timeout = getInputDispatchingTimeoutLocked(proc);
9729        }
9730
9731        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9732            return -1;
9733        }
9734
9735        return timeout;
9736    }
9737
9738    /**
9739     * Handle input dispatching timeouts.
9740     * Returns whether input dispatching should be aborted or not.
9741     */
9742    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9743            final ActivityRecord activity, final ActivityRecord parent,
9744            final boolean aboveSystem, String reason) {
9745        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9746                != PackageManager.PERMISSION_GRANTED) {
9747            throw new SecurityException("Requires permission "
9748                    + android.Manifest.permission.FILTER_EVENTS);
9749        }
9750
9751        final String annotation;
9752        if (reason == null) {
9753            annotation = "Input dispatching timed out";
9754        } else {
9755            annotation = "Input dispatching timed out (" + reason + ")";
9756        }
9757
9758        if (proc != null) {
9759            synchronized (this) {
9760                if (proc.debugging) {
9761                    return false;
9762                }
9763
9764                if (mDidDexOpt) {
9765                    // Give more time since we were dexopting.
9766                    mDidDexOpt = false;
9767                    return false;
9768                }
9769
9770                if (proc.instrumentationClass != null) {
9771                    Bundle info = new Bundle();
9772                    info.putString("shortMsg", "keyDispatchingTimedOut");
9773                    info.putString("longMsg", annotation);
9774                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9775                    return true;
9776                }
9777            }
9778            mHandler.post(new Runnable() {
9779                @Override
9780                public void run() {
9781                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9782                }
9783            });
9784        }
9785
9786        return true;
9787    }
9788
9789    public Bundle getAssistContextExtras(int requestType) {
9790        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9791                "getAssistContextExtras()");
9792        PendingAssistExtras pae;
9793        Bundle extras = new Bundle();
9794        synchronized (this) {
9795            ActivityRecord activity = getFocusedStack().mResumedActivity;
9796            if (activity == null) {
9797                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9798                return null;
9799            }
9800            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9801            if (activity.app == null || activity.app.thread == null) {
9802                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9803                return extras;
9804            }
9805            if (activity.app.pid == Binder.getCallingPid()) {
9806                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9807                return extras;
9808            }
9809            pae = new PendingAssistExtras(activity);
9810            try {
9811                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9812                        requestType);
9813                mPendingAssistExtras.add(pae);
9814                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9815            } catch (RemoteException e) {
9816                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9817                return extras;
9818            }
9819        }
9820        synchronized (pae) {
9821            while (!pae.haveResult) {
9822                try {
9823                    pae.wait();
9824                } catch (InterruptedException e) {
9825                }
9826            }
9827            if (pae.result != null) {
9828                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9829            }
9830        }
9831        synchronized (this) {
9832            mPendingAssistExtras.remove(pae);
9833            mHandler.removeCallbacks(pae);
9834        }
9835        return extras;
9836    }
9837
9838    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9839        PendingAssistExtras pae = (PendingAssistExtras)token;
9840        synchronized (pae) {
9841            pae.result = extras;
9842            pae.haveResult = true;
9843            pae.notifyAll();
9844        }
9845    }
9846
9847    public void registerProcessObserver(IProcessObserver observer) {
9848        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9849                "registerProcessObserver()");
9850        synchronized (this) {
9851            mProcessObservers.register(observer);
9852        }
9853    }
9854
9855    @Override
9856    public void unregisterProcessObserver(IProcessObserver observer) {
9857        synchronized (this) {
9858            mProcessObservers.unregister(observer);
9859        }
9860    }
9861
9862    @Override
9863    public boolean convertFromTranslucent(IBinder token) {
9864        final long origId = Binder.clearCallingIdentity();
9865        try {
9866            synchronized (this) {
9867                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9868                if (r == null) {
9869                    return false;
9870                }
9871                if (r.changeWindowTranslucency(true)) {
9872                    mWindowManager.setAppFullscreen(token, true);
9873                    r.task.stack.releaseBackgroundResources();
9874                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9875                    return true;
9876                }
9877                return false;
9878            }
9879        } finally {
9880            Binder.restoreCallingIdentity(origId);
9881        }
9882    }
9883
9884    @Override
9885    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9886        final long origId = Binder.clearCallingIdentity();
9887        try {
9888            synchronized (this) {
9889                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9890                if (r == null) {
9891                    return false;
9892                }
9893                int index = r.task.mActivities.lastIndexOf(r);
9894                if (index > 0) {
9895                    ActivityRecord under = r.task.mActivities.get(index - 1);
9896                    under.returningOptions = options;
9897                }
9898                if (r.changeWindowTranslucency(false)) {
9899                    r.task.stack.convertToTranslucent(r);
9900                    mWindowManager.setAppFullscreen(token, false);
9901                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9902                    return true;
9903                } else {
9904                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9905                    return false;
9906                }
9907            }
9908        } finally {
9909            Binder.restoreCallingIdentity(origId);
9910        }
9911    }
9912
9913    @Override
9914    public boolean requestVisibleBehind(IBinder token, boolean visible) {
9915        final long origId = Binder.clearCallingIdentity();
9916        try {
9917            synchronized (this) {
9918                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9919                if (r != null) {
9920                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
9921                }
9922            }
9923            return false;
9924        } finally {
9925            Binder.restoreCallingIdentity(origId);
9926        }
9927    }
9928
9929    @Override
9930    public boolean isBackgroundVisibleBehind(IBinder token) {
9931        final long origId = Binder.clearCallingIdentity();
9932        try {
9933            synchronized (this) {
9934                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9935                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
9936                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
9937                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
9938                return visible;
9939            }
9940        } finally {
9941            Binder.restoreCallingIdentity(origId);
9942        }
9943    }
9944
9945    @Override
9946    public ActivityOptions getActivityOptions(IBinder token) {
9947        final long origId = Binder.clearCallingIdentity();
9948        try {
9949            synchronized (this) {
9950                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9951                if (r != null) {
9952                    final ActivityOptions activityOptions = r.pendingOptions;
9953                    r.pendingOptions = null;
9954                    return activityOptions;
9955                }
9956                return null;
9957            }
9958        } finally {
9959            Binder.restoreCallingIdentity(origId);
9960        }
9961    }
9962
9963    @Override
9964    public void setImmersive(IBinder token, boolean immersive) {
9965        synchronized(this) {
9966            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9967            if (r == null) {
9968                throw new IllegalArgumentException();
9969            }
9970            r.immersive = immersive;
9971
9972            // update associated state if we're frontmost
9973            if (r == mFocusedActivity) {
9974                if (DEBUG_IMMERSIVE) {
9975                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9976                }
9977                applyUpdateLockStateLocked(r);
9978            }
9979        }
9980    }
9981
9982    @Override
9983    public boolean isImmersive(IBinder token) {
9984        synchronized (this) {
9985            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9986            if (r == null) {
9987                throw new IllegalArgumentException();
9988            }
9989            return r.immersive;
9990        }
9991    }
9992
9993    public boolean isTopActivityImmersive() {
9994        enforceNotIsolatedCaller("startActivity");
9995        synchronized (this) {
9996            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9997            return (r != null) ? r.immersive : false;
9998        }
9999    }
10000
10001    @Override
10002    public boolean isTopOfTask(IBinder token) {
10003        synchronized (this) {
10004            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10005            if (r == null) {
10006                throw new IllegalArgumentException();
10007            }
10008            return r.task.getTopActivity() == r;
10009        }
10010    }
10011
10012    public final void enterSafeMode() {
10013        synchronized(this) {
10014            // It only makes sense to do this before the system is ready
10015            // and started launching other packages.
10016            if (!mSystemReady) {
10017                try {
10018                    AppGlobals.getPackageManager().enterSafeMode();
10019                } catch (RemoteException e) {
10020                }
10021            }
10022
10023            mSafeMode = true;
10024        }
10025    }
10026
10027    public final void showSafeModeOverlay() {
10028        View v = LayoutInflater.from(mContext).inflate(
10029                com.android.internal.R.layout.safe_mode, null);
10030        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10031        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10032        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10033        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10034        lp.gravity = Gravity.BOTTOM | Gravity.START;
10035        lp.format = v.getBackground().getOpacity();
10036        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10037                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10038        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10039        ((WindowManager)mContext.getSystemService(
10040                Context.WINDOW_SERVICE)).addView(v, lp);
10041    }
10042
10043    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10044        if (!(sender instanceof PendingIntentRecord)) {
10045            return;
10046        }
10047        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10048        synchronized (stats) {
10049            if (mBatteryStatsService.isOnBattery()) {
10050                mBatteryStatsService.enforceCallingPermission();
10051                PendingIntentRecord rec = (PendingIntentRecord)sender;
10052                int MY_UID = Binder.getCallingUid();
10053                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10054                BatteryStatsImpl.Uid.Pkg pkg =
10055                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10056                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10057                pkg.incWakeupsLocked();
10058            }
10059        }
10060    }
10061
10062    public boolean killPids(int[] pids, String pReason, boolean secure) {
10063        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10064            throw new SecurityException("killPids only available to the system");
10065        }
10066        String reason = (pReason == null) ? "Unknown" : pReason;
10067        // XXX Note: don't acquire main activity lock here, because the window
10068        // manager calls in with its locks held.
10069
10070        boolean killed = false;
10071        synchronized (mPidsSelfLocked) {
10072            int[] types = new int[pids.length];
10073            int worstType = 0;
10074            for (int i=0; i<pids.length; i++) {
10075                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10076                if (proc != null) {
10077                    int type = proc.setAdj;
10078                    types[i] = type;
10079                    if (type > worstType) {
10080                        worstType = type;
10081                    }
10082                }
10083            }
10084
10085            // If the worst oom_adj is somewhere in the cached proc LRU range,
10086            // then constrain it so we will kill all cached procs.
10087            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10088                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10089                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10090            }
10091
10092            // If this is not a secure call, don't let it kill processes that
10093            // are important.
10094            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10095                worstType = ProcessList.SERVICE_ADJ;
10096            }
10097
10098            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10099            for (int i=0; i<pids.length; i++) {
10100                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10101                if (proc == null) {
10102                    continue;
10103                }
10104                int adj = proc.setAdj;
10105                if (adj >= worstType && !proc.killedByAm) {
10106                    killUnneededProcessLocked(proc, reason);
10107                    killed = true;
10108                }
10109            }
10110        }
10111        return killed;
10112    }
10113
10114    @Override
10115    public void killUid(int uid, String reason) {
10116        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10117            throw new SecurityException("killUid only available to the system");
10118        }
10119        synchronized (this) {
10120            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10121                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10122                    reason != null ? reason : "kill uid");
10123        }
10124    }
10125
10126    @Override
10127    public boolean killProcessesBelowForeground(String reason) {
10128        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10129            throw new SecurityException("killProcessesBelowForeground() only available to system");
10130        }
10131
10132        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10133    }
10134
10135    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10136        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10137            throw new SecurityException("killProcessesBelowAdj() only available to system");
10138        }
10139
10140        boolean killed = false;
10141        synchronized (mPidsSelfLocked) {
10142            final int size = mPidsSelfLocked.size();
10143            for (int i = 0; i < size; i++) {
10144                final int pid = mPidsSelfLocked.keyAt(i);
10145                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10146                if (proc == null) continue;
10147
10148                final int adj = proc.setAdj;
10149                if (adj > belowAdj && !proc.killedByAm) {
10150                    killUnneededProcessLocked(proc, reason);
10151                    killed = true;
10152                }
10153            }
10154        }
10155        return killed;
10156    }
10157
10158    @Override
10159    public void hang(final IBinder who, boolean allowRestart) {
10160        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10161                != PackageManager.PERMISSION_GRANTED) {
10162            throw new SecurityException("Requires permission "
10163                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10164        }
10165
10166        final IBinder.DeathRecipient death = new DeathRecipient() {
10167            @Override
10168            public void binderDied() {
10169                synchronized (this) {
10170                    notifyAll();
10171                }
10172            }
10173        };
10174
10175        try {
10176            who.linkToDeath(death, 0);
10177        } catch (RemoteException e) {
10178            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10179            return;
10180        }
10181
10182        synchronized (this) {
10183            Watchdog.getInstance().setAllowRestart(allowRestart);
10184            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10185            synchronized (death) {
10186                while (who.isBinderAlive()) {
10187                    try {
10188                        death.wait();
10189                    } catch (InterruptedException e) {
10190                    }
10191                }
10192            }
10193            Watchdog.getInstance().setAllowRestart(true);
10194        }
10195    }
10196
10197    @Override
10198    public void restart() {
10199        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10200                != PackageManager.PERMISSION_GRANTED) {
10201            throw new SecurityException("Requires permission "
10202                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10203        }
10204
10205        Log.i(TAG, "Sending shutdown broadcast...");
10206
10207        BroadcastReceiver br = new BroadcastReceiver() {
10208            @Override public void onReceive(Context context, Intent intent) {
10209                // Now the broadcast is done, finish up the low-level shutdown.
10210                Log.i(TAG, "Shutting down activity manager...");
10211                shutdown(10000);
10212                Log.i(TAG, "Shutdown complete, restarting!");
10213                Process.killProcess(Process.myPid());
10214                System.exit(10);
10215            }
10216        };
10217
10218        // First send the high-level shut down broadcast.
10219        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10220        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10221        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10222        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10223        mContext.sendOrderedBroadcastAsUser(intent,
10224                UserHandle.ALL, null, br, mHandler, 0, null, null);
10225        */
10226        br.onReceive(mContext, intent);
10227    }
10228
10229    private long getLowRamTimeSinceIdle(long now) {
10230        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10231    }
10232
10233    @Override
10234    public void performIdleMaintenance() {
10235        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10236                != PackageManager.PERMISSION_GRANTED) {
10237            throw new SecurityException("Requires permission "
10238                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10239        }
10240
10241        synchronized (this) {
10242            final long now = SystemClock.uptimeMillis();
10243            final long timeSinceLastIdle = now - mLastIdleTime;
10244            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10245            mLastIdleTime = now;
10246            mLowRamTimeSinceLastIdle = 0;
10247            if (mLowRamStartTime != 0) {
10248                mLowRamStartTime = now;
10249            }
10250
10251            StringBuilder sb = new StringBuilder(128);
10252            sb.append("Idle maintenance over ");
10253            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10254            sb.append(" low RAM for ");
10255            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10256            Slog.i(TAG, sb.toString());
10257
10258            // If at least 1/3 of our time since the last idle period has been spent
10259            // with RAM low, then we want to kill processes.
10260            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10261
10262            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10263                ProcessRecord proc = mLruProcesses.get(i);
10264                if (proc.notCachedSinceIdle) {
10265                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10266                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10267                        if (doKilling && proc.initialIdlePss != 0
10268                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10269                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10270                                    + " from " + proc.initialIdlePss + ")");
10271                        }
10272                    }
10273                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10274                    proc.notCachedSinceIdle = true;
10275                    proc.initialIdlePss = 0;
10276                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10277                            isSleeping(), now);
10278                }
10279            }
10280
10281            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10282            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10283        }
10284    }
10285
10286    private void retrieveSettings() {
10287        final ContentResolver resolver = mContext.getContentResolver();
10288        String debugApp = Settings.Global.getString(
10289            resolver, Settings.Global.DEBUG_APP);
10290        boolean waitForDebugger = Settings.Global.getInt(
10291            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10292        boolean alwaysFinishActivities = Settings.Global.getInt(
10293            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10294        boolean forceRtl = Settings.Global.getInt(
10295                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10296        // Transfer any global setting for forcing RTL layout, into a System Property
10297        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10298
10299        Configuration configuration = new Configuration();
10300        Settings.System.getConfiguration(resolver, configuration);
10301        if (forceRtl) {
10302            // This will take care of setting the correct layout direction flags
10303            configuration.setLayoutDirection(configuration.locale);
10304        }
10305
10306        synchronized (this) {
10307            mDebugApp = mOrigDebugApp = debugApp;
10308            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10309            mAlwaysFinishActivities = alwaysFinishActivities;
10310            // This happens before any activities are started, so we can
10311            // change mConfiguration in-place.
10312            updateConfigurationLocked(configuration, null, false, true);
10313            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10314        }
10315    }
10316
10317    public boolean testIsSystemReady() {
10318        // no need to synchronize(this) just to read & return the value
10319        return mSystemReady;
10320    }
10321
10322    private static File getCalledPreBootReceiversFile() {
10323        File dataDir = Environment.getDataDirectory();
10324        File systemDir = new File(dataDir, "system");
10325        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10326        return fname;
10327    }
10328
10329    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10330        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10331        File file = getCalledPreBootReceiversFile();
10332        FileInputStream fis = null;
10333        try {
10334            fis = new FileInputStream(file);
10335            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10336            int fvers = dis.readInt();
10337            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10338                String vers = dis.readUTF();
10339                String codename = dis.readUTF();
10340                String build = dis.readUTF();
10341                if (android.os.Build.VERSION.RELEASE.equals(vers)
10342                        && android.os.Build.VERSION.CODENAME.equals(codename)
10343                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10344                    int num = dis.readInt();
10345                    while (num > 0) {
10346                        num--;
10347                        String pkg = dis.readUTF();
10348                        String cls = dis.readUTF();
10349                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10350                    }
10351                }
10352            }
10353        } catch (FileNotFoundException e) {
10354        } catch (IOException e) {
10355            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10356        } finally {
10357            if (fis != null) {
10358                try {
10359                    fis.close();
10360                } catch (IOException e) {
10361                }
10362            }
10363        }
10364        return lastDoneReceivers;
10365    }
10366
10367    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10368        File file = getCalledPreBootReceiversFile();
10369        FileOutputStream fos = null;
10370        DataOutputStream dos = null;
10371        try {
10372            fos = new FileOutputStream(file);
10373            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10374            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10375            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10376            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10377            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10378            dos.writeInt(list.size());
10379            for (int i=0; i<list.size(); i++) {
10380                dos.writeUTF(list.get(i).getPackageName());
10381                dos.writeUTF(list.get(i).getClassName());
10382            }
10383        } catch (IOException e) {
10384            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10385            file.delete();
10386        } finally {
10387            FileUtils.sync(fos);
10388            if (dos != null) {
10389                try {
10390                    dos.close();
10391                } catch (IOException e) {
10392                    // TODO Auto-generated catch block
10393                    e.printStackTrace();
10394                }
10395            }
10396        }
10397    }
10398
10399    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10400            ArrayList<ComponentName> doneReceivers, int userId) {
10401        boolean waitingUpdate = false;
10402        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10403        List<ResolveInfo> ris = null;
10404        try {
10405            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10406                    intent, null, 0, userId);
10407        } catch (RemoteException e) {
10408        }
10409        if (ris != null) {
10410            for (int i=ris.size()-1; i>=0; i--) {
10411                if ((ris.get(i).activityInfo.applicationInfo.flags
10412                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10413                    ris.remove(i);
10414                }
10415            }
10416            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10417
10418            // For User 0, load the version number. When delivering to a new user, deliver
10419            // to all receivers.
10420            if (userId == UserHandle.USER_OWNER) {
10421                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10422                for (int i=0; i<ris.size(); i++) {
10423                    ActivityInfo ai = ris.get(i).activityInfo;
10424                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10425                    if (lastDoneReceivers.contains(comp)) {
10426                        // We already did the pre boot receiver for this app with the current
10427                        // platform version, so don't do it again...
10428                        ris.remove(i);
10429                        i--;
10430                        // ...however, do keep it as one that has been done, so we don't
10431                        // forget about it when rewriting the file of last done receivers.
10432                        doneReceivers.add(comp);
10433                    }
10434                }
10435            }
10436
10437            // If primary user, send broadcast to all available users, else just to userId
10438            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10439                    : new int[] { userId };
10440            for (int i = 0; i < ris.size(); i++) {
10441                ActivityInfo ai = ris.get(i).activityInfo;
10442                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10443                doneReceivers.add(comp);
10444                intent.setComponent(comp);
10445                for (int j=0; j<users.length; j++) {
10446                    IIntentReceiver finisher = null;
10447                    // On last receiver and user, set up a completion callback
10448                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10449                        finisher = new IIntentReceiver.Stub() {
10450                            public void performReceive(Intent intent, int resultCode,
10451                                    String data, Bundle extras, boolean ordered,
10452                                    boolean sticky, int sendingUser) {
10453                                // The raw IIntentReceiver interface is called
10454                                // with the AM lock held, so redispatch to
10455                                // execute our code without the lock.
10456                                mHandler.post(onFinishCallback);
10457                            }
10458                        };
10459                    }
10460                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10461                            + " for user " + users[j]);
10462                    broadcastIntentLocked(null, null, intent, null, finisher,
10463                            0, null, null, null, AppOpsManager.OP_NONE,
10464                            true, false, MY_PID, Process.SYSTEM_UID,
10465                            users[j]);
10466                    if (finisher != null) {
10467                        waitingUpdate = true;
10468                    }
10469                }
10470            }
10471        }
10472
10473        return waitingUpdate;
10474    }
10475
10476    public void systemReady(final Runnable goingCallback) {
10477        synchronized(this) {
10478            if (mSystemReady) {
10479                // If we're done calling all the receivers, run the next "boot phase" passed in
10480                // by the SystemServer
10481                if (goingCallback != null) {
10482                    goingCallback.run();
10483                }
10484                return;
10485            }
10486
10487            // Make sure we have the current profile info, since it is needed for
10488            // security checks.
10489            updateCurrentProfileIdsLocked();
10490
10491            if (mRecentTasks == null) {
10492                mRecentTasks = mTaskPersister.restoreTasksLocked();
10493                if (!mRecentTasks.isEmpty()) {
10494                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10495                }
10496                mTaskPersister.startPersisting();
10497            }
10498
10499            // Check to see if there are any update receivers to run.
10500            if (!mDidUpdate) {
10501                if (mWaitingUpdate) {
10502                    return;
10503                }
10504                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10505                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10506                    public void run() {
10507                        synchronized (ActivityManagerService.this) {
10508                            mDidUpdate = true;
10509                        }
10510                        writeLastDonePreBootReceivers(doneReceivers);
10511                        showBootMessage(mContext.getText(
10512                                R.string.android_upgrading_complete),
10513                                false);
10514                        systemReady(goingCallback);
10515                    }
10516                }, doneReceivers, UserHandle.USER_OWNER);
10517
10518                if (mWaitingUpdate) {
10519                    return;
10520                }
10521                mDidUpdate = true;
10522            }
10523
10524            mAppOpsService.systemReady();
10525            mSystemReady = true;
10526        }
10527
10528        ArrayList<ProcessRecord> procsToKill = null;
10529        synchronized(mPidsSelfLocked) {
10530            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10531                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10532                if (!isAllowedWhileBooting(proc.info)){
10533                    if (procsToKill == null) {
10534                        procsToKill = new ArrayList<ProcessRecord>();
10535                    }
10536                    procsToKill.add(proc);
10537                }
10538            }
10539        }
10540
10541        synchronized(this) {
10542            if (procsToKill != null) {
10543                for (int i=procsToKill.size()-1; i>=0; i--) {
10544                    ProcessRecord proc = procsToKill.get(i);
10545                    Slog.i(TAG, "Removing system update proc: " + proc);
10546                    removeProcessLocked(proc, true, false, "system update done");
10547                }
10548            }
10549
10550            // Now that we have cleaned up any update processes, we
10551            // are ready to start launching real processes and know that
10552            // we won't trample on them any more.
10553            mProcessesReady = true;
10554        }
10555
10556        Slog.i(TAG, "System now ready");
10557        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10558            SystemClock.uptimeMillis());
10559
10560        synchronized(this) {
10561            // Make sure we have no pre-ready processes sitting around.
10562
10563            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10564                ResolveInfo ri = mContext.getPackageManager()
10565                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10566                                STOCK_PM_FLAGS);
10567                CharSequence errorMsg = null;
10568                if (ri != null) {
10569                    ActivityInfo ai = ri.activityInfo;
10570                    ApplicationInfo app = ai.applicationInfo;
10571                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10572                        mTopAction = Intent.ACTION_FACTORY_TEST;
10573                        mTopData = null;
10574                        mTopComponent = new ComponentName(app.packageName,
10575                                ai.name);
10576                    } else {
10577                        errorMsg = mContext.getResources().getText(
10578                                com.android.internal.R.string.factorytest_not_system);
10579                    }
10580                } else {
10581                    errorMsg = mContext.getResources().getText(
10582                            com.android.internal.R.string.factorytest_no_action);
10583                }
10584                if (errorMsg != null) {
10585                    mTopAction = null;
10586                    mTopData = null;
10587                    mTopComponent = null;
10588                    Message msg = Message.obtain();
10589                    msg.what = SHOW_FACTORY_ERROR_MSG;
10590                    msg.getData().putCharSequence("msg", errorMsg);
10591                    mHandler.sendMessage(msg);
10592                }
10593            }
10594        }
10595
10596        retrieveSettings();
10597
10598        synchronized (this) {
10599            readGrantedUriPermissionsLocked();
10600        }
10601
10602        if (goingCallback != null) goingCallback.run();
10603
10604        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10605                Integer.toString(mCurrentUserId), mCurrentUserId);
10606        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10607                Integer.toString(mCurrentUserId), mCurrentUserId);
10608        mSystemServiceManager.startUser(mCurrentUserId);
10609
10610        synchronized (this) {
10611            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10612                try {
10613                    List apps = AppGlobals.getPackageManager().
10614                        getPersistentApplications(STOCK_PM_FLAGS);
10615                    if (apps != null) {
10616                        int N = apps.size();
10617                        int i;
10618                        for (i=0; i<N; i++) {
10619                            ApplicationInfo info
10620                                = (ApplicationInfo)apps.get(i);
10621                            if (info != null &&
10622                                    !info.packageName.equals("android")) {
10623                                addAppLocked(info, false, null /* ABI override */);
10624                            }
10625                        }
10626                    }
10627                } catch (RemoteException ex) {
10628                    // pm is in same process, this will never happen.
10629                }
10630            }
10631
10632            // Start up initial activity.
10633            mBooting = true;
10634
10635            try {
10636                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10637                    Message msg = Message.obtain();
10638                    msg.what = SHOW_UID_ERROR_MSG;
10639                    mHandler.sendMessage(msg);
10640                }
10641            } catch (RemoteException e) {
10642            }
10643
10644            long ident = Binder.clearCallingIdentity();
10645            try {
10646                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10647                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10648                        | Intent.FLAG_RECEIVER_FOREGROUND);
10649                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10650                broadcastIntentLocked(null, null, intent,
10651                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10652                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10653                intent = new Intent(Intent.ACTION_USER_STARTING);
10654                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10655                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10656                broadcastIntentLocked(null, null, intent,
10657                        null, new IIntentReceiver.Stub() {
10658                            @Override
10659                            public void performReceive(Intent intent, int resultCode, String data,
10660                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10661                                    throws RemoteException {
10662                            }
10663                        }, 0, null, null,
10664                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10665                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10666            } catch (Throwable t) {
10667                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10668            } finally {
10669                Binder.restoreCallingIdentity(ident);
10670            }
10671            mStackSupervisor.resumeTopActivitiesLocked();
10672            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10673        }
10674    }
10675
10676    private boolean makeAppCrashingLocked(ProcessRecord app,
10677            String shortMsg, String longMsg, String stackTrace) {
10678        app.crashing = true;
10679        app.crashingReport = generateProcessError(app,
10680                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10681        startAppProblemLocked(app);
10682        app.stopFreezingAllLocked();
10683        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10684    }
10685
10686    private void makeAppNotRespondingLocked(ProcessRecord app,
10687            String activity, String shortMsg, String longMsg) {
10688        app.notResponding = true;
10689        app.notRespondingReport = generateProcessError(app,
10690                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10691                activity, shortMsg, longMsg, null);
10692        startAppProblemLocked(app);
10693        app.stopFreezingAllLocked();
10694    }
10695
10696    /**
10697     * Generate a process error record, suitable for attachment to a ProcessRecord.
10698     *
10699     * @param app The ProcessRecord in which the error occurred.
10700     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10701     *                      ActivityManager.AppErrorStateInfo
10702     * @param activity The activity associated with the crash, if known.
10703     * @param shortMsg Short message describing the crash.
10704     * @param longMsg Long message describing the crash.
10705     * @param stackTrace Full crash stack trace, may be null.
10706     *
10707     * @return Returns a fully-formed AppErrorStateInfo record.
10708     */
10709    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10710            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10711        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10712
10713        report.condition = condition;
10714        report.processName = app.processName;
10715        report.pid = app.pid;
10716        report.uid = app.info.uid;
10717        report.tag = activity;
10718        report.shortMsg = shortMsg;
10719        report.longMsg = longMsg;
10720        report.stackTrace = stackTrace;
10721
10722        return report;
10723    }
10724
10725    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10726        synchronized (this) {
10727            app.crashing = false;
10728            app.crashingReport = null;
10729            app.notResponding = false;
10730            app.notRespondingReport = null;
10731            if (app.anrDialog == fromDialog) {
10732                app.anrDialog = null;
10733            }
10734            if (app.waitDialog == fromDialog) {
10735                app.waitDialog = null;
10736            }
10737            if (app.pid > 0 && app.pid != MY_PID) {
10738                handleAppCrashLocked(app, null, null, null);
10739                killUnneededProcessLocked(app, "user request after error");
10740            }
10741        }
10742    }
10743
10744    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10745            String stackTrace) {
10746        long now = SystemClock.uptimeMillis();
10747
10748        Long crashTime;
10749        if (!app.isolated) {
10750            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10751        } else {
10752            crashTime = null;
10753        }
10754        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10755            // This process loses!
10756            Slog.w(TAG, "Process " + app.info.processName
10757                    + " has crashed too many times: killing!");
10758            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10759                    app.userId, app.info.processName, app.uid);
10760            mStackSupervisor.handleAppCrashLocked(app);
10761            if (!app.persistent) {
10762                // We don't want to start this process again until the user
10763                // explicitly does so...  but for persistent process, we really
10764                // need to keep it running.  If a persistent process is actually
10765                // repeatedly crashing, then badness for everyone.
10766                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10767                        app.info.processName);
10768                if (!app.isolated) {
10769                    // XXX We don't have a way to mark isolated processes
10770                    // as bad, since they don't have a peristent identity.
10771                    mBadProcesses.put(app.info.processName, app.uid,
10772                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10773                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10774                }
10775                app.bad = true;
10776                app.removed = true;
10777                // Don't let services in this process be restarted and potentially
10778                // annoy the user repeatedly.  Unless it is persistent, since those
10779                // processes run critical code.
10780                removeProcessLocked(app, false, false, "crash");
10781                mStackSupervisor.resumeTopActivitiesLocked();
10782                return false;
10783            }
10784            mStackSupervisor.resumeTopActivitiesLocked();
10785        } else {
10786            mStackSupervisor.finishTopRunningActivityLocked(app);
10787        }
10788
10789        // Bump up the crash count of any services currently running in the proc.
10790        for (int i=app.services.size()-1; i>=0; i--) {
10791            // Any services running in the application need to be placed
10792            // back in the pending list.
10793            ServiceRecord sr = app.services.valueAt(i);
10794            sr.crashCount++;
10795        }
10796
10797        // If the crashing process is what we consider to be the "home process" and it has been
10798        // replaced by a third-party app, clear the package preferred activities from packages
10799        // with a home activity running in the process to prevent a repeatedly crashing app
10800        // from blocking the user to manually clear the list.
10801        final ArrayList<ActivityRecord> activities = app.activities;
10802        if (app == mHomeProcess && activities.size() > 0
10803                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10804            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10805                final ActivityRecord r = activities.get(activityNdx);
10806                if (r.isHomeActivity()) {
10807                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10808                    try {
10809                        ActivityThread.getPackageManager()
10810                                .clearPackagePreferredActivities(r.packageName);
10811                    } catch (RemoteException c) {
10812                        // pm is in same process, this will never happen.
10813                    }
10814                }
10815            }
10816        }
10817
10818        if (!app.isolated) {
10819            // XXX Can't keep track of crash times for isolated processes,
10820            // because they don't have a perisistent identity.
10821            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10822        }
10823
10824        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10825        return true;
10826    }
10827
10828    void startAppProblemLocked(ProcessRecord app) {
10829        // If this app is not running under the current user, then we
10830        // can't give it a report button because that would require
10831        // launching the report UI under a different user.
10832        app.errorReportReceiver = null;
10833
10834        for (int userId : mCurrentProfileIds) {
10835            if (app.userId == userId) {
10836                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10837                        mContext, app.info.packageName, app.info.flags);
10838            }
10839        }
10840        skipCurrentReceiverLocked(app);
10841    }
10842
10843    void skipCurrentReceiverLocked(ProcessRecord app) {
10844        for (BroadcastQueue queue : mBroadcastQueues) {
10845            queue.skipCurrentReceiverLocked(app);
10846        }
10847    }
10848
10849    /**
10850     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10851     * The application process will exit immediately after this call returns.
10852     * @param app object of the crashing app, null for the system server
10853     * @param crashInfo describing the exception
10854     */
10855    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10856        ProcessRecord r = findAppProcess(app, "Crash");
10857        final String processName = app == null ? "system_server"
10858                : (r == null ? "unknown" : r.processName);
10859
10860        handleApplicationCrashInner("crash", r, processName, crashInfo);
10861    }
10862
10863    /* Native crash reporting uses this inner version because it needs to be somewhat
10864     * decoupled from the AM-managed cleanup lifecycle
10865     */
10866    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10867            ApplicationErrorReport.CrashInfo crashInfo) {
10868        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10869                UserHandle.getUserId(Binder.getCallingUid()), processName,
10870                r == null ? -1 : r.info.flags,
10871                crashInfo.exceptionClassName,
10872                crashInfo.exceptionMessage,
10873                crashInfo.throwFileName,
10874                crashInfo.throwLineNumber);
10875
10876        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10877
10878        crashApplication(r, crashInfo);
10879    }
10880
10881    public void handleApplicationStrictModeViolation(
10882            IBinder app,
10883            int violationMask,
10884            StrictMode.ViolationInfo info) {
10885        ProcessRecord r = findAppProcess(app, "StrictMode");
10886        if (r == null) {
10887            return;
10888        }
10889
10890        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10891            Integer stackFingerprint = info.hashCode();
10892            boolean logIt = true;
10893            synchronized (mAlreadyLoggedViolatedStacks) {
10894                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10895                    logIt = false;
10896                    // TODO: sub-sample into EventLog for these, with
10897                    // the info.durationMillis?  Then we'd get
10898                    // the relative pain numbers, without logging all
10899                    // the stack traces repeatedly.  We'd want to do
10900                    // likewise in the client code, which also does
10901                    // dup suppression, before the Binder call.
10902                } else {
10903                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10904                        mAlreadyLoggedViolatedStacks.clear();
10905                    }
10906                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10907                }
10908            }
10909            if (logIt) {
10910                logStrictModeViolationToDropBox(r, info);
10911            }
10912        }
10913
10914        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10915            AppErrorResult result = new AppErrorResult();
10916            synchronized (this) {
10917                final long origId = Binder.clearCallingIdentity();
10918
10919                Message msg = Message.obtain();
10920                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10921                HashMap<String, Object> data = new HashMap<String, Object>();
10922                data.put("result", result);
10923                data.put("app", r);
10924                data.put("violationMask", violationMask);
10925                data.put("info", info);
10926                msg.obj = data;
10927                mHandler.sendMessage(msg);
10928
10929                Binder.restoreCallingIdentity(origId);
10930            }
10931            int res = result.get();
10932            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10933        }
10934    }
10935
10936    // Depending on the policy in effect, there could be a bunch of
10937    // these in quick succession so we try to batch these together to
10938    // minimize disk writes, number of dropbox entries, and maximize
10939    // compression, by having more fewer, larger records.
10940    private void logStrictModeViolationToDropBox(
10941            ProcessRecord process,
10942            StrictMode.ViolationInfo info) {
10943        if (info == null) {
10944            return;
10945        }
10946        final boolean isSystemApp = process == null ||
10947                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10948                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10949        final String processName = process == null ? "unknown" : process.processName;
10950        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10951        final DropBoxManager dbox = (DropBoxManager)
10952                mContext.getSystemService(Context.DROPBOX_SERVICE);
10953
10954        // Exit early if the dropbox isn't configured to accept this report type.
10955        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10956
10957        boolean bufferWasEmpty;
10958        boolean needsFlush;
10959        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10960        synchronized (sb) {
10961            bufferWasEmpty = sb.length() == 0;
10962            appendDropBoxProcessHeaders(process, processName, sb);
10963            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10964            sb.append("System-App: ").append(isSystemApp).append("\n");
10965            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10966            if (info.violationNumThisLoop != 0) {
10967                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10968            }
10969            if (info.numAnimationsRunning != 0) {
10970                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10971            }
10972            if (info.broadcastIntentAction != null) {
10973                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10974            }
10975            if (info.durationMillis != -1) {
10976                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10977            }
10978            if (info.numInstances != -1) {
10979                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10980            }
10981            if (info.tags != null) {
10982                for (String tag : info.tags) {
10983                    sb.append("Span-Tag: ").append(tag).append("\n");
10984                }
10985            }
10986            sb.append("\n");
10987            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10988                sb.append(info.crashInfo.stackTrace);
10989            }
10990            sb.append("\n");
10991
10992            // Only buffer up to ~64k.  Various logging bits truncate
10993            // things at 128k.
10994            needsFlush = (sb.length() > 64 * 1024);
10995        }
10996
10997        // Flush immediately if the buffer's grown too large, or this
10998        // is a non-system app.  Non-system apps are isolated with a
10999        // different tag & policy and not batched.
11000        //
11001        // Batching is useful during internal testing with
11002        // StrictMode settings turned up high.  Without batching,
11003        // thousands of separate files could be created on boot.
11004        if (!isSystemApp || needsFlush) {
11005            new Thread("Error dump: " + dropboxTag) {
11006                @Override
11007                public void run() {
11008                    String report;
11009                    synchronized (sb) {
11010                        report = sb.toString();
11011                        sb.delete(0, sb.length());
11012                        sb.trimToSize();
11013                    }
11014                    if (report.length() != 0) {
11015                        dbox.addText(dropboxTag, report);
11016                    }
11017                }
11018            }.start();
11019            return;
11020        }
11021
11022        // System app batching:
11023        if (!bufferWasEmpty) {
11024            // An existing dropbox-writing thread is outstanding, so
11025            // we don't need to start it up.  The existing thread will
11026            // catch the buffer appends we just did.
11027            return;
11028        }
11029
11030        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11031        // (After this point, we shouldn't access AMS internal data structures.)
11032        new Thread("Error dump: " + dropboxTag) {
11033            @Override
11034            public void run() {
11035                // 5 second sleep to let stacks arrive and be batched together
11036                try {
11037                    Thread.sleep(5000);  // 5 seconds
11038                } catch (InterruptedException e) {}
11039
11040                String errorReport;
11041                synchronized (mStrictModeBuffer) {
11042                    errorReport = mStrictModeBuffer.toString();
11043                    if (errorReport.length() == 0) {
11044                        return;
11045                    }
11046                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11047                    mStrictModeBuffer.trimToSize();
11048                }
11049                dbox.addText(dropboxTag, errorReport);
11050            }
11051        }.start();
11052    }
11053
11054    /**
11055     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11056     * @param app object of the crashing app, null for the system server
11057     * @param tag reported by the caller
11058     * @param crashInfo describing the context of the error
11059     * @return true if the process should exit immediately (WTF is fatal)
11060     */
11061    public boolean handleApplicationWtf(IBinder app, String tag,
11062            ApplicationErrorReport.CrashInfo crashInfo) {
11063        ProcessRecord r = findAppProcess(app, "WTF");
11064        final String processName = app == null ? "system_server"
11065                : (r == null ? "unknown" : r.processName);
11066
11067        EventLog.writeEvent(EventLogTags.AM_WTF,
11068                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11069                processName,
11070                r == null ? -1 : r.info.flags,
11071                tag, crashInfo.exceptionMessage);
11072
11073        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11074
11075        if (r != null && r.pid != Process.myPid() &&
11076                Settings.Global.getInt(mContext.getContentResolver(),
11077                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11078            crashApplication(r, crashInfo);
11079            return true;
11080        } else {
11081            return false;
11082        }
11083    }
11084
11085    /**
11086     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11087     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11088     */
11089    private ProcessRecord findAppProcess(IBinder app, String reason) {
11090        if (app == null) {
11091            return null;
11092        }
11093
11094        synchronized (this) {
11095            final int NP = mProcessNames.getMap().size();
11096            for (int ip=0; ip<NP; ip++) {
11097                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11098                final int NA = apps.size();
11099                for (int ia=0; ia<NA; ia++) {
11100                    ProcessRecord p = apps.valueAt(ia);
11101                    if (p.thread != null && p.thread.asBinder() == app) {
11102                        return p;
11103                    }
11104                }
11105            }
11106
11107            Slog.w(TAG, "Can't find mystery application for " + reason
11108                    + " from pid=" + Binder.getCallingPid()
11109                    + " uid=" + Binder.getCallingUid() + ": " + app);
11110            return null;
11111        }
11112    }
11113
11114    /**
11115     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11116     * to append various headers to the dropbox log text.
11117     */
11118    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11119            StringBuilder sb) {
11120        // Watchdog thread ends up invoking this function (with
11121        // a null ProcessRecord) to add the stack file to dropbox.
11122        // Do not acquire a lock on this (am) in such cases, as it
11123        // could cause a potential deadlock, if and when watchdog
11124        // is invoked due to unavailability of lock on am and it
11125        // would prevent watchdog from killing system_server.
11126        if (process == null) {
11127            sb.append("Process: ").append(processName).append("\n");
11128            return;
11129        }
11130        // Note: ProcessRecord 'process' is guarded by the service
11131        // instance.  (notably process.pkgList, which could otherwise change
11132        // concurrently during execution of this method)
11133        synchronized (this) {
11134            sb.append("Process: ").append(processName).append("\n");
11135            int flags = process.info.flags;
11136            IPackageManager pm = AppGlobals.getPackageManager();
11137            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11138            for (int ip=0; ip<process.pkgList.size(); ip++) {
11139                String pkg = process.pkgList.keyAt(ip);
11140                sb.append("Package: ").append(pkg);
11141                try {
11142                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11143                    if (pi != null) {
11144                        sb.append(" v").append(pi.versionCode);
11145                        if (pi.versionName != null) {
11146                            sb.append(" (").append(pi.versionName).append(")");
11147                        }
11148                    }
11149                } catch (RemoteException e) {
11150                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11151                }
11152                sb.append("\n");
11153            }
11154        }
11155    }
11156
11157    private static String processClass(ProcessRecord process) {
11158        if (process == null || process.pid == MY_PID) {
11159            return "system_server";
11160        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11161            return "system_app";
11162        } else {
11163            return "data_app";
11164        }
11165    }
11166
11167    /**
11168     * Write a description of an error (crash, WTF, ANR) to the drop box.
11169     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11170     * @param process which caused the error, null means the system server
11171     * @param activity which triggered the error, null if unknown
11172     * @param parent activity related to the error, null if unknown
11173     * @param subject line related to the error, null if absent
11174     * @param report in long form describing the error, null if absent
11175     * @param logFile to include in the report, null if none
11176     * @param crashInfo giving an application stack trace, null if absent
11177     */
11178    public void addErrorToDropBox(String eventType,
11179            ProcessRecord process, String processName, ActivityRecord activity,
11180            ActivityRecord parent, String subject,
11181            final String report, final File logFile,
11182            final ApplicationErrorReport.CrashInfo crashInfo) {
11183        // NOTE -- this must never acquire the ActivityManagerService lock,
11184        // otherwise the watchdog may be prevented from resetting the system.
11185
11186        final String dropboxTag = processClass(process) + "_" + eventType;
11187        final DropBoxManager dbox = (DropBoxManager)
11188                mContext.getSystemService(Context.DROPBOX_SERVICE);
11189
11190        // Exit early if the dropbox isn't configured to accept this report type.
11191        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11192
11193        final StringBuilder sb = new StringBuilder(1024);
11194        appendDropBoxProcessHeaders(process, processName, sb);
11195        if (activity != null) {
11196            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11197        }
11198        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11199            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11200        }
11201        if (parent != null && parent != activity) {
11202            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11203        }
11204        if (subject != null) {
11205            sb.append("Subject: ").append(subject).append("\n");
11206        }
11207        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11208        if (Debug.isDebuggerConnected()) {
11209            sb.append("Debugger: Connected\n");
11210        }
11211        sb.append("\n");
11212
11213        // Do the rest in a worker thread to avoid blocking the caller on I/O
11214        // (After this point, we shouldn't access AMS internal data structures.)
11215        Thread worker = new Thread("Error dump: " + dropboxTag) {
11216            @Override
11217            public void run() {
11218                if (report != null) {
11219                    sb.append(report);
11220                }
11221                if (logFile != null) {
11222                    try {
11223                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11224                                    "\n\n[[TRUNCATED]]"));
11225                    } catch (IOException e) {
11226                        Slog.e(TAG, "Error reading " + logFile, e);
11227                    }
11228                }
11229                if (crashInfo != null && crashInfo.stackTrace != null) {
11230                    sb.append(crashInfo.stackTrace);
11231                }
11232
11233                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11234                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11235                if (lines > 0) {
11236                    sb.append("\n");
11237
11238                    // Merge several logcat streams, and take the last N lines
11239                    InputStreamReader input = null;
11240                    try {
11241                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11242                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11243                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11244
11245                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11246                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11247                        input = new InputStreamReader(logcat.getInputStream());
11248
11249                        int num;
11250                        char[] buf = new char[8192];
11251                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11252                    } catch (IOException e) {
11253                        Slog.e(TAG, "Error running logcat", e);
11254                    } finally {
11255                        if (input != null) try { input.close(); } catch (IOException e) {}
11256                    }
11257                }
11258
11259                dbox.addText(dropboxTag, sb.toString());
11260            }
11261        };
11262
11263        if (process == null) {
11264            // If process is null, we are being called from some internal code
11265            // and may be about to die -- run this synchronously.
11266            worker.run();
11267        } else {
11268            worker.start();
11269        }
11270    }
11271
11272    /**
11273     * Bring up the "unexpected error" dialog box for a crashing app.
11274     * Deal with edge cases (intercepts from instrumented applications,
11275     * ActivityController, error intent receivers, that sort of thing).
11276     * @param r the application crashing
11277     * @param crashInfo describing the failure
11278     */
11279    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11280        long timeMillis = System.currentTimeMillis();
11281        String shortMsg = crashInfo.exceptionClassName;
11282        String longMsg = crashInfo.exceptionMessage;
11283        String stackTrace = crashInfo.stackTrace;
11284        if (shortMsg != null && longMsg != null) {
11285            longMsg = shortMsg + ": " + longMsg;
11286        } else if (shortMsg != null) {
11287            longMsg = shortMsg;
11288        }
11289
11290        AppErrorResult result = new AppErrorResult();
11291        synchronized (this) {
11292            if (mController != null) {
11293                try {
11294                    String name = r != null ? r.processName : null;
11295                    int pid = r != null ? r.pid : Binder.getCallingPid();
11296                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11297                    if (!mController.appCrashed(name, pid,
11298                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11299                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11300                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11301                            Slog.w(TAG, "Skip killing native crashed app " + name
11302                                    + "(" + pid + ") during testing");
11303                        } else {
11304                            Slog.w(TAG, "Force-killing crashed app " + name
11305                                    + " at watcher's request");
11306                            Process.killProcess(pid);
11307                            if (r != null) {
11308                                Process.killProcessGroup(uid, pid);
11309                            }
11310                        }
11311                        return;
11312                    }
11313                } catch (RemoteException e) {
11314                    mController = null;
11315                    Watchdog.getInstance().setActivityController(null);
11316                }
11317            }
11318
11319            final long origId = Binder.clearCallingIdentity();
11320
11321            // If this process is running instrumentation, finish it.
11322            if (r != null && r.instrumentationClass != null) {
11323                Slog.w(TAG, "Error in app " + r.processName
11324                      + " running instrumentation " + r.instrumentationClass + ":");
11325                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11326                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11327                Bundle info = new Bundle();
11328                info.putString("shortMsg", shortMsg);
11329                info.putString("longMsg", longMsg);
11330                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11331                Binder.restoreCallingIdentity(origId);
11332                return;
11333            }
11334
11335            // If we can't identify the process or it's already exceeded its crash quota,
11336            // quit right away without showing a crash dialog.
11337            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11338                Binder.restoreCallingIdentity(origId);
11339                return;
11340            }
11341
11342            Message msg = Message.obtain();
11343            msg.what = SHOW_ERROR_MSG;
11344            HashMap data = new HashMap();
11345            data.put("result", result);
11346            data.put("app", r);
11347            msg.obj = data;
11348            mHandler.sendMessage(msg);
11349
11350            Binder.restoreCallingIdentity(origId);
11351        }
11352
11353        int res = result.get();
11354
11355        Intent appErrorIntent = null;
11356        synchronized (this) {
11357            if (r != null && !r.isolated) {
11358                // XXX Can't keep track of crash time for isolated processes,
11359                // since they don't have a persistent identity.
11360                mProcessCrashTimes.put(r.info.processName, r.uid,
11361                        SystemClock.uptimeMillis());
11362            }
11363            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11364                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11365            }
11366        }
11367
11368        if (appErrorIntent != null) {
11369            try {
11370                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11371            } catch (ActivityNotFoundException e) {
11372                Slog.w(TAG, "bug report receiver dissappeared", e);
11373            }
11374        }
11375    }
11376
11377    Intent createAppErrorIntentLocked(ProcessRecord r,
11378            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11379        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11380        if (report == null) {
11381            return null;
11382        }
11383        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11384        result.setComponent(r.errorReportReceiver);
11385        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11386        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11387        return result;
11388    }
11389
11390    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11391            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11392        if (r.errorReportReceiver == null) {
11393            return null;
11394        }
11395
11396        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11397            return null;
11398        }
11399
11400        ApplicationErrorReport report = new ApplicationErrorReport();
11401        report.packageName = r.info.packageName;
11402        report.installerPackageName = r.errorReportReceiver.getPackageName();
11403        report.processName = r.processName;
11404        report.time = timeMillis;
11405        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11406
11407        if (r.crashing || r.forceCrashReport) {
11408            report.type = ApplicationErrorReport.TYPE_CRASH;
11409            report.crashInfo = crashInfo;
11410        } else if (r.notResponding) {
11411            report.type = ApplicationErrorReport.TYPE_ANR;
11412            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11413
11414            report.anrInfo.activity = r.notRespondingReport.tag;
11415            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11416            report.anrInfo.info = r.notRespondingReport.longMsg;
11417        }
11418
11419        return report;
11420    }
11421
11422    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11423        enforceNotIsolatedCaller("getProcessesInErrorState");
11424        // assume our apps are happy - lazy create the list
11425        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11426
11427        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11428                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11429        int userId = UserHandle.getUserId(Binder.getCallingUid());
11430
11431        synchronized (this) {
11432
11433            // iterate across all processes
11434            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11435                ProcessRecord app = mLruProcesses.get(i);
11436                if (!allUsers && app.userId != userId) {
11437                    continue;
11438                }
11439                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11440                    // This one's in trouble, so we'll generate a report for it
11441                    // crashes are higher priority (in case there's a crash *and* an anr)
11442                    ActivityManager.ProcessErrorStateInfo report = null;
11443                    if (app.crashing) {
11444                        report = app.crashingReport;
11445                    } else if (app.notResponding) {
11446                        report = app.notRespondingReport;
11447                    }
11448
11449                    if (report != null) {
11450                        if (errList == null) {
11451                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11452                        }
11453                        errList.add(report);
11454                    } else {
11455                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11456                                " crashing = " + app.crashing +
11457                                " notResponding = " + app.notResponding);
11458                    }
11459                }
11460            }
11461        }
11462
11463        return errList;
11464    }
11465
11466    static int procStateToImportance(int procState, int memAdj,
11467            ActivityManager.RunningAppProcessInfo currApp) {
11468        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11469        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11470            currApp.lru = memAdj;
11471        } else {
11472            currApp.lru = 0;
11473        }
11474        return imp;
11475    }
11476
11477    private void fillInProcMemInfo(ProcessRecord app,
11478            ActivityManager.RunningAppProcessInfo outInfo) {
11479        outInfo.pid = app.pid;
11480        outInfo.uid = app.info.uid;
11481        if (mHeavyWeightProcess == app) {
11482            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11483        }
11484        if (app.persistent) {
11485            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11486        }
11487        if (app.activities.size() > 0) {
11488            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11489        }
11490        outInfo.lastTrimLevel = app.trimMemoryLevel;
11491        int adj = app.curAdj;
11492        int procState = app.curProcState;
11493        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11494        outInfo.importanceReasonCode = app.adjTypeCode;
11495        outInfo.processState = app.curProcState;
11496    }
11497
11498    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11499        enforceNotIsolatedCaller("getRunningAppProcesses");
11500        // Lazy instantiation of list
11501        List<ActivityManager.RunningAppProcessInfo> runList = null;
11502        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11503                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11504        int userId = UserHandle.getUserId(Binder.getCallingUid());
11505        synchronized (this) {
11506            // Iterate across all processes
11507            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11508                ProcessRecord app = mLruProcesses.get(i);
11509                if (!allUsers && app.userId != userId) {
11510                    continue;
11511                }
11512                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11513                    // Generate process state info for running application
11514                    ActivityManager.RunningAppProcessInfo currApp =
11515                        new ActivityManager.RunningAppProcessInfo(app.processName,
11516                                app.pid, app.getPackageList());
11517                    fillInProcMemInfo(app, currApp);
11518                    if (app.adjSource instanceof ProcessRecord) {
11519                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11520                        currApp.importanceReasonImportance =
11521                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11522                                        app.adjSourceProcState);
11523                    } else if (app.adjSource instanceof ActivityRecord) {
11524                        ActivityRecord r = (ActivityRecord)app.adjSource;
11525                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11526                    }
11527                    if (app.adjTarget instanceof ComponentName) {
11528                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11529                    }
11530                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11531                    //        + " lru=" + currApp.lru);
11532                    if (runList == null) {
11533                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11534                    }
11535                    runList.add(currApp);
11536                }
11537            }
11538        }
11539        return runList;
11540    }
11541
11542    public List<ApplicationInfo> getRunningExternalApplications() {
11543        enforceNotIsolatedCaller("getRunningExternalApplications");
11544        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11545        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11546        if (runningApps != null && runningApps.size() > 0) {
11547            Set<String> extList = new HashSet<String>();
11548            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11549                if (app.pkgList != null) {
11550                    for (String pkg : app.pkgList) {
11551                        extList.add(pkg);
11552                    }
11553                }
11554            }
11555            IPackageManager pm = AppGlobals.getPackageManager();
11556            for (String pkg : extList) {
11557                try {
11558                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11559                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11560                        retList.add(info);
11561                    }
11562                } catch (RemoteException e) {
11563                }
11564            }
11565        }
11566        return retList;
11567    }
11568
11569    @Override
11570    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11571        enforceNotIsolatedCaller("getMyMemoryState");
11572        synchronized (this) {
11573            ProcessRecord proc;
11574            synchronized (mPidsSelfLocked) {
11575                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11576            }
11577            fillInProcMemInfo(proc, outInfo);
11578        }
11579    }
11580
11581    @Override
11582    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11583        if (checkCallingPermission(android.Manifest.permission.DUMP)
11584                != PackageManager.PERMISSION_GRANTED) {
11585            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11586                    + Binder.getCallingPid()
11587                    + ", uid=" + Binder.getCallingUid()
11588                    + " without permission "
11589                    + android.Manifest.permission.DUMP);
11590            return;
11591        }
11592
11593        boolean dumpAll = false;
11594        boolean dumpClient = false;
11595        String dumpPackage = null;
11596
11597        int opti = 0;
11598        while (opti < args.length) {
11599            String opt = args[opti];
11600            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11601                break;
11602            }
11603            opti++;
11604            if ("-a".equals(opt)) {
11605                dumpAll = true;
11606            } else if ("-c".equals(opt)) {
11607                dumpClient = true;
11608            } else if ("-h".equals(opt)) {
11609                pw.println("Activity manager dump options:");
11610                pw.println("  [-a] [-c] [-h] [cmd] ...");
11611                pw.println("  cmd may be one of:");
11612                pw.println("    a[ctivities]: activity stack state");
11613                pw.println("    r[recents]: recent activities state");
11614                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11615                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11616                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11617                pw.println("    o[om]: out of memory management");
11618                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11619                pw.println("    provider [COMP_SPEC]: provider client-side state");
11620                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11621                pw.println("    service [COMP_SPEC]: service client-side state");
11622                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11623                pw.println("    all: dump all activities");
11624                pw.println("    top: dump the top activity");
11625                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11626                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11627                pw.println("    a partial substring in a component name, a");
11628                pw.println("    hex object identifier.");
11629                pw.println("  -a: include all available server state.");
11630                pw.println("  -c: include client state.");
11631                return;
11632            } else {
11633                pw.println("Unknown argument: " + opt + "; use -h for help");
11634            }
11635        }
11636
11637        long origId = Binder.clearCallingIdentity();
11638        boolean more = false;
11639        // Is the caller requesting to dump a particular piece of data?
11640        if (opti < args.length) {
11641            String cmd = args[opti];
11642            opti++;
11643            if ("activities".equals(cmd) || "a".equals(cmd)) {
11644                synchronized (this) {
11645                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11646                }
11647            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11648                synchronized (this) {
11649                    dumpRecentsLocked(fd, pw, args, opti, true, null);
11650                }
11651            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11652                String[] newArgs;
11653                String name;
11654                if (opti >= args.length) {
11655                    name = null;
11656                    newArgs = EMPTY_STRING_ARRAY;
11657                } else {
11658                    name = args[opti];
11659                    opti++;
11660                    newArgs = new String[args.length - opti];
11661                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11662                            args.length - opti);
11663                }
11664                synchronized (this) {
11665                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11666                }
11667            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11668                String[] newArgs;
11669                String name;
11670                if (opti >= args.length) {
11671                    name = null;
11672                    newArgs = EMPTY_STRING_ARRAY;
11673                } else {
11674                    name = args[opti];
11675                    opti++;
11676                    newArgs = new String[args.length - opti];
11677                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11678                            args.length - opti);
11679                }
11680                synchronized (this) {
11681                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11682                }
11683            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11684                String[] newArgs;
11685                String name;
11686                if (opti >= args.length) {
11687                    name = null;
11688                    newArgs = EMPTY_STRING_ARRAY;
11689                } else {
11690                    name = args[opti];
11691                    opti++;
11692                    newArgs = new String[args.length - opti];
11693                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11694                            args.length - opti);
11695                }
11696                synchronized (this) {
11697                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11698                }
11699            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11700                synchronized (this) {
11701                    dumpOomLocked(fd, pw, args, opti, true);
11702                }
11703            } else if ("provider".equals(cmd)) {
11704                String[] newArgs;
11705                String name;
11706                if (opti >= args.length) {
11707                    name = null;
11708                    newArgs = EMPTY_STRING_ARRAY;
11709                } else {
11710                    name = args[opti];
11711                    opti++;
11712                    newArgs = new String[args.length - opti];
11713                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11714                }
11715                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11716                    pw.println("No providers match: " + name);
11717                    pw.println("Use -h for help.");
11718                }
11719            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11720                synchronized (this) {
11721                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11722                }
11723            } else if ("service".equals(cmd)) {
11724                String[] newArgs;
11725                String name;
11726                if (opti >= args.length) {
11727                    name = null;
11728                    newArgs = EMPTY_STRING_ARRAY;
11729                } else {
11730                    name = args[opti];
11731                    opti++;
11732                    newArgs = new String[args.length - opti];
11733                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11734                            args.length - opti);
11735                }
11736                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11737                    pw.println("No services match: " + name);
11738                    pw.println("Use -h for help.");
11739                }
11740            } else if ("package".equals(cmd)) {
11741                String[] newArgs;
11742                if (opti >= args.length) {
11743                    pw.println("package: no package name specified");
11744                    pw.println("Use -h for help.");
11745                } else {
11746                    dumpPackage = args[opti];
11747                    opti++;
11748                    newArgs = new String[args.length - opti];
11749                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11750                            args.length - opti);
11751                    args = newArgs;
11752                    opti = 0;
11753                    more = true;
11754                }
11755            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11756                synchronized (this) {
11757                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11758                }
11759            } else {
11760                // Dumping a single activity?
11761                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11762                    pw.println("Bad activity command, or no activities match: " + cmd);
11763                    pw.println("Use -h for help.");
11764                }
11765            }
11766            if (!more) {
11767                Binder.restoreCallingIdentity(origId);
11768                return;
11769            }
11770        }
11771
11772        // No piece of data specified, dump everything.
11773        synchronized (this) {
11774            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11775            pw.println();
11776            if (dumpAll) {
11777                pw.println("-------------------------------------------------------------------------------");
11778            }
11779            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11780            pw.println();
11781            if (dumpAll) {
11782                pw.println("-------------------------------------------------------------------------------");
11783            }
11784            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11785            pw.println();
11786            if (dumpAll) {
11787                pw.println("-------------------------------------------------------------------------------");
11788            }
11789            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11790            pw.println();
11791            if (dumpAll) {
11792                pw.println("-------------------------------------------------------------------------------");
11793            }
11794            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11795            pw.println();
11796            if (dumpAll) {
11797                pw.println("-------------------------------------------------------------------------------");
11798            }
11799            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11800            pw.println();
11801            if (dumpAll) {
11802                pw.println("-------------------------------------------------------------------------------");
11803            }
11804            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11805        }
11806        Binder.restoreCallingIdentity(origId);
11807    }
11808
11809    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11810            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11811        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11812
11813        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11814                dumpPackage);
11815        boolean needSep = printedAnything;
11816
11817        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11818                dumpPackage, needSep, "  mFocusedActivity: ");
11819        if (printed) {
11820            printedAnything = true;
11821            needSep = false;
11822        }
11823
11824        if (dumpPackage == null) {
11825            if (needSep) {
11826                pw.println();
11827            }
11828            needSep = true;
11829            printedAnything = true;
11830            mStackSupervisor.dump(pw, "  ");
11831        }
11832
11833        if (!printedAnything) {
11834            pw.println("  (nothing)");
11835        }
11836    }
11837
11838    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11839            int opti, boolean dumpAll, String dumpPackage) {
11840        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
11841
11842        boolean printedAnything = false;
11843
11844        if (mRecentTasks.size() > 0) {
11845            boolean printedHeader = false;
11846
11847            final int N = mRecentTasks.size();
11848            for (int i=0; i<N; i++) {
11849                TaskRecord tr = mRecentTasks.get(i);
11850                if (dumpPackage != null) {
11851                    if (tr.realActivity == null ||
11852                            !dumpPackage.equals(tr.realActivity)) {
11853                        continue;
11854                    }
11855                }
11856                if (!printedHeader) {
11857                    pw.println("  Recent tasks:");
11858                    printedHeader = true;
11859                    printedAnything = true;
11860                }
11861                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11862                        pw.println(tr);
11863                if (dumpAll) {
11864                    mRecentTasks.get(i).dump(pw, "    ");
11865                }
11866            }
11867        }
11868
11869        if (!printedAnything) {
11870            pw.println("  (nothing)");
11871        }
11872    }
11873
11874    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11875            int opti, boolean dumpAll, String dumpPackage) {
11876        boolean needSep = false;
11877        boolean printedAnything = false;
11878        int numPers = 0;
11879
11880        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11881
11882        if (dumpAll) {
11883            final int NP = mProcessNames.getMap().size();
11884            for (int ip=0; ip<NP; ip++) {
11885                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11886                final int NA = procs.size();
11887                for (int ia=0; ia<NA; ia++) {
11888                    ProcessRecord r = procs.valueAt(ia);
11889                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11890                        continue;
11891                    }
11892                    if (!needSep) {
11893                        pw.println("  All known processes:");
11894                        needSep = true;
11895                        printedAnything = true;
11896                    }
11897                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11898                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11899                        pw.print(" "); pw.println(r);
11900                    r.dump(pw, "    ");
11901                    if (r.persistent) {
11902                        numPers++;
11903                    }
11904                }
11905            }
11906        }
11907
11908        if (mIsolatedProcesses.size() > 0) {
11909            boolean printed = false;
11910            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11911                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11912                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11913                    continue;
11914                }
11915                if (!printed) {
11916                    if (needSep) {
11917                        pw.println();
11918                    }
11919                    pw.println("  Isolated process list (sorted by uid):");
11920                    printedAnything = true;
11921                    printed = true;
11922                    needSep = true;
11923                }
11924                pw.println(String.format("%sIsolated #%2d: %s",
11925                        "    ", i, r.toString()));
11926            }
11927        }
11928
11929        if (mLruProcesses.size() > 0) {
11930            if (needSep) {
11931                pw.println();
11932            }
11933            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11934                    pw.print(" total, non-act at ");
11935                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11936                    pw.print(", non-svc at ");
11937                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11938                    pw.println("):");
11939            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11940            needSep = true;
11941            printedAnything = true;
11942        }
11943
11944        if (dumpAll || dumpPackage != null) {
11945            synchronized (mPidsSelfLocked) {
11946                boolean printed = false;
11947                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11948                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11949                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11950                        continue;
11951                    }
11952                    if (!printed) {
11953                        if (needSep) pw.println();
11954                        needSep = true;
11955                        pw.println("  PID mappings:");
11956                        printed = true;
11957                        printedAnything = true;
11958                    }
11959                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11960                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11961                }
11962            }
11963        }
11964
11965        if (mForegroundProcesses.size() > 0) {
11966            synchronized (mPidsSelfLocked) {
11967                boolean printed = false;
11968                for (int i=0; i<mForegroundProcesses.size(); i++) {
11969                    ProcessRecord r = mPidsSelfLocked.get(
11970                            mForegroundProcesses.valueAt(i).pid);
11971                    if (dumpPackage != null && (r == null
11972                            || !r.pkgList.containsKey(dumpPackage))) {
11973                        continue;
11974                    }
11975                    if (!printed) {
11976                        if (needSep) pw.println();
11977                        needSep = true;
11978                        pw.println("  Foreground Processes:");
11979                        printed = true;
11980                        printedAnything = true;
11981                    }
11982                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11983                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11984                }
11985            }
11986        }
11987
11988        if (mPersistentStartingProcesses.size() > 0) {
11989            if (needSep) pw.println();
11990            needSep = true;
11991            printedAnything = true;
11992            pw.println("  Persisent processes that are starting:");
11993            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11994                    "Starting Norm", "Restarting PERS", dumpPackage);
11995        }
11996
11997        if (mRemovedProcesses.size() > 0) {
11998            if (needSep) pw.println();
11999            needSep = true;
12000            printedAnything = true;
12001            pw.println("  Processes that are being removed:");
12002            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12003                    "Removed Norm", "Removed PERS", dumpPackage);
12004        }
12005
12006        if (mProcessesOnHold.size() > 0) {
12007            if (needSep) pw.println();
12008            needSep = true;
12009            printedAnything = true;
12010            pw.println("  Processes that are on old until the system is ready:");
12011            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12012                    "OnHold Norm", "OnHold PERS", dumpPackage);
12013        }
12014
12015        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12016
12017        if (mProcessCrashTimes.getMap().size() > 0) {
12018            boolean printed = false;
12019            long now = SystemClock.uptimeMillis();
12020            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12021            final int NP = pmap.size();
12022            for (int ip=0; ip<NP; ip++) {
12023                String pname = pmap.keyAt(ip);
12024                SparseArray<Long> uids = pmap.valueAt(ip);
12025                final int N = uids.size();
12026                for (int i=0; i<N; i++) {
12027                    int puid = uids.keyAt(i);
12028                    ProcessRecord r = mProcessNames.get(pname, puid);
12029                    if (dumpPackage != null && (r == null
12030                            || !r.pkgList.containsKey(dumpPackage))) {
12031                        continue;
12032                    }
12033                    if (!printed) {
12034                        if (needSep) pw.println();
12035                        needSep = true;
12036                        pw.println("  Time since processes crashed:");
12037                        printed = true;
12038                        printedAnything = true;
12039                    }
12040                    pw.print("    Process "); pw.print(pname);
12041                            pw.print(" uid "); pw.print(puid);
12042                            pw.print(": last crashed ");
12043                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12044                            pw.println(" ago");
12045                }
12046            }
12047        }
12048
12049        if (mBadProcesses.getMap().size() > 0) {
12050            boolean printed = false;
12051            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12052            final int NP = pmap.size();
12053            for (int ip=0; ip<NP; ip++) {
12054                String pname = pmap.keyAt(ip);
12055                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12056                final int N = uids.size();
12057                for (int i=0; i<N; i++) {
12058                    int puid = uids.keyAt(i);
12059                    ProcessRecord r = mProcessNames.get(pname, puid);
12060                    if (dumpPackage != null && (r == null
12061                            || !r.pkgList.containsKey(dumpPackage))) {
12062                        continue;
12063                    }
12064                    if (!printed) {
12065                        if (needSep) pw.println();
12066                        needSep = true;
12067                        pw.println("  Bad processes:");
12068                        printedAnything = true;
12069                    }
12070                    BadProcessInfo info = uids.valueAt(i);
12071                    pw.print("    Bad process "); pw.print(pname);
12072                            pw.print(" uid "); pw.print(puid);
12073                            pw.print(": crashed at time "); pw.println(info.time);
12074                    if (info.shortMsg != null) {
12075                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12076                    }
12077                    if (info.longMsg != null) {
12078                        pw.print("      Long msg: "); pw.println(info.longMsg);
12079                    }
12080                    if (info.stack != null) {
12081                        pw.println("      Stack:");
12082                        int lastPos = 0;
12083                        for (int pos=0; pos<info.stack.length(); pos++) {
12084                            if (info.stack.charAt(pos) == '\n') {
12085                                pw.print("        ");
12086                                pw.write(info.stack, lastPos, pos-lastPos);
12087                                pw.println();
12088                                lastPos = pos+1;
12089                            }
12090                        }
12091                        if (lastPos < info.stack.length()) {
12092                            pw.print("        ");
12093                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12094                            pw.println();
12095                        }
12096                    }
12097                }
12098            }
12099        }
12100
12101        if (dumpPackage == null) {
12102            pw.println();
12103            needSep = false;
12104            pw.println("  mStartedUsers:");
12105            for (int i=0; i<mStartedUsers.size(); i++) {
12106                UserStartedState uss = mStartedUsers.valueAt(i);
12107                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12108                        pw.print(": "); uss.dump("", pw);
12109            }
12110            pw.print("  mStartedUserArray: [");
12111            for (int i=0; i<mStartedUserArray.length; i++) {
12112                if (i > 0) pw.print(", ");
12113                pw.print(mStartedUserArray[i]);
12114            }
12115            pw.println("]");
12116            pw.print("  mUserLru: [");
12117            for (int i=0; i<mUserLru.size(); i++) {
12118                if (i > 0) pw.print(", ");
12119                pw.print(mUserLru.get(i));
12120            }
12121            pw.println("]");
12122            if (dumpAll) {
12123                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12124            }
12125            synchronized (mUserProfileGroupIdsSelfLocked) {
12126                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12127                    pw.println("  mUserProfileGroupIds:");
12128                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12129                        pw.print("    User #");
12130                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12131                        pw.print(" -> profile #");
12132                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12133                    }
12134                }
12135            }
12136        }
12137        if (mHomeProcess != null && (dumpPackage == null
12138                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12139            if (needSep) {
12140                pw.println();
12141                needSep = false;
12142            }
12143            pw.println("  mHomeProcess: " + mHomeProcess);
12144        }
12145        if (mPreviousProcess != null && (dumpPackage == null
12146                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12147            if (needSep) {
12148                pw.println();
12149                needSep = false;
12150            }
12151            pw.println("  mPreviousProcess: " + mPreviousProcess);
12152        }
12153        if (dumpAll) {
12154            StringBuilder sb = new StringBuilder(128);
12155            sb.append("  mPreviousProcessVisibleTime: ");
12156            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12157            pw.println(sb);
12158        }
12159        if (mHeavyWeightProcess != null && (dumpPackage == null
12160                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12161            if (needSep) {
12162                pw.println();
12163                needSep = false;
12164            }
12165            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12166        }
12167        if (dumpPackage == null) {
12168            pw.println("  mConfiguration: " + mConfiguration);
12169        }
12170        if (dumpAll) {
12171            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12172            if (mCompatModePackages.getPackages().size() > 0) {
12173                boolean printed = false;
12174                for (Map.Entry<String, Integer> entry
12175                        : mCompatModePackages.getPackages().entrySet()) {
12176                    String pkg = entry.getKey();
12177                    int mode = entry.getValue();
12178                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12179                        continue;
12180                    }
12181                    if (!printed) {
12182                        pw.println("  mScreenCompatPackages:");
12183                        printed = true;
12184                    }
12185                    pw.print("    "); pw.print(pkg); pw.print(": ");
12186                            pw.print(mode); pw.println();
12187                }
12188            }
12189        }
12190        if (dumpPackage == null) {
12191            if (mSleeping || mWentToSleep || mLockScreenShown) {
12192                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12193                        + " mLockScreenShown " + mLockScreenShown);
12194            }
12195            if (mShuttingDown || mRunningVoice) {
12196                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12197            }
12198        }
12199        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12200                || mOrigWaitForDebugger) {
12201            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12202                    || dumpPackage.equals(mOrigDebugApp)) {
12203                if (needSep) {
12204                    pw.println();
12205                    needSep = false;
12206                }
12207                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12208                        + " mDebugTransient=" + mDebugTransient
12209                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12210            }
12211        }
12212        if (mOpenGlTraceApp != null) {
12213            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12214                if (needSep) {
12215                    pw.println();
12216                    needSep = false;
12217                }
12218                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12219            }
12220        }
12221        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12222                || mProfileFd != null) {
12223            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12224                if (needSep) {
12225                    pw.println();
12226                    needSep = false;
12227                }
12228                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12229                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12230                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12231                        + mAutoStopProfiler);
12232            }
12233        }
12234        if (dumpPackage == null) {
12235            if (mAlwaysFinishActivities || mController != null) {
12236                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12237                        + " mController=" + mController);
12238            }
12239            if (dumpAll) {
12240                pw.println("  Total persistent processes: " + numPers);
12241                pw.println("  mProcessesReady=" + mProcessesReady
12242                        + " mSystemReady=" + mSystemReady);
12243                pw.println("  mBooting=" + mBooting
12244                        + " mBooted=" + mBooted
12245                        + " mFactoryTest=" + mFactoryTest);
12246                pw.print("  mLastPowerCheckRealtime=");
12247                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12248                        pw.println("");
12249                pw.print("  mLastPowerCheckUptime=");
12250                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12251                        pw.println("");
12252                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12253                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12254                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12255                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12256                        + " (" + mLruProcesses.size() + " total)"
12257                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12258                        + " mNumServiceProcs=" + mNumServiceProcs
12259                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12260                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12261                        + " mLastMemoryLevel" + mLastMemoryLevel
12262                        + " mLastNumProcesses" + mLastNumProcesses);
12263                long now = SystemClock.uptimeMillis();
12264                pw.print("  mLastIdleTime=");
12265                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12266                        pw.print(" mLowRamSinceLastIdle=");
12267                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12268                        pw.println();
12269            }
12270        }
12271
12272        if (!printedAnything) {
12273            pw.println("  (nothing)");
12274        }
12275    }
12276
12277    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12278            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12279        if (mProcessesToGc.size() > 0) {
12280            boolean printed = false;
12281            long now = SystemClock.uptimeMillis();
12282            for (int i=0; i<mProcessesToGc.size(); i++) {
12283                ProcessRecord proc = mProcessesToGc.get(i);
12284                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12285                    continue;
12286                }
12287                if (!printed) {
12288                    if (needSep) pw.println();
12289                    needSep = true;
12290                    pw.println("  Processes that are waiting to GC:");
12291                    printed = true;
12292                }
12293                pw.print("    Process "); pw.println(proc);
12294                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12295                        pw.print(", last gced=");
12296                        pw.print(now-proc.lastRequestedGc);
12297                        pw.print(" ms ago, last lowMem=");
12298                        pw.print(now-proc.lastLowMemory);
12299                        pw.println(" ms ago");
12300
12301            }
12302        }
12303        return needSep;
12304    }
12305
12306    void printOomLevel(PrintWriter pw, String name, int adj) {
12307        pw.print("    ");
12308        if (adj >= 0) {
12309            pw.print(' ');
12310            if (adj < 10) pw.print(' ');
12311        } else {
12312            if (adj > -10) pw.print(' ');
12313        }
12314        pw.print(adj);
12315        pw.print(": ");
12316        pw.print(name);
12317        pw.print(" (");
12318        pw.print(mProcessList.getMemLevel(adj)/1024);
12319        pw.println(" kB)");
12320    }
12321
12322    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12323            int opti, boolean dumpAll) {
12324        boolean needSep = false;
12325
12326        if (mLruProcesses.size() > 0) {
12327            if (needSep) pw.println();
12328            needSep = true;
12329            pw.println("  OOM levels:");
12330            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12331            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12332            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12333            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12334            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12335            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12336            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12337            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12338            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12339            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12340            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12341            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12342            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12343
12344            if (needSep) pw.println();
12345            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12346                    pw.print(" total, non-act at ");
12347                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12348                    pw.print(", non-svc at ");
12349                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12350                    pw.println("):");
12351            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12352            needSep = true;
12353        }
12354
12355        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12356
12357        pw.println();
12358        pw.println("  mHomeProcess: " + mHomeProcess);
12359        pw.println("  mPreviousProcess: " + mPreviousProcess);
12360        if (mHeavyWeightProcess != null) {
12361            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12362        }
12363
12364        return true;
12365    }
12366
12367    /**
12368     * There are three ways to call this:
12369     *  - no provider specified: dump all the providers
12370     *  - a flattened component name that matched an existing provider was specified as the
12371     *    first arg: dump that one provider
12372     *  - the first arg isn't the flattened component name of an existing provider:
12373     *    dump all providers whose component contains the first arg as a substring
12374     */
12375    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12376            int opti, boolean dumpAll) {
12377        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12378    }
12379
12380    static class ItemMatcher {
12381        ArrayList<ComponentName> components;
12382        ArrayList<String> strings;
12383        ArrayList<Integer> objects;
12384        boolean all;
12385
12386        ItemMatcher() {
12387            all = true;
12388        }
12389
12390        void build(String name) {
12391            ComponentName componentName = ComponentName.unflattenFromString(name);
12392            if (componentName != null) {
12393                if (components == null) {
12394                    components = new ArrayList<ComponentName>();
12395                }
12396                components.add(componentName);
12397                all = false;
12398            } else {
12399                int objectId = 0;
12400                // Not a '/' separated full component name; maybe an object ID?
12401                try {
12402                    objectId = Integer.parseInt(name, 16);
12403                    if (objects == null) {
12404                        objects = new ArrayList<Integer>();
12405                    }
12406                    objects.add(objectId);
12407                    all = false;
12408                } catch (RuntimeException e) {
12409                    // Not an integer; just do string match.
12410                    if (strings == null) {
12411                        strings = new ArrayList<String>();
12412                    }
12413                    strings.add(name);
12414                    all = false;
12415                }
12416            }
12417        }
12418
12419        int build(String[] args, int opti) {
12420            for (; opti<args.length; opti++) {
12421                String name = args[opti];
12422                if ("--".equals(name)) {
12423                    return opti+1;
12424                }
12425                build(name);
12426            }
12427            return opti;
12428        }
12429
12430        boolean match(Object object, ComponentName comp) {
12431            if (all) {
12432                return true;
12433            }
12434            if (components != null) {
12435                for (int i=0; i<components.size(); i++) {
12436                    if (components.get(i).equals(comp)) {
12437                        return true;
12438                    }
12439                }
12440            }
12441            if (objects != null) {
12442                for (int i=0; i<objects.size(); i++) {
12443                    if (System.identityHashCode(object) == objects.get(i)) {
12444                        return true;
12445                    }
12446                }
12447            }
12448            if (strings != null) {
12449                String flat = comp.flattenToString();
12450                for (int i=0; i<strings.size(); i++) {
12451                    if (flat.contains(strings.get(i))) {
12452                        return true;
12453                    }
12454                }
12455            }
12456            return false;
12457        }
12458    }
12459
12460    /**
12461     * There are three things that cmd can be:
12462     *  - a flattened component name that matches an existing activity
12463     *  - the cmd arg isn't the flattened component name of an existing activity:
12464     *    dump all activity whose component contains the cmd as a substring
12465     *  - A hex number of the ActivityRecord object instance.
12466     */
12467    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12468            int opti, boolean dumpAll) {
12469        ArrayList<ActivityRecord> activities;
12470
12471        synchronized (this) {
12472            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12473        }
12474
12475        if (activities.size() <= 0) {
12476            return false;
12477        }
12478
12479        String[] newArgs = new String[args.length - opti];
12480        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12481
12482        TaskRecord lastTask = null;
12483        boolean needSep = false;
12484        for (int i=activities.size()-1; i>=0; i--) {
12485            ActivityRecord r = activities.get(i);
12486            if (needSep) {
12487                pw.println();
12488            }
12489            needSep = true;
12490            synchronized (this) {
12491                if (lastTask != r.task) {
12492                    lastTask = r.task;
12493                    pw.print("TASK "); pw.print(lastTask.affinity);
12494                            pw.print(" id="); pw.println(lastTask.taskId);
12495                    if (dumpAll) {
12496                        lastTask.dump(pw, "  ");
12497                    }
12498                }
12499            }
12500            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12501        }
12502        return true;
12503    }
12504
12505    /**
12506     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12507     * there is a thread associated with the activity.
12508     */
12509    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12510            final ActivityRecord r, String[] args, boolean dumpAll) {
12511        String innerPrefix = prefix + "  ";
12512        synchronized (this) {
12513            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12514                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12515                    pw.print(" pid=");
12516                    if (r.app != null) pw.println(r.app.pid);
12517                    else pw.println("(not running)");
12518            if (dumpAll) {
12519                r.dump(pw, innerPrefix);
12520            }
12521        }
12522        if (r.app != null && r.app.thread != null) {
12523            // flush anything that is already in the PrintWriter since the thread is going
12524            // to write to the file descriptor directly
12525            pw.flush();
12526            try {
12527                TransferPipe tp = new TransferPipe();
12528                try {
12529                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12530                            r.appToken, innerPrefix, args);
12531                    tp.go(fd);
12532                } finally {
12533                    tp.kill();
12534                }
12535            } catch (IOException e) {
12536                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12537            } catch (RemoteException e) {
12538                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12539            }
12540        }
12541    }
12542
12543    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12544            int opti, boolean dumpAll, String dumpPackage) {
12545        boolean needSep = false;
12546        boolean onlyHistory = false;
12547        boolean printedAnything = false;
12548
12549        if ("history".equals(dumpPackage)) {
12550            if (opti < args.length && "-s".equals(args[opti])) {
12551                dumpAll = false;
12552            }
12553            onlyHistory = true;
12554            dumpPackage = null;
12555        }
12556
12557        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12558        if (!onlyHistory && dumpAll) {
12559            if (mRegisteredReceivers.size() > 0) {
12560                boolean printed = false;
12561                Iterator it = mRegisteredReceivers.values().iterator();
12562                while (it.hasNext()) {
12563                    ReceiverList r = (ReceiverList)it.next();
12564                    if (dumpPackage != null && (r.app == null ||
12565                            !dumpPackage.equals(r.app.info.packageName))) {
12566                        continue;
12567                    }
12568                    if (!printed) {
12569                        pw.println("  Registered Receivers:");
12570                        needSep = true;
12571                        printed = true;
12572                        printedAnything = true;
12573                    }
12574                    pw.print("  * "); pw.println(r);
12575                    r.dump(pw, "    ");
12576                }
12577            }
12578
12579            if (mReceiverResolver.dump(pw, needSep ?
12580                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12581                    "    ", dumpPackage, false)) {
12582                needSep = true;
12583                printedAnything = true;
12584            }
12585        }
12586
12587        for (BroadcastQueue q : mBroadcastQueues) {
12588            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12589            printedAnything |= needSep;
12590        }
12591
12592        needSep = true;
12593
12594        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12595            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12596                if (needSep) {
12597                    pw.println();
12598                }
12599                needSep = true;
12600                printedAnything = true;
12601                pw.print("  Sticky broadcasts for user ");
12602                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12603                StringBuilder sb = new StringBuilder(128);
12604                for (Map.Entry<String, ArrayList<Intent>> ent
12605                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12606                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12607                    if (dumpAll) {
12608                        pw.println(":");
12609                        ArrayList<Intent> intents = ent.getValue();
12610                        final int N = intents.size();
12611                        for (int i=0; i<N; i++) {
12612                            sb.setLength(0);
12613                            sb.append("    Intent: ");
12614                            intents.get(i).toShortString(sb, false, true, false, false);
12615                            pw.println(sb.toString());
12616                            Bundle bundle = intents.get(i).getExtras();
12617                            if (bundle != null) {
12618                                pw.print("      ");
12619                                pw.println(bundle.toString());
12620                            }
12621                        }
12622                    } else {
12623                        pw.println("");
12624                    }
12625                }
12626            }
12627        }
12628
12629        if (!onlyHistory && dumpAll) {
12630            pw.println();
12631            for (BroadcastQueue queue : mBroadcastQueues) {
12632                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12633                        + queue.mBroadcastsScheduled);
12634            }
12635            pw.println("  mHandler:");
12636            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12637            needSep = true;
12638            printedAnything = true;
12639        }
12640
12641        if (!printedAnything) {
12642            pw.println("  (nothing)");
12643        }
12644    }
12645
12646    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12647            int opti, boolean dumpAll, String dumpPackage) {
12648        boolean needSep;
12649        boolean printedAnything = false;
12650
12651        ItemMatcher matcher = new ItemMatcher();
12652        matcher.build(args, opti);
12653
12654        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12655
12656        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12657        printedAnything |= needSep;
12658
12659        if (mLaunchingProviders.size() > 0) {
12660            boolean printed = false;
12661            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12662                ContentProviderRecord r = mLaunchingProviders.get(i);
12663                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12664                    continue;
12665                }
12666                if (!printed) {
12667                    if (needSep) pw.println();
12668                    needSep = true;
12669                    pw.println("  Launching content providers:");
12670                    printed = true;
12671                    printedAnything = true;
12672                }
12673                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12674                        pw.println(r);
12675            }
12676        }
12677
12678        if (mGrantedUriPermissions.size() > 0) {
12679            boolean printed = false;
12680            int dumpUid = -2;
12681            if (dumpPackage != null) {
12682                try {
12683                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12684                } catch (NameNotFoundException e) {
12685                    dumpUid = -1;
12686                }
12687            }
12688            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12689                int uid = mGrantedUriPermissions.keyAt(i);
12690                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12691                    continue;
12692                }
12693                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12694                if (!printed) {
12695                    if (needSep) pw.println();
12696                    needSep = true;
12697                    pw.println("  Granted Uri Permissions:");
12698                    printed = true;
12699                    printedAnything = true;
12700                }
12701                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12702                for (UriPermission perm : perms.values()) {
12703                    pw.print("    "); pw.println(perm);
12704                    if (dumpAll) {
12705                        perm.dump(pw, "      ");
12706                    }
12707                }
12708            }
12709        }
12710
12711        if (!printedAnything) {
12712            pw.println("  (nothing)");
12713        }
12714    }
12715
12716    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12717            int opti, boolean dumpAll, String dumpPackage) {
12718        boolean printed = false;
12719
12720        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12721
12722        if (mIntentSenderRecords.size() > 0) {
12723            Iterator<WeakReference<PendingIntentRecord>> it
12724                    = mIntentSenderRecords.values().iterator();
12725            while (it.hasNext()) {
12726                WeakReference<PendingIntentRecord> ref = it.next();
12727                PendingIntentRecord rec = ref != null ? ref.get(): null;
12728                if (dumpPackage != null && (rec == null
12729                        || !dumpPackage.equals(rec.key.packageName))) {
12730                    continue;
12731                }
12732                printed = true;
12733                if (rec != null) {
12734                    pw.print("  * "); pw.println(rec);
12735                    if (dumpAll) {
12736                        rec.dump(pw, "    ");
12737                    }
12738                } else {
12739                    pw.print("  * "); pw.println(ref);
12740                }
12741            }
12742        }
12743
12744        if (!printed) {
12745            pw.println("  (nothing)");
12746        }
12747    }
12748
12749    private static final int dumpProcessList(PrintWriter pw,
12750            ActivityManagerService service, List list,
12751            String prefix, String normalLabel, String persistentLabel,
12752            String dumpPackage) {
12753        int numPers = 0;
12754        final int N = list.size()-1;
12755        for (int i=N; i>=0; i--) {
12756            ProcessRecord r = (ProcessRecord)list.get(i);
12757            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12758                continue;
12759            }
12760            pw.println(String.format("%s%s #%2d: %s",
12761                    prefix, (r.persistent ? persistentLabel : normalLabel),
12762                    i, r.toString()));
12763            if (r.persistent) {
12764                numPers++;
12765            }
12766        }
12767        return numPers;
12768    }
12769
12770    private static final boolean dumpProcessOomList(PrintWriter pw,
12771            ActivityManagerService service, List<ProcessRecord> origList,
12772            String prefix, String normalLabel, String persistentLabel,
12773            boolean inclDetails, String dumpPackage) {
12774
12775        ArrayList<Pair<ProcessRecord, Integer>> list
12776                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12777        for (int i=0; i<origList.size(); i++) {
12778            ProcessRecord r = origList.get(i);
12779            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12780                continue;
12781            }
12782            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12783        }
12784
12785        if (list.size() <= 0) {
12786            return false;
12787        }
12788
12789        Comparator<Pair<ProcessRecord, Integer>> comparator
12790                = new Comparator<Pair<ProcessRecord, Integer>>() {
12791            @Override
12792            public int compare(Pair<ProcessRecord, Integer> object1,
12793                    Pair<ProcessRecord, Integer> object2) {
12794                if (object1.first.setAdj != object2.first.setAdj) {
12795                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12796                }
12797                if (object1.second.intValue() != object2.second.intValue()) {
12798                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12799                }
12800                return 0;
12801            }
12802        };
12803
12804        Collections.sort(list, comparator);
12805
12806        final long curRealtime = SystemClock.elapsedRealtime();
12807        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12808        final long curUptime = SystemClock.uptimeMillis();
12809        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12810
12811        for (int i=list.size()-1; i>=0; i--) {
12812            ProcessRecord r = list.get(i).first;
12813            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12814            char schedGroup;
12815            switch (r.setSchedGroup) {
12816                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12817                    schedGroup = 'B';
12818                    break;
12819                case Process.THREAD_GROUP_DEFAULT:
12820                    schedGroup = 'F';
12821                    break;
12822                default:
12823                    schedGroup = '?';
12824                    break;
12825            }
12826            char foreground;
12827            if (r.foregroundActivities) {
12828                foreground = 'A';
12829            } else if (r.foregroundServices) {
12830                foreground = 'S';
12831            } else {
12832                foreground = ' ';
12833            }
12834            String procState = ProcessList.makeProcStateString(r.curProcState);
12835            pw.print(prefix);
12836            pw.print(r.persistent ? persistentLabel : normalLabel);
12837            pw.print(" #");
12838            int num = (origList.size()-1)-list.get(i).second;
12839            if (num < 10) pw.print(' ');
12840            pw.print(num);
12841            pw.print(": ");
12842            pw.print(oomAdj);
12843            pw.print(' ');
12844            pw.print(schedGroup);
12845            pw.print('/');
12846            pw.print(foreground);
12847            pw.print('/');
12848            pw.print(procState);
12849            pw.print(" trm:");
12850            if (r.trimMemoryLevel < 10) pw.print(' ');
12851            pw.print(r.trimMemoryLevel);
12852            pw.print(' ');
12853            pw.print(r.toShortString());
12854            pw.print(" (");
12855            pw.print(r.adjType);
12856            pw.println(')');
12857            if (r.adjSource != null || r.adjTarget != null) {
12858                pw.print(prefix);
12859                pw.print("    ");
12860                if (r.adjTarget instanceof ComponentName) {
12861                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12862                } else if (r.adjTarget != null) {
12863                    pw.print(r.adjTarget.toString());
12864                } else {
12865                    pw.print("{null}");
12866                }
12867                pw.print("<=");
12868                if (r.adjSource instanceof ProcessRecord) {
12869                    pw.print("Proc{");
12870                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12871                    pw.println("}");
12872                } else if (r.adjSource != null) {
12873                    pw.println(r.adjSource.toString());
12874                } else {
12875                    pw.println("{null}");
12876                }
12877            }
12878            if (inclDetails) {
12879                pw.print(prefix);
12880                pw.print("    ");
12881                pw.print("oom: max="); pw.print(r.maxAdj);
12882                pw.print(" curRaw="); pw.print(r.curRawAdj);
12883                pw.print(" setRaw="); pw.print(r.setRawAdj);
12884                pw.print(" cur="); pw.print(r.curAdj);
12885                pw.print(" set="); pw.println(r.setAdj);
12886                pw.print(prefix);
12887                pw.print("    ");
12888                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12889                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12890                pw.print(" lastPss="); pw.print(r.lastPss);
12891                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12892                pw.print(prefix);
12893                pw.print("    ");
12894                pw.print("cached="); pw.print(r.cached);
12895                pw.print(" empty="); pw.print(r.empty);
12896                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12897
12898                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12899                    if (r.lastWakeTime != 0) {
12900                        long wtime;
12901                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12902                        synchronized (stats) {
12903                            wtime = stats.getProcessWakeTime(r.info.uid,
12904                                    r.pid, curRealtime);
12905                        }
12906                        long timeUsed = wtime - r.lastWakeTime;
12907                        pw.print(prefix);
12908                        pw.print("    ");
12909                        pw.print("keep awake over ");
12910                        TimeUtils.formatDuration(realtimeSince, pw);
12911                        pw.print(" used ");
12912                        TimeUtils.formatDuration(timeUsed, pw);
12913                        pw.print(" (");
12914                        pw.print((timeUsed*100)/realtimeSince);
12915                        pw.println("%)");
12916                    }
12917                    if (r.lastCpuTime != 0) {
12918                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12919                        pw.print(prefix);
12920                        pw.print("    ");
12921                        pw.print("run cpu over ");
12922                        TimeUtils.formatDuration(uptimeSince, pw);
12923                        pw.print(" used ");
12924                        TimeUtils.formatDuration(timeUsed, pw);
12925                        pw.print(" (");
12926                        pw.print((timeUsed*100)/uptimeSince);
12927                        pw.println("%)");
12928                    }
12929                }
12930            }
12931        }
12932        return true;
12933    }
12934
12935    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12936        ArrayList<ProcessRecord> procs;
12937        synchronized (this) {
12938            if (args != null && args.length > start
12939                    && args[start].charAt(0) != '-') {
12940                procs = new ArrayList<ProcessRecord>();
12941                int pid = -1;
12942                try {
12943                    pid = Integer.parseInt(args[start]);
12944                } catch (NumberFormatException e) {
12945                }
12946                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12947                    ProcessRecord proc = mLruProcesses.get(i);
12948                    if (proc.pid == pid) {
12949                        procs.add(proc);
12950                    } else if (proc.processName.equals(args[start])) {
12951                        procs.add(proc);
12952                    }
12953                }
12954                if (procs.size() <= 0) {
12955                    return null;
12956                }
12957            } else {
12958                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12959            }
12960        }
12961        return procs;
12962    }
12963
12964    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12965            PrintWriter pw, String[] args) {
12966        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12967        if (procs == null) {
12968            pw.println("No process found for: " + args[0]);
12969            return;
12970        }
12971
12972        long uptime = SystemClock.uptimeMillis();
12973        long realtime = SystemClock.elapsedRealtime();
12974        pw.println("Applications Graphics Acceleration Info:");
12975        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12976
12977        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12978            ProcessRecord r = procs.get(i);
12979            if (r.thread != null) {
12980                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12981                pw.flush();
12982                try {
12983                    TransferPipe tp = new TransferPipe();
12984                    try {
12985                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12986                        tp.go(fd);
12987                    } finally {
12988                        tp.kill();
12989                    }
12990                } catch (IOException e) {
12991                    pw.println("Failure while dumping the app: " + r);
12992                    pw.flush();
12993                } catch (RemoteException e) {
12994                    pw.println("Got a RemoteException while dumping the app " + r);
12995                    pw.flush();
12996                }
12997            }
12998        }
12999    }
13000
13001    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13002        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13003        if (procs == null) {
13004            pw.println("No process found for: " + args[0]);
13005            return;
13006        }
13007
13008        pw.println("Applications Database Info:");
13009
13010        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13011            ProcessRecord r = procs.get(i);
13012            if (r.thread != null) {
13013                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13014                pw.flush();
13015                try {
13016                    TransferPipe tp = new TransferPipe();
13017                    try {
13018                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13019                        tp.go(fd);
13020                    } finally {
13021                        tp.kill();
13022                    }
13023                } catch (IOException e) {
13024                    pw.println("Failure while dumping the app: " + r);
13025                    pw.flush();
13026                } catch (RemoteException e) {
13027                    pw.println("Got a RemoteException while dumping the app " + r);
13028                    pw.flush();
13029                }
13030            }
13031        }
13032    }
13033
13034    final static class MemItem {
13035        final boolean isProc;
13036        final String label;
13037        final String shortLabel;
13038        final long pss;
13039        final int id;
13040        final boolean hasActivities;
13041        ArrayList<MemItem> subitems;
13042
13043        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13044                boolean _hasActivities) {
13045            isProc = true;
13046            label = _label;
13047            shortLabel = _shortLabel;
13048            pss = _pss;
13049            id = _id;
13050            hasActivities = _hasActivities;
13051        }
13052
13053        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13054            isProc = false;
13055            label = _label;
13056            shortLabel = _shortLabel;
13057            pss = _pss;
13058            id = _id;
13059            hasActivities = false;
13060        }
13061    }
13062
13063    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13064            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13065        if (sort && !isCompact) {
13066            Collections.sort(items, new Comparator<MemItem>() {
13067                @Override
13068                public int compare(MemItem lhs, MemItem rhs) {
13069                    if (lhs.pss < rhs.pss) {
13070                        return 1;
13071                    } else if (lhs.pss > rhs.pss) {
13072                        return -1;
13073                    }
13074                    return 0;
13075                }
13076            });
13077        }
13078
13079        for (int i=0; i<items.size(); i++) {
13080            MemItem mi = items.get(i);
13081            if (!isCompact) {
13082                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13083            } else if (mi.isProc) {
13084                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13085                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13086                pw.println(mi.hasActivities ? ",a" : ",e");
13087            } else {
13088                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13089                pw.println(mi.pss);
13090            }
13091            if (mi.subitems != null) {
13092                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13093                        true, isCompact);
13094            }
13095        }
13096    }
13097
13098    // These are in KB.
13099    static final long[] DUMP_MEM_BUCKETS = new long[] {
13100        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13101        120*1024, 160*1024, 200*1024,
13102        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13103        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13104    };
13105
13106    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13107            boolean stackLike) {
13108        int start = label.lastIndexOf('.');
13109        if (start >= 0) start++;
13110        else start = 0;
13111        int end = label.length();
13112        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13113            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13114                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13115                out.append(bucket);
13116                out.append(stackLike ? "MB." : "MB ");
13117                out.append(label, start, end);
13118                return;
13119            }
13120        }
13121        out.append(memKB/1024);
13122        out.append(stackLike ? "MB." : "MB ");
13123        out.append(label, start, end);
13124    }
13125
13126    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13127            ProcessList.NATIVE_ADJ,
13128            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13129            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13130            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13131            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13132            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13133    };
13134    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13135            "Native",
13136            "System", "Persistent", "Foreground",
13137            "Visible", "Perceptible",
13138            "Heavy Weight", "Backup",
13139            "A Services", "Home",
13140            "Previous", "B Services", "Cached"
13141    };
13142    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13143            "native",
13144            "sys", "pers", "fore",
13145            "vis", "percept",
13146            "heavy", "backup",
13147            "servicea", "home",
13148            "prev", "serviceb", "cached"
13149    };
13150
13151    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13152            long realtime, boolean isCheckinRequest, boolean isCompact) {
13153        if (isCheckinRequest || isCompact) {
13154            // short checkin version
13155            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13156        } else {
13157            pw.println("Applications Memory Usage (kB):");
13158            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13159        }
13160    }
13161
13162    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13163            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13164        boolean dumpDetails = false;
13165        boolean dumpFullDetails = false;
13166        boolean dumpDalvik = false;
13167        boolean oomOnly = false;
13168        boolean isCompact = false;
13169        boolean localOnly = false;
13170
13171        int opti = 0;
13172        while (opti < args.length) {
13173            String opt = args[opti];
13174            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13175                break;
13176            }
13177            opti++;
13178            if ("-a".equals(opt)) {
13179                dumpDetails = true;
13180                dumpFullDetails = true;
13181                dumpDalvik = true;
13182            } else if ("-d".equals(opt)) {
13183                dumpDalvik = true;
13184            } else if ("-c".equals(opt)) {
13185                isCompact = true;
13186            } else if ("--oom".equals(opt)) {
13187                oomOnly = true;
13188            } else if ("--local".equals(opt)) {
13189                localOnly = true;
13190            } else if ("-h".equals(opt)) {
13191                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13192                pw.println("  -a: include all available information for each process.");
13193                pw.println("  -d: include dalvik details when dumping process details.");
13194                pw.println("  -c: dump in a compact machine-parseable representation.");
13195                pw.println("  --oom: only show processes organized by oom adj.");
13196                pw.println("  --local: only collect details locally, don't call process.");
13197                pw.println("If [process] is specified it can be the name or ");
13198                pw.println("pid of a specific process to dump.");
13199                return;
13200            } else {
13201                pw.println("Unknown argument: " + opt + "; use -h for help");
13202            }
13203        }
13204
13205        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13206        long uptime = SystemClock.uptimeMillis();
13207        long realtime = SystemClock.elapsedRealtime();
13208        final long[] tmpLong = new long[1];
13209
13210        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13211        if (procs == null) {
13212            // No Java processes.  Maybe they want to print a native process.
13213            if (args != null && args.length > opti
13214                    && args[opti].charAt(0) != '-') {
13215                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13216                        = new ArrayList<ProcessCpuTracker.Stats>();
13217                updateCpuStatsNow();
13218                int findPid = -1;
13219                try {
13220                    findPid = Integer.parseInt(args[opti]);
13221                } catch (NumberFormatException e) {
13222                }
13223                synchronized (mProcessCpuThread) {
13224                    final int N = mProcessCpuTracker.countStats();
13225                    for (int i=0; i<N; i++) {
13226                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13227                        if (st.pid == findPid || (st.baseName != null
13228                                && st.baseName.equals(args[opti]))) {
13229                            nativeProcs.add(st);
13230                        }
13231                    }
13232                }
13233                if (nativeProcs.size() > 0) {
13234                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13235                            isCompact);
13236                    Debug.MemoryInfo mi = null;
13237                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13238                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13239                        final int pid = r.pid;
13240                        if (!isCheckinRequest && dumpDetails) {
13241                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13242                        }
13243                        if (mi == null) {
13244                            mi = new Debug.MemoryInfo();
13245                        }
13246                        if (dumpDetails || (!brief && !oomOnly)) {
13247                            Debug.getMemoryInfo(pid, mi);
13248                        } else {
13249                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13250                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13251                        }
13252                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13253                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13254                        if (isCheckinRequest) {
13255                            pw.println();
13256                        }
13257                    }
13258                    return;
13259                }
13260            }
13261            pw.println("No process found for: " + args[opti]);
13262            return;
13263        }
13264
13265        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13266            dumpDetails = true;
13267        }
13268
13269        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13270
13271        String[] innerArgs = new String[args.length-opti];
13272        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13273
13274        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13275        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13276        long nativePss=0, dalvikPss=0, otherPss=0;
13277        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13278
13279        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13280        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13281                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13282
13283        long totalPss = 0;
13284        long cachedPss = 0;
13285
13286        Debug.MemoryInfo mi = null;
13287        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13288            final ProcessRecord r = procs.get(i);
13289            final IApplicationThread thread;
13290            final int pid;
13291            final int oomAdj;
13292            final boolean hasActivities;
13293            synchronized (this) {
13294                thread = r.thread;
13295                pid = r.pid;
13296                oomAdj = r.getSetAdjWithServices();
13297                hasActivities = r.activities.size() > 0;
13298            }
13299            if (thread != null) {
13300                if (!isCheckinRequest && dumpDetails) {
13301                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13302                }
13303                if (mi == null) {
13304                    mi = new Debug.MemoryInfo();
13305                }
13306                if (dumpDetails || (!brief && !oomOnly)) {
13307                    Debug.getMemoryInfo(pid, mi);
13308                } else {
13309                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13310                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13311                }
13312                if (dumpDetails) {
13313                    if (localOnly) {
13314                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13315                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13316                        if (isCheckinRequest) {
13317                            pw.println();
13318                        }
13319                    } else {
13320                        try {
13321                            pw.flush();
13322                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13323                                    dumpDalvik, innerArgs);
13324                        } catch (RemoteException e) {
13325                            if (!isCheckinRequest) {
13326                                pw.println("Got RemoteException!");
13327                                pw.flush();
13328                            }
13329                        }
13330                    }
13331                }
13332
13333                final long myTotalPss = mi.getTotalPss();
13334                final long myTotalUss = mi.getTotalUss();
13335
13336                synchronized (this) {
13337                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13338                        // Record this for posterity if the process has been stable.
13339                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13340                    }
13341                }
13342
13343                if (!isCheckinRequest && mi != null) {
13344                    totalPss += myTotalPss;
13345                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13346                            (hasActivities ? " / activities)" : ")"),
13347                            r.processName, myTotalPss, pid, hasActivities);
13348                    procMems.add(pssItem);
13349                    procMemsMap.put(pid, pssItem);
13350
13351                    nativePss += mi.nativePss;
13352                    dalvikPss += mi.dalvikPss;
13353                    otherPss += mi.otherPss;
13354                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13355                        long mem = mi.getOtherPss(j);
13356                        miscPss[j] += mem;
13357                        otherPss -= mem;
13358                    }
13359
13360                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13361                        cachedPss += myTotalPss;
13362                    }
13363
13364                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13365                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13366                                || oomIndex == (oomPss.length-1)) {
13367                            oomPss[oomIndex] += myTotalPss;
13368                            if (oomProcs[oomIndex] == null) {
13369                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13370                            }
13371                            oomProcs[oomIndex].add(pssItem);
13372                            break;
13373                        }
13374                    }
13375                }
13376            }
13377        }
13378
13379        long nativeProcTotalPss = 0;
13380
13381        if (!isCheckinRequest && procs.size() > 1) {
13382            // If we are showing aggregations, also look for native processes to
13383            // include so that our aggregations are more accurate.
13384            updateCpuStatsNow();
13385            synchronized (mProcessCpuThread) {
13386                final int N = mProcessCpuTracker.countStats();
13387                for (int i=0; i<N; i++) {
13388                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13389                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13390                        if (mi == null) {
13391                            mi = new Debug.MemoryInfo();
13392                        }
13393                        if (!brief && !oomOnly) {
13394                            Debug.getMemoryInfo(st.pid, mi);
13395                        } else {
13396                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13397                            mi.nativePrivateDirty = (int)tmpLong[0];
13398                        }
13399
13400                        final long myTotalPss = mi.getTotalPss();
13401                        totalPss += myTotalPss;
13402                        nativeProcTotalPss += myTotalPss;
13403
13404                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13405                                st.name, myTotalPss, st.pid, false);
13406                        procMems.add(pssItem);
13407
13408                        nativePss += mi.nativePss;
13409                        dalvikPss += mi.dalvikPss;
13410                        otherPss += mi.otherPss;
13411                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13412                            long mem = mi.getOtherPss(j);
13413                            miscPss[j] += mem;
13414                            otherPss -= mem;
13415                        }
13416                        oomPss[0] += myTotalPss;
13417                        if (oomProcs[0] == null) {
13418                            oomProcs[0] = new ArrayList<MemItem>();
13419                        }
13420                        oomProcs[0].add(pssItem);
13421                    }
13422                }
13423            }
13424
13425            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13426
13427            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13428            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13429            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13430            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13431                String label = Debug.MemoryInfo.getOtherLabel(j);
13432                catMems.add(new MemItem(label, label, miscPss[j], j));
13433            }
13434
13435            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13436            for (int j=0; j<oomPss.length; j++) {
13437                if (oomPss[j] != 0) {
13438                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13439                            : DUMP_MEM_OOM_LABEL[j];
13440                    MemItem item = new MemItem(label, label, oomPss[j],
13441                            DUMP_MEM_OOM_ADJ[j]);
13442                    item.subitems = oomProcs[j];
13443                    oomMems.add(item);
13444                }
13445            }
13446
13447            if (!brief && !oomOnly && !isCompact) {
13448                pw.println();
13449                pw.println("Total PSS by process:");
13450                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13451                pw.println();
13452            }
13453            if (!isCompact) {
13454                pw.println("Total PSS by OOM adjustment:");
13455            }
13456            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13457            if (!brief && !oomOnly) {
13458                PrintWriter out = categoryPw != null ? categoryPw : pw;
13459                if (!isCompact) {
13460                    out.println();
13461                    out.println("Total PSS by category:");
13462                }
13463                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13464            }
13465            if (!isCompact) {
13466                pw.println();
13467            }
13468            MemInfoReader memInfo = new MemInfoReader();
13469            memInfo.readMemInfo();
13470            if (nativeProcTotalPss > 0) {
13471                synchronized (this) {
13472                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13473                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13474                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13475                            nativeProcTotalPss);
13476                }
13477            }
13478            if (!brief) {
13479                if (!isCompact) {
13480                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13481                    pw.print(" kB (status ");
13482                    switch (mLastMemoryLevel) {
13483                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13484                            pw.println("normal)");
13485                            break;
13486                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13487                            pw.println("moderate)");
13488                            break;
13489                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13490                            pw.println("low)");
13491                            break;
13492                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13493                            pw.println("critical)");
13494                            break;
13495                        default:
13496                            pw.print(mLastMemoryLevel);
13497                            pw.println(")");
13498                            break;
13499                    }
13500                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13501                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13502                            pw.print(cachedPss); pw.print(" cached pss + ");
13503                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13504                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13505                } else {
13506                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13507                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13508                            + memInfo.getFreeSizeKb()); pw.print(",");
13509                    pw.println(totalPss - cachedPss);
13510                }
13511            }
13512            if (!isCompact) {
13513                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13514                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13515                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13516                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13517                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13518                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13519                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13520                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13521                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13522                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13523                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13524            }
13525            if (!brief) {
13526                if (memInfo.getZramTotalSizeKb() != 0) {
13527                    if (!isCompact) {
13528                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13529                                pw.print(" kB physical used for ");
13530                                pw.print(memInfo.getSwapTotalSizeKb()
13531                                        - memInfo.getSwapFreeSizeKb());
13532                                pw.print(" kB in swap (");
13533                                pw.print(memInfo.getSwapTotalSizeKb());
13534                                pw.println(" kB total swap)");
13535                    } else {
13536                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13537                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13538                                pw.println(memInfo.getSwapFreeSizeKb());
13539                    }
13540                }
13541                final int[] SINGLE_LONG_FORMAT = new int[] {
13542                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13543                };
13544                long[] longOut = new long[1];
13545                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13546                        SINGLE_LONG_FORMAT, null, longOut, null);
13547                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13548                longOut[0] = 0;
13549                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13550                        SINGLE_LONG_FORMAT, null, longOut, null);
13551                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13552                longOut[0] = 0;
13553                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13554                        SINGLE_LONG_FORMAT, null, longOut, null);
13555                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13556                longOut[0] = 0;
13557                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13558                        SINGLE_LONG_FORMAT, null, longOut, null);
13559                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13560                if (!isCompact) {
13561                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13562                        pw.print("      KSM: "); pw.print(sharing);
13563                                pw.print(" kB saved from shared ");
13564                                pw.print(shared); pw.println(" kB");
13565                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13566                                pw.print(voltile); pw.println(" kB volatile");
13567                    }
13568                    pw.print("   Tuning: ");
13569                    pw.print(ActivityManager.staticGetMemoryClass());
13570                    pw.print(" (large ");
13571                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13572                    pw.print("), oom ");
13573                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13574                    pw.print(" kB");
13575                    pw.print(", restore limit ");
13576                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13577                    pw.print(" kB");
13578                    if (ActivityManager.isLowRamDeviceStatic()) {
13579                        pw.print(" (low-ram)");
13580                    }
13581                    if (ActivityManager.isHighEndGfx()) {
13582                        pw.print(" (high-end-gfx)");
13583                    }
13584                    pw.println();
13585                } else {
13586                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13587                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13588                    pw.println(voltile);
13589                    pw.print("tuning,");
13590                    pw.print(ActivityManager.staticGetMemoryClass());
13591                    pw.print(',');
13592                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13593                    pw.print(',');
13594                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13595                    if (ActivityManager.isLowRamDeviceStatic()) {
13596                        pw.print(",low-ram");
13597                    }
13598                    if (ActivityManager.isHighEndGfx()) {
13599                        pw.print(",high-end-gfx");
13600                    }
13601                    pw.println();
13602                }
13603            }
13604        }
13605    }
13606
13607    /**
13608     * Searches array of arguments for the specified string
13609     * @param args array of argument strings
13610     * @param value value to search for
13611     * @return true if the value is contained in the array
13612     */
13613    private static boolean scanArgs(String[] args, String value) {
13614        if (args != null) {
13615            for (String arg : args) {
13616                if (value.equals(arg)) {
13617                    return true;
13618                }
13619            }
13620        }
13621        return false;
13622    }
13623
13624    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13625            ContentProviderRecord cpr, boolean always) {
13626        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13627
13628        if (!inLaunching || always) {
13629            synchronized (cpr) {
13630                cpr.launchingApp = null;
13631                cpr.notifyAll();
13632            }
13633            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13634            String names[] = cpr.info.authority.split(";");
13635            for (int j = 0; j < names.length; j++) {
13636                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13637            }
13638        }
13639
13640        for (int i=0; i<cpr.connections.size(); i++) {
13641            ContentProviderConnection conn = cpr.connections.get(i);
13642            if (conn.waiting) {
13643                // If this connection is waiting for the provider, then we don't
13644                // need to mess with its process unless we are always removing
13645                // or for some reason the provider is not currently launching.
13646                if (inLaunching && !always) {
13647                    continue;
13648                }
13649            }
13650            ProcessRecord capp = conn.client;
13651            conn.dead = true;
13652            if (conn.stableCount > 0) {
13653                if (!capp.persistent && capp.thread != null
13654                        && capp.pid != 0
13655                        && capp.pid != MY_PID) {
13656                    killUnneededProcessLocked(capp, "depends on provider "
13657                            + cpr.name.flattenToShortString()
13658                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13659                }
13660            } else if (capp.thread != null && conn.provider.provider != null) {
13661                try {
13662                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13663                } catch (RemoteException e) {
13664                }
13665                // In the protocol here, we don't expect the client to correctly
13666                // clean up this connection, we'll just remove it.
13667                cpr.connections.remove(i);
13668                conn.client.conProviders.remove(conn);
13669            }
13670        }
13671
13672        if (inLaunching && always) {
13673            mLaunchingProviders.remove(cpr);
13674        }
13675        return inLaunching;
13676    }
13677
13678    /**
13679     * Main code for cleaning up a process when it has gone away.  This is
13680     * called both as a result of the process dying, or directly when stopping
13681     * a process when running in single process mode.
13682     */
13683    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13684            boolean restarting, boolean allowRestart, int index) {
13685        if (index >= 0) {
13686            removeLruProcessLocked(app);
13687            ProcessList.remove(app.pid);
13688        }
13689
13690        mProcessesToGc.remove(app);
13691        mPendingPssProcesses.remove(app);
13692
13693        // Dismiss any open dialogs.
13694        if (app.crashDialog != null && !app.forceCrashReport) {
13695            app.crashDialog.dismiss();
13696            app.crashDialog = null;
13697        }
13698        if (app.anrDialog != null) {
13699            app.anrDialog.dismiss();
13700            app.anrDialog = null;
13701        }
13702        if (app.waitDialog != null) {
13703            app.waitDialog.dismiss();
13704            app.waitDialog = null;
13705        }
13706
13707        app.crashing = false;
13708        app.notResponding = false;
13709
13710        app.resetPackageList(mProcessStats);
13711        app.unlinkDeathRecipient();
13712        app.makeInactive(mProcessStats);
13713        app.waitingToKill = null;
13714        app.forcingToForeground = null;
13715        updateProcessForegroundLocked(app, false, false);
13716        app.foregroundActivities = false;
13717        app.hasShownUi = false;
13718        app.treatLikeActivity = false;
13719        app.hasAboveClient = false;
13720        app.hasClientActivities = false;
13721
13722        mServices.killServicesLocked(app, allowRestart);
13723
13724        boolean restart = false;
13725
13726        // Remove published content providers.
13727        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13728            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13729            final boolean always = app.bad || !allowRestart;
13730            if (removeDyingProviderLocked(app, cpr, always) || always) {
13731                // We left the provider in the launching list, need to
13732                // restart it.
13733                restart = true;
13734            }
13735
13736            cpr.provider = null;
13737            cpr.proc = null;
13738        }
13739        app.pubProviders.clear();
13740
13741        // Take care of any launching providers waiting for this process.
13742        if (checkAppInLaunchingProvidersLocked(app, false)) {
13743            restart = true;
13744        }
13745
13746        // Unregister from connected content providers.
13747        if (!app.conProviders.isEmpty()) {
13748            for (int i=0; i<app.conProviders.size(); i++) {
13749                ContentProviderConnection conn = app.conProviders.get(i);
13750                conn.provider.connections.remove(conn);
13751            }
13752            app.conProviders.clear();
13753        }
13754
13755        // At this point there may be remaining entries in mLaunchingProviders
13756        // where we were the only one waiting, so they are no longer of use.
13757        // Look for these and clean up if found.
13758        // XXX Commented out for now.  Trying to figure out a way to reproduce
13759        // the actual situation to identify what is actually going on.
13760        if (false) {
13761            for (int i=0; i<mLaunchingProviders.size(); i++) {
13762                ContentProviderRecord cpr = (ContentProviderRecord)
13763                        mLaunchingProviders.get(i);
13764                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13765                    synchronized (cpr) {
13766                        cpr.launchingApp = null;
13767                        cpr.notifyAll();
13768                    }
13769                }
13770            }
13771        }
13772
13773        skipCurrentReceiverLocked(app);
13774
13775        // Unregister any receivers.
13776        for (int i=app.receivers.size()-1; i>=0; i--) {
13777            removeReceiverLocked(app.receivers.valueAt(i));
13778        }
13779        app.receivers.clear();
13780
13781        // If the app is undergoing backup, tell the backup manager about it
13782        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13783            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13784                    + mBackupTarget.appInfo + " died during backup");
13785            try {
13786                IBackupManager bm = IBackupManager.Stub.asInterface(
13787                        ServiceManager.getService(Context.BACKUP_SERVICE));
13788                bm.agentDisconnected(app.info.packageName);
13789            } catch (RemoteException e) {
13790                // can't happen; backup manager is local
13791            }
13792        }
13793
13794        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13795            ProcessChangeItem item = mPendingProcessChanges.get(i);
13796            if (item.pid == app.pid) {
13797                mPendingProcessChanges.remove(i);
13798                mAvailProcessChanges.add(item);
13799            }
13800        }
13801        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13802
13803        // If the caller is restarting this app, then leave it in its
13804        // current lists and let the caller take care of it.
13805        if (restarting) {
13806            return;
13807        }
13808
13809        if (!app.persistent || app.isolated) {
13810            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13811                    "Removing non-persistent process during cleanup: " + app);
13812            mProcessNames.remove(app.processName, app.uid);
13813            mIsolatedProcesses.remove(app.uid);
13814            if (mHeavyWeightProcess == app) {
13815                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13816                        mHeavyWeightProcess.userId, 0));
13817                mHeavyWeightProcess = null;
13818            }
13819        } else if (!app.removed) {
13820            // This app is persistent, so we need to keep its record around.
13821            // If it is not already on the pending app list, add it there
13822            // and start a new process for it.
13823            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13824                mPersistentStartingProcesses.add(app);
13825                restart = true;
13826            }
13827        }
13828        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13829                "Clean-up removing on hold: " + app);
13830        mProcessesOnHold.remove(app);
13831
13832        if (app == mHomeProcess) {
13833            mHomeProcess = null;
13834        }
13835        if (app == mPreviousProcess) {
13836            mPreviousProcess = null;
13837        }
13838
13839        if (restart && !app.isolated) {
13840            // We have components that still need to be running in the
13841            // process, so re-launch it.
13842            mProcessNames.put(app.processName, app.uid, app);
13843            startProcessLocked(app, "restart", app.processName);
13844        } else if (app.pid > 0 && app.pid != MY_PID) {
13845            // Goodbye!
13846            boolean removed;
13847            synchronized (mPidsSelfLocked) {
13848                mPidsSelfLocked.remove(app.pid);
13849                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13850            }
13851            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13852            if (app.isolated) {
13853                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13854            }
13855            app.setPid(0);
13856        }
13857    }
13858
13859    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13860        // Look through the content providers we are waiting to have launched,
13861        // and if any run in this process then either schedule a restart of
13862        // the process or kill the client waiting for it if this process has
13863        // gone bad.
13864        int NL = mLaunchingProviders.size();
13865        boolean restart = false;
13866        for (int i=0; i<NL; i++) {
13867            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13868            if (cpr.launchingApp == app) {
13869                if (!alwaysBad && !app.bad) {
13870                    restart = true;
13871                } else {
13872                    removeDyingProviderLocked(app, cpr, true);
13873                    // cpr should have been removed from mLaunchingProviders
13874                    NL = mLaunchingProviders.size();
13875                    i--;
13876                }
13877            }
13878        }
13879        return restart;
13880    }
13881
13882    // =========================================================
13883    // SERVICES
13884    // =========================================================
13885
13886    @Override
13887    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13888            int flags) {
13889        enforceNotIsolatedCaller("getServices");
13890        synchronized (this) {
13891            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13892        }
13893    }
13894
13895    @Override
13896    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13897        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13898        synchronized (this) {
13899            return mServices.getRunningServiceControlPanelLocked(name);
13900        }
13901    }
13902
13903    @Override
13904    public ComponentName startService(IApplicationThread caller, Intent service,
13905            String resolvedType, int userId) {
13906        enforceNotIsolatedCaller("startService");
13907        // Refuse possible leaked file descriptors
13908        if (service != null && service.hasFileDescriptors() == true) {
13909            throw new IllegalArgumentException("File descriptors passed in Intent");
13910        }
13911
13912        if (DEBUG_SERVICE)
13913            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13914        synchronized(this) {
13915            final int callingPid = Binder.getCallingPid();
13916            final int callingUid = Binder.getCallingUid();
13917            final long origId = Binder.clearCallingIdentity();
13918            ComponentName res = mServices.startServiceLocked(caller, service,
13919                    resolvedType, callingPid, callingUid, userId);
13920            Binder.restoreCallingIdentity(origId);
13921            return res;
13922        }
13923    }
13924
13925    ComponentName startServiceInPackage(int uid,
13926            Intent service, String resolvedType, int userId) {
13927        synchronized(this) {
13928            if (DEBUG_SERVICE)
13929                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13930            final long origId = Binder.clearCallingIdentity();
13931            ComponentName res = mServices.startServiceLocked(null, service,
13932                    resolvedType, -1, uid, userId);
13933            Binder.restoreCallingIdentity(origId);
13934            return res;
13935        }
13936    }
13937
13938    @Override
13939    public int stopService(IApplicationThread caller, Intent service,
13940            String resolvedType, int userId) {
13941        enforceNotIsolatedCaller("stopService");
13942        // Refuse possible leaked file descriptors
13943        if (service != null && service.hasFileDescriptors() == true) {
13944            throw new IllegalArgumentException("File descriptors passed in Intent");
13945        }
13946
13947        synchronized(this) {
13948            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13949        }
13950    }
13951
13952    @Override
13953    public IBinder peekService(Intent service, String resolvedType) {
13954        enforceNotIsolatedCaller("peekService");
13955        // Refuse possible leaked file descriptors
13956        if (service != null && service.hasFileDescriptors() == true) {
13957            throw new IllegalArgumentException("File descriptors passed in Intent");
13958        }
13959        synchronized(this) {
13960            return mServices.peekServiceLocked(service, resolvedType);
13961        }
13962    }
13963
13964    @Override
13965    public boolean stopServiceToken(ComponentName className, IBinder token,
13966            int startId) {
13967        synchronized(this) {
13968            return mServices.stopServiceTokenLocked(className, token, startId);
13969        }
13970    }
13971
13972    @Override
13973    public void setServiceForeground(ComponentName className, IBinder token,
13974            int id, Notification notification, boolean removeNotification) {
13975        synchronized(this) {
13976            mServices.setServiceForegroundLocked(className, token, id, notification,
13977                    removeNotification);
13978        }
13979    }
13980
13981    @Override
13982    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13983            boolean requireFull, String name, String callerPackage) {
13984        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13985                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13986    }
13987
13988    int unsafeConvertIncomingUser(int userId) {
13989        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13990                ? mCurrentUserId : userId;
13991    }
13992
13993    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13994            int allowMode, String name, String callerPackage) {
13995        final int callingUserId = UserHandle.getUserId(callingUid);
13996        if (callingUserId == userId) {
13997            return userId;
13998        }
13999
14000        // Note that we may be accessing mCurrentUserId outside of a lock...
14001        // shouldn't be a big deal, if this is being called outside
14002        // of a locked context there is intrinsically a race with
14003        // the value the caller will receive and someone else changing it.
14004        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14005        // we will switch to the calling user if access to the current user fails.
14006        int targetUserId = unsafeConvertIncomingUser(userId);
14007
14008        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14009            final boolean allow;
14010            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14011                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14012                // If the caller has this permission, they always pass go.  And collect $200.
14013                allow = true;
14014            } else if (allowMode == ALLOW_FULL_ONLY) {
14015                // We require full access, sucks to be you.
14016                allow = false;
14017            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14018                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14019                // If the caller does not have either permission, they are always doomed.
14020                allow = false;
14021            } else if (allowMode == ALLOW_NON_FULL) {
14022                // We are blanket allowing non-full access, you lucky caller!
14023                allow = true;
14024            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14025                // We may or may not allow this depending on whether the two users are
14026                // in the same profile.
14027                synchronized (mUserProfileGroupIdsSelfLocked) {
14028                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14029                            UserInfo.NO_PROFILE_GROUP_ID);
14030                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14031                            UserInfo.NO_PROFILE_GROUP_ID);
14032                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14033                            && callingProfile == targetProfile;
14034                }
14035            } else {
14036                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14037            }
14038            if (!allow) {
14039                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14040                    // In this case, they would like to just execute as their
14041                    // owner user instead of failing.
14042                    targetUserId = callingUserId;
14043                } else {
14044                    StringBuilder builder = new StringBuilder(128);
14045                    builder.append("Permission Denial: ");
14046                    builder.append(name);
14047                    if (callerPackage != null) {
14048                        builder.append(" from ");
14049                        builder.append(callerPackage);
14050                    }
14051                    builder.append(" asks to run as user ");
14052                    builder.append(userId);
14053                    builder.append(" but is calling from user ");
14054                    builder.append(UserHandle.getUserId(callingUid));
14055                    builder.append("; this requires ");
14056                    builder.append(INTERACT_ACROSS_USERS_FULL);
14057                    if (allowMode != ALLOW_FULL_ONLY) {
14058                        builder.append(" or ");
14059                        builder.append(INTERACT_ACROSS_USERS);
14060                    }
14061                    String msg = builder.toString();
14062                    Slog.w(TAG, msg);
14063                    throw new SecurityException(msg);
14064                }
14065            }
14066        }
14067        if (!allowAll && targetUserId < 0) {
14068            throw new IllegalArgumentException(
14069                    "Call does not support special user #" + targetUserId);
14070        }
14071        return targetUserId;
14072    }
14073
14074    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14075            String className, int flags) {
14076        boolean result = false;
14077        // For apps that don't have pre-defined UIDs, check for permission
14078        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14079            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14080                if (ActivityManager.checkUidPermission(
14081                        INTERACT_ACROSS_USERS,
14082                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14083                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14084                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14085                            + " requests FLAG_SINGLE_USER, but app does not hold "
14086                            + INTERACT_ACROSS_USERS;
14087                    Slog.w(TAG, msg);
14088                    throw new SecurityException(msg);
14089                }
14090                // Permission passed
14091                result = true;
14092            }
14093        } else if ("system".equals(componentProcessName)) {
14094            result = true;
14095        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14096                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14097            // Phone app is allowed to export singleuser providers.
14098            result = true;
14099        } else {
14100            // App with pre-defined UID, check if it's a persistent app
14101            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14102        }
14103        if (DEBUG_MU) {
14104            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14105                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14106        }
14107        return result;
14108    }
14109
14110    /**
14111     * Checks to see if the caller is in the same app as the singleton
14112     * component, or the component is in a special app. It allows special apps
14113     * to export singleton components but prevents exporting singleton
14114     * components for regular apps.
14115     */
14116    boolean isValidSingletonCall(int callingUid, int componentUid) {
14117        int componentAppId = UserHandle.getAppId(componentUid);
14118        return UserHandle.isSameApp(callingUid, componentUid)
14119                || componentAppId == Process.SYSTEM_UID
14120                || componentAppId == Process.PHONE_UID
14121                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14122                        == PackageManager.PERMISSION_GRANTED;
14123    }
14124
14125    public int bindService(IApplicationThread caller, IBinder token,
14126            Intent service, String resolvedType,
14127            IServiceConnection connection, int flags, int userId) {
14128        enforceNotIsolatedCaller("bindService");
14129        // Refuse possible leaked file descriptors
14130        if (service != null && service.hasFileDescriptors() == true) {
14131            throw new IllegalArgumentException("File descriptors passed in Intent");
14132        }
14133
14134        synchronized(this) {
14135            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14136                    connection, flags, userId);
14137        }
14138    }
14139
14140    public boolean unbindService(IServiceConnection connection) {
14141        synchronized (this) {
14142            return mServices.unbindServiceLocked(connection);
14143        }
14144    }
14145
14146    public void publishService(IBinder token, Intent intent, IBinder service) {
14147        // Refuse possible leaked file descriptors
14148        if (intent != null && intent.hasFileDescriptors() == true) {
14149            throw new IllegalArgumentException("File descriptors passed in Intent");
14150        }
14151
14152        synchronized(this) {
14153            if (!(token instanceof ServiceRecord)) {
14154                throw new IllegalArgumentException("Invalid service token");
14155            }
14156            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14157        }
14158    }
14159
14160    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14161        // Refuse possible leaked file descriptors
14162        if (intent != null && intent.hasFileDescriptors() == true) {
14163            throw new IllegalArgumentException("File descriptors passed in Intent");
14164        }
14165
14166        synchronized(this) {
14167            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14168        }
14169    }
14170
14171    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14172        synchronized(this) {
14173            if (!(token instanceof ServiceRecord)) {
14174                throw new IllegalArgumentException("Invalid service token");
14175            }
14176            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14177        }
14178    }
14179
14180    // =========================================================
14181    // BACKUP AND RESTORE
14182    // =========================================================
14183
14184    // Cause the target app to be launched if necessary and its backup agent
14185    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14186    // activity manager to announce its creation.
14187    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14188        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14189        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14190
14191        synchronized(this) {
14192            // !!! TODO: currently no check here that we're already bound
14193            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14194            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14195            synchronized (stats) {
14196                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14197            }
14198
14199            // Backup agent is now in use, its package can't be stopped.
14200            try {
14201                AppGlobals.getPackageManager().setPackageStoppedState(
14202                        app.packageName, false, UserHandle.getUserId(app.uid));
14203            } catch (RemoteException e) {
14204            } catch (IllegalArgumentException e) {
14205                Slog.w(TAG, "Failed trying to unstop package "
14206                        + app.packageName + ": " + e);
14207            }
14208
14209            BackupRecord r = new BackupRecord(ss, app, backupMode);
14210            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14211                    ? new ComponentName(app.packageName, app.backupAgentName)
14212                    : new ComponentName("android", "FullBackupAgent");
14213            // startProcessLocked() returns existing proc's record if it's already running
14214            ProcessRecord proc = startProcessLocked(app.processName, app,
14215                    false, 0, "backup", hostingName, false, false, false);
14216            if (proc == null) {
14217                Slog.e(TAG, "Unable to start backup agent process " + r);
14218                return false;
14219            }
14220
14221            r.app = proc;
14222            mBackupTarget = r;
14223            mBackupAppName = app.packageName;
14224
14225            // Try not to kill the process during backup
14226            updateOomAdjLocked(proc);
14227
14228            // If the process is already attached, schedule the creation of the backup agent now.
14229            // If it is not yet live, this will be done when it attaches to the framework.
14230            if (proc.thread != null) {
14231                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14232                try {
14233                    proc.thread.scheduleCreateBackupAgent(app,
14234                            compatibilityInfoForPackageLocked(app), backupMode);
14235                } catch (RemoteException e) {
14236                    // Will time out on the backup manager side
14237                }
14238            } else {
14239                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14240            }
14241            // Invariants: at this point, the target app process exists and the application
14242            // is either already running or in the process of coming up.  mBackupTarget and
14243            // mBackupAppName describe the app, so that when it binds back to the AM we
14244            // know that it's scheduled for a backup-agent operation.
14245        }
14246
14247        return true;
14248    }
14249
14250    @Override
14251    public void clearPendingBackup() {
14252        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14253        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14254
14255        synchronized (this) {
14256            mBackupTarget = null;
14257            mBackupAppName = null;
14258        }
14259    }
14260
14261    // A backup agent has just come up
14262    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14263        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14264                + " = " + agent);
14265
14266        synchronized(this) {
14267            if (!agentPackageName.equals(mBackupAppName)) {
14268                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14269                return;
14270            }
14271        }
14272
14273        long oldIdent = Binder.clearCallingIdentity();
14274        try {
14275            IBackupManager bm = IBackupManager.Stub.asInterface(
14276                    ServiceManager.getService(Context.BACKUP_SERVICE));
14277            bm.agentConnected(agentPackageName, agent);
14278        } catch (RemoteException e) {
14279            // can't happen; the backup manager service is local
14280        } catch (Exception e) {
14281            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14282            e.printStackTrace();
14283        } finally {
14284            Binder.restoreCallingIdentity(oldIdent);
14285        }
14286    }
14287
14288    // done with this agent
14289    public void unbindBackupAgent(ApplicationInfo appInfo) {
14290        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14291        if (appInfo == null) {
14292            Slog.w(TAG, "unbind backup agent for null app");
14293            return;
14294        }
14295
14296        synchronized(this) {
14297            try {
14298                if (mBackupAppName == null) {
14299                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14300                    return;
14301                }
14302
14303                if (!mBackupAppName.equals(appInfo.packageName)) {
14304                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14305                    return;
14306                }
14307
14308                // Not backing this app up any more; reset its OOM adjustment
14309                final ProcessRecord proc = mBackupTarget.app;
14310                updateOomAdjLocked(proc);
14311
14312                // If the app crashed during backup, 'thread' will be null here
14313                if (proc.thread != null) {
14314                    try {
14315                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14316                                compatibilityInfoForPackageLocked(appInfo));
14317                    } catch (Exception e) {
14318                        Slog.e(TAG, "Exception when unbinding backup agent:");
14319                        e.printStackTrace();
14320                    }
14321                }
14322            } finally {
14323                mBackupTarget = null;
14324                mBackupAppName = null;
14325            }
14326        }
14327    }
14328    // =========================================================
14329    // BROADCASTS
14330    // =========================================================
14331
14332    private final List getStickiesLocked(String action, IntentFilter filter,
14333            List cur, int userId) {
14334        final ContentResolver resolver = mContext.getContentResolver();
14335        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14336        if (stickies == null) {
14337            return cur;
14338        }
14339        final ArrayList<Intent> list = stickies.get(action);
14340        if (list == null) {
14341            return cur;
14342        }
14343        int N = list.size();
14344        for (int i=0; i<N; i++) {
14345            Intent intent = list.get(i);
14346            if (filter.match(resolver, intent, true, TAG) >= 0) {
14347                if (cur == null) {
14348                    cur = new ArrayList<Intent>();
14349                }
14350                cur.add(intent);
14351            }
14352        }
14353        return cur;
14354    }
14355
14356    boolean isPendingBroadcastProcessLocked(int pid) {
14357        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14358                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14359    }
14360
14361    void skipPendingBroadcastLocked(int pid) {
14362            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14363            for (BroadcastQueue queue : mBroadcastQueues) {
14364                queue.skipPendingBroadcastLocked(pid);
14365            }
14366    }
14367
14368    // The app just attached; send any pending broadcasts that it should receive
14369    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14370        boolean didSomething = false;
14371        for (BroadcastQueue queue : mBroadcastQueues) {
14372            didSomething |= queue.sendPendingBroadcastsLocked(app);
14373        }
14374        return didSomething;
14375    }
14376
14377    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14378            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14379        enforceNotIsolatedCaller("registerReceiver");
14380        int callingUid;
14381        int callingPid;
14382        synchronized(this) {
14383            ProcessRecord callerApp = null;
14384            if (caller != null) {
14385                callerApp = getRecordForAppLocked(caller);
14386                if (callerApp == null) {
14387                    throw new SecurityException(
14388                            "Unable to find app for caller " + caller
14389                            + " (pid=" + Binder.getCallingPid()
14390                            + ") when registering receiver " + receiver);
14391                }
14392                if (callerApp.info.uid != Process.SYSTEM_UID &&
14393                        !callerApp.pkgList.containsKey(callerPackage) &&
14394                        !"android".equals(callerPackage)) {
14395                    throw new SecurityException("Given caller package " + callerPackage
14396                            + " is not running in process " + callerApp);
14397                }
14398                callingUid = callerApp.info.uid;
14399                callingPid = callerApp.pid;
14400            } else {
14401                callerPackage = null;
14402                callingUid = Binder.getCallingUid();
14403                callingPid = Binder.getCallingPid();
14404            }
14405
14406            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14407                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14408
14409            List allSticky = null;
14410
14411            // Look for any matching sticky broadcasts...
14412            Iterator actions = filter.actionsIterator();
14413            if (actions != null) {
14414                while (actions.hasNext()) {
14415                    String action = (String)actions.next();
14416                    allSticky = getStickiesLocked(action, filter, allSticky,
14417                            UserHandle.USER_ALL);
14418                    allSticky = getStickiesLocked(action, filter, allSticky,
14419                            UserHandle.getUserId(callingUid));
14420                }
14421            } else {
14422                allSticky = getStickiesLocked(null, filter, allSticky,
14423                        UserHandle.USER_ALL);
14424                allSticky = getStickiesLocked(null, filter, allSticky,
14425                        UserHandle.getUserId(callingUid));
14426            }
14427
14428            // The first sticky in the list is returned directly back to
14429            // the client.
14430            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14431
14432            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14433                    + ": " + sticky);
14434
14435            if (receiver == null) {
14436                return sticky;
14437            }
14438
14439            ReceiverList rl
14440                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14441            if (rl == null) {
14442                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14443                        userId, receiver);
14444                if (rl.app != null) {
14445                    rl.app.receivers.add(rl);
14446                } else {
14447                    try {
14448                        receiver.asBinder().linkToDeath(rl, 0);
14449                    } catch (RemoteException e) {
14450                        return sticky;
14451                    }
14452                    rl.linkedToDeath = true;
14453                }
14454                mRegisteredReceivers.put(receiver.asBinder(), rl);
14455            } else if (rl.uid != callingUid) {
14456                throw new IllegalArgumentException(
14457                        "Receiver requested to register for uid " + callingUid
14458                        + " was previously registered for uid " + rl.uid);
14459            } else if (rl.pid != callingPid) {
14460                throw new IllegalArgumentException(
14461                        "Receiver requested to register for pid " + callingPid
14462                        + " was previously registered for pid " + rl.pid);
14463            } else if (rl.userId != userId) {
14464                throw new IllegalArgumentException(
14465                        "Receiver requested to register for user " + userId
14466                        + " was previously registered for user " + rl.userId);
14467            }
14468            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14469                    permission, callingUid, userId);
14470            rl.add(bf);
14471            if (!bf.debugCheck()) {
14472                Slog.w(TAG, "==> For Dynamic broadast");
14473            }
14474            mReceiverResolver.addFilter(bf);
14475
14476            // Enqueue broadcasts for all existing stickies that match
14477            // this filter.
14478            if (allSticky != null) {
14479                ArrayList receivers = new ArrayList();
14480                receivers.add(bf);
14481
14482                int N = allSticky.size();
14483                for (int i=0; i<N; i++) {
14484                    Intent intent = (Intent)allSticky.get(i);
14485                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14486                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14487                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14488                            null, null, false, true, true, -1);
14489                    queue.enqueueParallelBroadcastLocked(r);
14490                    queue.scheduleBroadcastsLocked();
14491                }
14492            }
14493
14494            return sticky;
14495        }
14496    }
14497
14498    public void unregisterReceiver(IIntentReceiver receiver) {
14499        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14500
14501        final long origId = Binder.clearCallingIdentity();
14502        try {
14503            boolean doTrim = false;
14504
14505            synchronized(this) {
14506                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14507                if (rl != null) {
14508                    if (rl.curBroadcast != null) {
14509                        BroadcastRecord r = rl.curBroadcast;
14510                        final boolean doNext = finishReceiverLocked(
14511                                receiver.asBinder(), r.resultCode, r.resultData,
14512                                r.resultExtras, r.resultAbort);
14513                        if (doNext) {
14514                            doTrim = true;
14515                            r.queue.processNextBroadcast(false);
14516                        }
14517                    }
14518
14519                    if (rl.app != null) {
14520                        rl.app.receivers.remove(rl);
14521                    }
14522                    removeReceiverLocked(rl);
14523                    if (rl.linkedToDeath) {
14524                        rl.linkedToDeath = false;
14525                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14526                    }
14527                }
14528            }
14529
14530            // If we actually concluded any broadcasts, we might now be able
14531            // to trim the recipients' apps from our working set
14532            if (doTrim) {
14533                trimApplications();
14534                return;
14535            }
14536
14537        } finally {
14538            Binder.restoreCallingIdentity(origId);
14539        }
14540    }
14541
14542    void removeReceiverLocked(ReceiverList rl) {
14543        mRegisteredReceivers.remove(rl.receiver.asBinder());
14544        int N = rl.size();
14545        for (int i=0; i<N; i++) {
14546            mReceiverResolver.removeFilter(rl.get(i));
14547        }
14548    }
14549
14550    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14551        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14552            ProcessRecord r = mLruProcesses.get(i);
14553            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14554                try {
14555                    r.thread.dispatchPackageBroadcast(cmd, packages);
14556                } catch (RemoteException ex) {
14557                }
14558            }
14559        }
14560    }
14561
14562    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14563            int[] users) {
14564        List<ResolveInfo> receivers = null;
14565        try {
14566            HashSet<ComponentName> singleUserReceivers = null;
14567            boolean scannedFirstReceivers = false;
14568            for (int user : users) {
14569                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14570                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14571                if (user != 0 && newReceivers != null) {
14572                    // If this is not the primary user, we need to check for
14573                    // any receivers that should be filtered out.
14574                    for (int i=0; i<newReceivers.size(); i++) {
14575                        ResolveInfo ri = newReceivers.get(i);
14576                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14577                            newReceivers.remove(i);
14578                            i--;
14579                        }
14580                    }
14581                }
14582                if (newReceivers != null && newReceivers.size() == 0) {
14583                    newReceivers = null;
14584                }
14585                if (receivers == null) {
14586                    receivers = newReceivers;
14587                } else if (newReceivers != null) {
14588                    // We need to concatenate the additional receivers
14589                    // found with what we have do far.  This would be easy,
14590                    // but we also need to de-dup any receivers that are
14591                    // singleUser.
14592                    if (!scannedFirstReceivers) {
14593                        // Collect any single user receivers we had already retrieved.
14594                        scannedFirstReceivers = true;
14595                        for (int i=0; i<receivers.size(); i++) {
14596                            ResolveInfo ri = receivers.get(i);
14597                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14598                                ComponentName cn = new ComponentName(
14599                                        ri.activityInfo.packageName, ri.activityInfo.name);
14600                                if (singleUserReceivers == null) {
14601                                    singleUserReceivers = new HashSet<ComponentName>();
14602                                }
14603                                singleUserReceivers.add(cn);
14604                            }
14605                        }
14606                    }
14607                    // Add the new results to the existing results, tracking
14608                    // and de-dupping single user receivers.
14609                    for (int i=0; i<newReceivers.size(); i++) {
14610                        ResolveInfo ri = newReceivers.get(i);
14611                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14612                            ComponentName cn = new ComponentName(
14613                                    ri.activityInfo.packageName, ri.activityInfo.name);
14614                            if (singleUserReceivers == null) {
14615                                singleUserReceivers = new HashSet<ComponentName>();
14616                            }
14617                            if (!singleUserReceivers.contains(cn)) {
14618                                singleUserReceivers.add(cn);
14619                                receivers.add(ri);
14620                            }
14621                        } else {
14622                            receivers.add(ri);
14623                        }
14624                    }
14625                }
14626            }
14627        } catch (RemoteException ex) {
14628            // pm is in same process, this will never happen.
14629        }
14630        return receivers;
14631    }
14632
14633    private final int broadcastIntentLocked(ProcessRecord callerApp,
14634            String callerPackage, Intent intent, String resolvedType,
14635            IIntentReceiver resultTo, int resultCode, String resultData,
14636            Bundle map, String requiredPermission, int appOp,
14637            boolean ordered, boolean sticky, int callingPid, int callingUid,
14638            int userId) {
14639        intent = new Intent(intent);
14640
14641        // By default broadcasts do not go to stopped apps.
14642        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14643
14644        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14645            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14646            + " ordered=" + ordered + " userid=" + userId);
14647        if ((resultTo != null) && !ordered) {
14648            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14649        }
14650
14651        userId = handleIncomingUser(callingPid, callingUid, userId,
14652                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14653
14654        // Make sure that the user who is receiving this broadcast is started.
14655        // If not, we will just skip it.
14656
14657
14658        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14659            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14660                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14661                Slog.w(TAG, "Skipping broadcast of " + intent
14662                        + ": user " + userId + " is stopped");
14663                return ActivityManager.BROADCAST_SUCCESS;
14664            }
14665        }
14666
14667        /*
14668         * Prevent non-system code (defined here to be non-persistent
14669         * processes) from sending protected broadcasts.
14670         */
14671        int callingAppId = UserHandle.getAppId(callingUid);
14672        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14673            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14674            || callingAppId == Process.NFC_UID || callingUid == 0) {
14675            // Always okay.
14676        } else if (callerApp == null || !callerApp.persistent) {
14677            try {
14678                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14679                        intent.getAction())) {
14680                    String msg = "Permission Denial: not allowed to send broadcast "
14681                            + intent.getAction() + " from pid="
14682                            + callingPid + ", uid=" + callingUid;
14683                    Slog.w(TAG, msg);
14684                    throw new SecurityException(msg);
14685                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14686                    // Special case for compatibility: we don't want apps to send this,
14687                    // but historically it has not been protected and apps may be using it
14688                    // to poke their own app widget.  So, instead of making it protected,
14689                    // just limit it to the caller.
14690                    if (callerApp == null) {
14691                        String msg = "Permission Denial: not allowed to send broadcast "
14692                                + intent.getAction() + " from unknown caller.";
14693                        Slog.w(TAG, msg);
14694                        throw new SecurityException(msg);
14695                    } else if (intent.getComponent() != null) {
14696                        // They are good enough to send to an explicit component...  verify
14697                        // it is being sent to the calling app.
14698                        if (!intent.getComponent().getPackageName().equals(
14699                                callerApp.info.packageName)) {
14700                            String msg = "Permission Denial: not allowed to send broadcast "
14701                                    + intent.getAction() + " to "
14702                                    + intent.getComponent().getPackageName() + " from "
14703                                    + callerApp.info.packageName;
14704                            Slog.w(TAG, msg);
14705                            throw new SecurityException(msg);
14706                        }
14707                    } else {
14708                        // Limit broadcast to their own package.
14709                        intent.setPackage(callerApp.info.packageName);
14710                    }
14711                }
14712            } catch (RemoteException e) {
14713                Slog.w(TAG, "Remote exception", e);
14714                return ActivityManager.BROADCAST_SUCCESS;
14715            }
14716        }
14717
14718        // Handle special intents: if this broadcast is from the package
14719        // manager about a package being removed, we need to remove all of
14720        // its activities from the history stack.
14721        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14722                intent.getAction());
14723        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14724                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14725                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14726                || uidRemoved) {
14727            if (checkComponentPermission(
14728                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14729                    callingPid, callingUid, -1, true)
14730                    == PackageManager.PERMISSION_GRANTED) {
14731                if (uidRemoved) {
14732                    final Bundle intentExtras = intent.getExtras();
14733                    final int uid = intentExtras != null
14734                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14735                    if (uid >= 0) {
14736                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14737                        synchronized (bs) {
14738                            bs.removeUidStatsLocked(uid);
14739                        }
14740                        mAppOpsService.uidRemoved(uid);
14741                    }
14742                } else {
14743                    // If resources are unavailable just force stop all
14744                    // those packages and flush the attribute cache as well.
14745                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14746                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14747                        if (list != null && (list.length > 0)) {
14748                            for (String pkg : list) {
14749                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14750                                        "storage unmount");
14751                            }
14752                            sendPackageBroadcastLocked(
14753                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14754                        }
14755                    } else {
14756                        Uri data = intent.getData();
14757                        String ssp;
14758                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14759                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14760                                    intent.getAction());
14761                            boolean fullUninstall = removed &&
14762                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14763                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14764                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14765                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14766                                        false, fullUninstall, userId,
14767                                        removed ? "pkg removed" : "pkg changed");
14768                            }
14769                            if (removed) {
14770                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14771                                        new String[] {ssp}, userId);
14772                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14773                                    mAppOpsService.packageRemoved(
14774                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14775
14776                                    // Remove all permissions granted from/to this package
14777                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14778                                }
14779                            }
14780                        }
14781                    }
14782                }
14783            } else {
14784                String msg = "Permission Denial: " + intent.getAction()
14785                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14786                        + ", uid=" + callingUid + ")"
14787                        + " requires "
14788                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14789                Slog.w(TAG, msg);
14790                throw new SecurityException(msg);
14791            }
14792
14793        // Special case for adding a package: by default turn on compatibility
14794        // mode.
14795        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14796            Uri data = intent.getData();
14797            String ssp;
14798            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14799                mCompatModePackages.handlePackageAddedLocked(ssp,
14800                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14801            }
14802        }
14803
14804        /*
14805         * If this is the time zone changed action, queue up a message that will reset the timezone
14806         * of all currently running processes. This message will get queued up before the broadcast
14807         * happens.
14808         */
14809        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14810            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14811        }
14812
14813        /*
14814         * If the user set the time, let all running processes know.
14815         */
14816        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14817            final int is24Hour = intent.getBooleanExtra(
14818                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14819            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14820        }
14821
14822        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14823            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14824        }
14825
14826        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14827            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14828            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14829        }
14830
14831        // Add to the sticky list if requested.
14832        if (sticky) {
14833            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14834                    callingPid, callingUid)
14835                    != PackageManager.PERMISSION_GRANTED) {
14836                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14837                        + callingPid + ", uid=" + callingUid
14838                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14839                Slog.w(TAG, msg);
14840                throw new SecurityException(msg);
14841            }
14842            if (requiredPermission != null) {
14843                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14844                        + " and enforce permission " + requiredPermission);
14845                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14846            }
14847            if (intent.getComponent() != null) {
14848                throw new SecurityException(
14849                        "Sticky broadcasts can't target a specific component");
14850            }
14851            // We use userId directly here, since the "all" target is maintained
14852            // as a separate set of sticky broadcasts.
14853            if (userId != UserHandle.USER_ALL) {
14854                // But first, if this is not a broadcast to all users, then
14855                // make sure it doesn't conflict with an existing broadcast to
14856                // all users.
14857                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14858                        UserHandle.USER_ALL);
14859                if (stickies != null) {
14860                    ArrayList<Intent> list = stickies.get(intent.getAction());
14861                    if (list != null) {
14862                        int N = list.size();
14863                        int i;
14864                        for (i=0; i<N; i++) {
14865                            if (intent.filterEquals(list.get(i))) {
14866                                throw new IllegalArgumentException(
14867                                        "Sticky broadcast " + intent + " for user "
14868                                        + userId + " conflicts with existing global broadcast");
14869                            }
14870                        }
14871                    }
14872                }
14873            }
14874            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14875            if (stickies == null) {
14876                stickies = new ArrayMap<String, ArrayList<Intent>>();
14877                mStickyBroadcasts.put(userId, stickies);
14878            }
14879            ArrayList<Intent> list = stickies.get(intent.getAction());
14880            if (list == null) {
14881                list = new ArrayList<Intent>();
14882                stickies.put(intent.getAction(), list);
14883            }
14884            int N = list.size();
14885            int i;
14886            for (i=0; i<N; i++) {
14887                if (intent.filterEquals(list.get(i))) {
14888                    // This sticky already exists, replace it.
14889                    list.set(i, new Intent(intent));
14890                    break;
14891                }
14892            }
14893            if (i >= N) {
14894                list.add(new Intent(intent));
14895            }
14896        }
14897
14898        int[] users;
14899        if (userId == UserHandle.USER_ALL) {
14900            // Caller wants broadcast to go to all started users.
14901            users = mStartedUserArray;
14902        } else {
14903            // Caller wants broadcast to go to one specific user.
14904            users = new int[] {userId};
14905        }
14906
14907        // Figure out who all will receive this broadcast.
14908        List receivers = null;
14909        List<BroadcastFilter> registeredReceivers = null;
14910        // Need to resolve the intent to interested receivers...
14911        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14912                 == 0) {
14913            receivers = collectReceiverComponents(intent, resolvedType, users);
14914        }
14915        if (intent.getComponent() == null) {
14916            registeredReceivers = mReceiverResolver.queryIntent(intent,
14917                    resolvedType, false, userId);
14918        }
14919
14920        final boolean replacePending =
14921                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14922
14923        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14924                + " replacePending=" + replacePending);
14925
14926        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14927        if (!ordered && NR > 0) {
14928            // If we are not serializing this broadcast, then send the
14929            // registered receivers separately so they don't wait for the
14930            // components to be launched.
14931            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14932            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14933                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14934                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14935                    ordered, sticky, false, userId);
14936            if (DEBUG_BROADCAST) Slog.v(
14937                    TAG, "Enqueueing parallel broadcast " + r);
14938            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14939            if (!replaced) {
14940                queue.enqueueParallelBroadcastLocked(r);
14941                queue.scheduleBroadcastsLocked();
14942            }
14943            registeredReceivers = null;
14944            NR = 0;
14945        }
14946
14947        // Merge into one list.
14948        int ir = 0;
14949        if (receivers != null) {
14950            // A special case for PACKAGE_ADDED: do not allow the package
14951            // being added to see this broadcast.  This prevents them from
14952            // using this as a back door to get run as soon as they are
14953            // installed.  Maybe in the future we want to have a special install
14954            // broadcast or such for apps, but we'd like to deliberately make
14955            // this decision.
14956            String skipPackages[] = null;
14957            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14958                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14959                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14960                Uri data = intent.getData();
14961                if (data != null) {
14962                    String pkgName = data.getSchemeSpecificPart();
14963                    if (pkgName != null) {
14964                        skipPackages = new String[] { pkgName };
14965                    }
14966                }
14967            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14968                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14969            }
14970            if (skipPackages != null && (skipPackages.length > 0)) {
14971                for (String skipPackage : skipPackages) {
14972                    if (skipPackage != null) {
14973                        int NT = receivers.size();
14974                        for (int it=0; it<NT; it++) {
14975                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14976                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14977                                receivers.remove(it);
14978                                it--;
14979                                NT--;
14980                            }
14981                        }
14982                    }
14983                }
14984            }
14985
14986            int NT = receivers != null ? receivers.size() : 0;
14987            int it = 0;
14988            ResolveInfo curt = null;
14989            BroadcastFilter curr = null;
14990            while (it < NT && ir < NR) {
14991                if (curt == null) {
14992                    curt = (ResolveInfo)receivers.get(it);
14993                }
14994                if (curr == null) {
14995                    curr = registeredReceivers.get(ir);
14996                }
14997                if (curr.getPriority() >= curt.priority) {
14998                    // Insert this broadcast record into the final list.
14999                    receivers.add(it, curr);
15000                    ir++;
15001                    curr = null;
15002                    it++;
15003                    NT++;
15004                } else {
15005                    // Skip to the next ResolveInfo in the final list.
15006                    it++;
15007                    curt = null;
15008                }
15009            }
15010        }
15011        while (ir < NR) {
15012            if (receivers == null) {
15013                receivers = new ArrayList();
15014            }
15015            receivers.add(registeredReceivers.get(ir));
15016            ir++;
15017        }
15018
15019        if ((receivers != null && receivers.size() > 0)
15020                || resultTo != null) {
15021            BroadcastQueue queue = broadcastQueueForIntent(intent);
15022            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15023                    callerPackage, callingPid, callingUid, resolvedType,
15024                    requiredPermission, appOp, receivers, resultTo, resultCode,
15025                    resultData, map, ordered, sticky, false, userId);
15026            if (DEBUG_BROADCAST) Slog.v(
15027                    TAG, "Enqueueing ordered broadcast " + r
15028                    + ": prev had " + queue.mOrderedBroadcasts.size());
15029            if (DEBUG_BROADCAST) {
15030                int seq = r.intent.getIntExtra("seq", -1);
15031                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15032            }
15033            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15034            if (!replaced) {
15035                queue.enqueueOrderedBroadcastLocked(r);
15036                queue.scheduleBroadcastsLocked();
15037            }
15038        }
15039
15040        return ActivityManager.BROADCAST_SUCCESS;
15041    }
15042
15043    final Intent verifyBroadcastLocked(Intent intent) {
15044        // Refuse possible leaked file descriptors
15045        if (intent != null && intent.hasFileDescriptors() == true) {
15046            throw new IllegalArgumentException("File descriptors passed in Intent");
15047        }
15048
15049        int flags = intent.getFlags();
15050
15051        if (!mProcessesReady) {
15052            // if the caller really truly claims to know what they're doing, go
15053            // ahead and allow the broadcast without launching any receivers
15054            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15055                intent = new Intent(intent);
15056                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15057            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15058                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15059                        + " before boot completion");
15060                throw new IllegalStateException("Cannot broadcast before boot completed");
15061            }
15062        }
15063
15064        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15065            throw new IllegalArgumentException(
15066                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15067        }
15068
15069        return intent;
15070    }
15071
15072    public final int broadcastIntent(IApplicationThread caller,
15073            Intent intent, String resolvedType, IIntentReceiver resultTo,
15074            int resultCode, String resultData, Bundle map,
15075            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15076        enforceNotIsolatedCaller("broadcastIntent");
15077        synchronized(this) {
15078            intent = verifyBroadcastLocked(intent);
15079
15080            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15081            final int callingPid = Binder.getCallingPid();
15082            final int callingUid = Binder.getCallingUid();
15083            final long origId = Binder.clearCallingIdentity();
15084            int res = broadcastIntentLocked(callerApp,
15085                    callerApp != null ? callerApp.info.packageName : null,
15086                    intent, resolvedType, resultTo,
15087                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15088                    callingPid, callingUid, userId);
15089            Binder.restoreCallingIdentity(origId);
15090            return res;
15091        }
15092    }
15093
15094    int broadcastIntentInPackage(String packageName, int uid,
15095            Intent intent, String resolvedType, IIntentReceiver resultTo,
15096            int resultCode, String resultData, Bundle map,
15097            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15098        synchronized(this) {
15099            intent = verifyBroadcastLocked(intent);
15100
15101            final long origId = Binder.clearCallingIdentity();
15102            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15103                    resultTo, resultCode, resultData, map, requiredPermission,
15104                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15105            Binder.restoreCallingIdentity(origId);
15106            return res;
15107        }
15108    }
15109
15110    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15111        // Refuse possible leaked file descriptors
15112        if (intent != null && intent.hasFileDescriptors() == true) {
15113            throw new IllegalArgumentException("File descriptors passed in Intent");
15114        }
15115
15116        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15117                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15118
15119        synchronized(this) {
15120            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15121                    != PackageManager.PERMISSION_GRANTED) {
15122                String msg = "Permission Denial: unbroadcastIntent() from pid="
15123                        + Binder.getCallingPid()
15124                        + ", uid=" + Binder.getCallingUid()
15125                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15126                Slog.w(TAG, msg);
15127                throw new SecurityException(msg);
15128            }
15129            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15130            if (stickies != null) {
15131                ArrayList<Intent> list = stickies.get(intent.getAction());
15132                if (list != null) {
15133                    int N = list.size();
15134                    int i;
15135                    for (i=0; i<N; i++) {
15136                        if (intent.filterEquals(list.get(i))) {
15137                            list.remove(i);
15138                            break;
15139                        }
15140                    }
15141                    if (list.size() <= 0) {
15142                        stickies.remove(intent.getAction());
15143                    }
15144                }
15145                if (stickies.size() <= 0) {
15146                    mStickyBroadcasts.remove(userId);
15147                }
15148            }
15149        }
15150    }
15151
15152    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15153            String resultData, Bundle resultExtras, boolean resultAbort) {
15154        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15155        if (r == null) {
15156            Slog.w(TAG, "finishReceiver called but not found on queue");
15157            return false;
15158        }
15159
15160        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15161    }
15162
15163    void backgroundServicesFinishedLocked(int userId) {
15164        for (BroadcastQueue queue : mBroadcastQueues) {
15165            queue.backgroundServicesFinishedLocked(userId);
15166        }
15167    }
15168
15169    public void finishReceiver(IBinder who, int resultCode, String resultData,
15170            Bundle resultExtras, boolean resultAbort) {
15171        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15172
15173        // Refuse possible leaked file descriptors
15174        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15175            throw new IllegalArgumentException("File descriptors passed in Bundle");
15176        }
15177
15178        final long origId = Binder.clearCallingIdentity();
15179        try {
15180            boolean doNext = false;
15181            BroadcastRecord r;
15182
15183            synchronized(this) {
15184                r = broadcastRecordForReceiverLocked(who);
15185                if (r != null) {
15186                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15187                        resultData, resultExtras, resultAbort, true);
15188                }
15189            }
15190
15191            if (doNext) {
15192                r.queue.processNextBroadcast(false);
15193            }
15194            trimApplications();
15195        } finally {
15196            Binder.restoreCallingIdentity(origId);
15197        }
15198    }
15199
15200    // =========================================================
15201    // INSTRUMENTATION
15202    // =========================================================
15203
15204    public boolean startInstrumentation(ComponentName className,
15205            String profileFile, int flags, Bundle arguments,
15206            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15207            int userId, String abiOverride) {
15208        enforceNotIsolatedCaller("startInstrumentation");
15209        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15210                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15211        // Refuse possible leaked file descriptors
15212        if (arguments != null && arguments.hasFileDescriptors()) {
15213            throw new IllegalArgumentException("File descriptors passed in Bundle");
15214        }
15215
15216        synchronized(this) {
15217            InstrumentationInfo ii = null;
15218            ApplicationInfo ai = null;
15219            try {
15220                ii = mContext.getPackageManager().getInstrumentationInfo(
15221                    className, STOCK_PM_FLAGS);
15222                ai = AppGlobals.getPackageManager().getApplicationInfo(
15223                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15224            } catch (PackageManager.NameNotFoundException e) {
15225            } catch (RemoteException e) {
15226            }
15227            if (ii == null) {
15228                reportStartInstrumentationFailure(watcher, className,
15229                        "Unable to find instrumentation info for: " + className);
15230                return false;
15231            }
15232            if (ai == null) {
15233                reportStartInstrumentationFailure(watcher, className,
15234                        "Unable to find instrumentation target package: " + ii.targetPackage);
15235                return false;
15236            }
15237
15238            int match = mContext.getPackageManager().checkSignatures(
15239                    ii.targetPackage, ii.packageName);
15240            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15241                String msg = "Permission Denial: starting instrumentation "
15242                        + className + " from pid="
15243                        + Binder.getCallingPid()
15244                        + ", uid=" + Binder.getCallingPid()
15245                        + " not allowed because package " + ii.packageName
15246                        + " does not have a signature matching the target "
15247                        + ii.targetPackage;
15248                reportStartInstrumentationFailure(watcher, className, msg);
15249                throw new SecurityException(msg);
15250            }
15251
15252            final long origId = Binder.clearCallingIdentity();
15253            // Instrumentation can kill and relaunch even persistent processes
15254            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15255                    "start instr");
15256            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15257            app.instrumentationClass = className;
15258            app.instrumentationInfo = ai;
15259            app.instrumentationProfileFile = profileFile;
15260            app.instrumentationArguments = arguments;
15261            app.instrumentationWatcher = watcher;
15262            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15263            app.instrumentationResultClass = className;
15264            Binder.restoreCallingIdentity(origId);
15265        }
15266
15267        return true;
15268    }
15269
15270    /**
15271     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15272     * error to the logs, but if somebody is watching, send the report there too.  This enables
15273     * the "am" command to report errors with more information.
15274     *
15275     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15276     * @param cn The component name of the instrumentation.
15277     * @param report The error report.
15278     */
15279    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15280            ComponentName cn, String report) {
15281        Slog.w(TAG, report);
15282        try {
15283            if (watcher != null) {
15284                Bundle results = new Bundle();
15285                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15286                results.putString("Error", report);
15287                watcher.instrumentationStatus(cn, -1, results);
15288            }
15289        } catch (RemoteException e) {
15290            Slog.w(TAG, e);
15291        }
15292    }
15293
15294    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15295        if (app.instrumentationWatcher != null) {
15296            try {
15297                // NOTE:  IInstrumentationWatcher *must* be oneway here
15298                app.instrumentationWatcher.instrumentationFinished(
15299                    app.instrumentationClass,
15300                    resultCode,
15301                    results);
15302            } catch (RemoteException e) {
15303            }
15304        }
15305        if (app.instrumentationUiAutomationConnection != null) {
15306            try {
15307                app.instrumentationUiAutomationConnection.shutdown();
15308            } catch (RemoteException re) {
15309                /* ignore */
15310            }
15311            // Only a UiAutomation can set this flag and now that
15312            // it is finished we make sure it is reset to its default.
15313            mUserIsMonkey = false;
15314        }
15315        app.instrumentationWatcher = null;
15316        app.instrumentationUiAutomationConnection = null;
15317        app.instrumentationClass = null;
15318        app.instrumentationInfo = null;
15319        app.instrumentationProfileFile = null;
15320        app.instrumentationArguments = null;
15321
15322        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15323                "finished inst");
15324    }
15325
15326    public void finishInstrumentation(IApplicationThread target,
15327            int resultCode, Bundle results) {
15328        int userId = UserHandle.getCallingUserId();
15329        // Refuse possible leaked file descriptors
15330        if (results != null && results.hasFileDescriptors()) {
15331            throw new IllegalArgumentException("File descriptors passed in Intent");
15332        }
15333
15334        synchronized(this) {
15335            ProcessRecord app = getRecordForAppLocked(target);
15336            if (app == null) {
15337                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15338                return;
15339            }
15340            final long origId = Binder.clearCallingIdentity();
15341            finishInstrumentationLocked(app, resultCode, results);
15342            Binder.restoreCallingIdentity(origId);
15343        }
15344    }
15345
15346    // =========================================================
15347    // CONFIGURATION
15348    // =========================================================
15349
15350    public ConfigurationInfo getDeviceConfigurationInfo() {
15351        ConfigurationInfo config = new ConfigurationInfo();
15352        synchronized (this) {
15353            config.reqTouchScreen = mConfiguration.touchscreen;
15354            config.reqKeyboardType = mConfiguration.keyboard;
15355            config.reqNavigation = mConfiguration.navigation;
15356            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15357                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15358                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15359            }
15360            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15361                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15362                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15363            }
15364            config.reqGlEsVersion = GL_ES_VERSION;
15365        }
15366        return config;
15367    }
15368
15369    ActivityStack getFocusedStack() {
15370        return mStackSupervisor.getFocusedStack();
15371    }
15372
15373    public Configuration getConfiguration() {
15374        Configuration ci;
15375        synchronized(this) {
15376            ci = new Configuration(mConfiguration);
15377        }
15378        return ci;
15379    }
15380
15381    public void updatePersistentConfiguration(Configuration values) {
15382        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15383                "updateConfiguration()");
15384        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15385                "updateConfiguration()");
15386        if (values == null) {
15387            throw new NullPointerException("Configuration must not be null");
15388        }
15389
15390        synchronized(this) {
15391            final long origId = Binder.clearCallingIdentity();
15392            updateConfigurationLocked(values, null, true, false);
15393            Binder.restoreCallingIdentity(origId);
15394        }
15395    }
15396
15397    public void updateConfiguration(Configuration values) {
15398        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15399                "updateConfiguration()");
15400
15401        synchronized(this) {
15402            if (values == null && mWindowManager != null) {
15403                // sentinel: fetch the current configuration from the window manager
15404                values = mWindowManager.computeNewConfiguration();
15405            }
15406
15407            if (mWindowManager != null) {
15408                mProcessList.applyDisplaySize(mWindowManager);
15409            }
15410
15411            final long origId = Binder.clearCallingIdentity();
15412            if (values != null) {
15413                Settings.System.clearConfiguration(values);
15414            }
15415            updateConfigurationLocked(values, null, false, false);
15416            Binder.restoreCallingIdentity(origId);
15417        }
15418    }
15419
15420    /**
15421     * Do either or both things: (1) change the current configuration, and (2)
15422     * make sure the given activity is running with the (now) current
15423     * configuration.  Returns true if the activity has been left running, or
15424     * false if <var>starting</var> is being destroyed to match the new
15425     * configuration.
15426     * @param persistent TODO
15427     */
15428    boolean updateConfigurationLocked(Configuration values,
15429            ActivityRecord starting, boolean persistent, boolean initLocale) {
15430        int changes = 0;
15431
15432        if (values != null) {
15433            Configuration newConfig = new Configuration(mConfiguration);
15434            changes = newConfig.updateFrom(values);
15435            if (changes != 0) {
15436                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15437                    Slog.i(TAG, "Updating configuration to: " + values);
15438                }
15439
15440                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15441
15442                if (values.locale != null && !initLocale) {
15443                    saveLocaleLocked(values.locale,
15444                                     !values.locale.equals(mConfiguration.locale),
15445                                     values.userSetLocale);
15446                }
15447
15448                mConfigurationSeq++;
15449                if (mConfigurationSeq <= 0) {
15450                    mConfigurationSeq = 1;
15451                }
15452                newConfig.seq = mConfigurationSeq;
15453                mConfiguration = newConfig;
15454                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15455                //mUsageStatsService.noteStartConfig(newConfig);
15456
15457                final Configuration configCopy = new Configuration(mConfiguration);
15458
15459                // TODO: If our config changes, should we auto dismiss any currently
15460                // showing dialogs?
15461                mShowDialogs = shouldShowDialogs(newConfig);
15462
15463                AttributeCache ac = AttributeCache.instance();
15464                if (ac != null) {
15465                    ac.updateConfiguration(configCopy);
15466                }
15467
15468                // Make sure all resources in our process are updated
15469                // right now, so that anyone who is going to retrieve
15470                // resource values after we return will be sure to get
15471                // the new ones.  This is especially important during
15472                // boot, where the first config change needs to guarantee
15473                // all resources have that config before following boot
15474                // code is executed.
15475                mSystemThread.applyConfigurationToResources(configCopy);
15476
15477                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15478                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15479                    msg.obj = new Configuration(configCopy);
15480                    mHandler.sendMessage(msg);
15481                }
15482
15483                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15484                    ProcessRecord app = mLruProcesses.get(i);
15485                    try {
15486                        if (app.thread != null) {
15487                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15488                                    + app.processName + " new config " + mConfiguration);
15489                            app.thread.scheduleConfigurationChanged(configCopy);
15490                        }
15491                    } catch (Exception e) {
15492                    }
15493                }
15494                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15495                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15496                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15497                        | Intent.FLAG_RECEIVER_FOREGROUND);
15498                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15499                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15500                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15501                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15502                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15503                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15504                    broadcastIntentLocked(null, null, intent,
15505                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15506                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15507                }
15508            }
15509        }
15510
15511        boolean kept = true;
15512        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15513        // mainStack is null during startup.
15514        if (mainStack != null) {
15515            if (changes != 0 && starting == null) {
15516                // If the configuration changed, and the caller is not already
15517                // in the process of starting an activity, then find the top
15518                // activity to check if its configuration needs to change.
15519                starting = mainStack.topRunningActivityLocked(null);
15520            }
15521
15522            if (starting != null) {
15523                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15524                // And we need to make sure at this point that all other activities
15525                // are made visible with the correct configuration.
15526                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15527            }
15528        }
15529
15530        if (values != null && mWindowManager != null) {
15531            mWindowManager.setNewConfiguration(mConfiguration);
15532        }
15533
15534        return kept;
15535    }
15536
15537    /**
15538     * Decide based on the configuration whether we should shouw the ANR,
15539     * crash, etc dialogs.  The idea is that if there is no affordnace to
15540     * press the on-screen buttons, we shouldn't show the dialog.
15541     *
15542     * A thought: SystemUI might also want to get told about this, the Power
15543     * dialog / global actions also might want different behaviors.
15544     */
15545    private static final boolean shouldShowDialogs(Configuration config) {
15546        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15547                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15548    }
15549
15550    /**
15551     * Save the locale.  You must be inside a synchronized (this) block.
15552     */
15553    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15554        if(isDiff) {
15555            SystemProperties.set("user.language", l.getLanguage());
15556            SystemProperties.set("user.region", l.getCountry());
15557        }
15558
15559        if(isPersist) {
15560            SystemProperties.set("persist.sys.language", l.getLanguage());
15561            SystemProperties.set("persist.sys.country", l.getCountry());
15562            SystemProperties.set("persist.sys.localevar", l.getVariant());
15563        }
15564    }
15565
15566    @Override
15567    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15568        ActivityRecord srec = ActivityRecord.forToken(token);
15569        return srec != null && srec.task.affinity != null &&
15570                srec.task.affinity.equals(destAffinity);
15571    }
15572
15573    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15574            Intent resultData) {
15575
15576        synchronized (this) {
15577            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15578            if (stack != null) {
15579                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15580            }
15581            return false;
15582        }
15583    }
15584
15585    public int getLaunchedFromUid(IBinder activityToken) {
15586        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15587        if (srec == null) {
15588            return -1;
15589        }
15590        return srec.launchedFromUid;
15591    }
15592
15593    public String getLaunchedFromPackage(IBinder activityToken) {
15594        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15595        if (srec == null) {
15596            return null;
15597        }
15598        return srec.launchedFromPackage;
15599    }
15600
15601    // =========================================================
15602    // LIFETIME MANAGEMENT
15603    // =========================================================
15604
15605    // Returns which broadcast queue the app is the current [or imminent] receiver
15606    // on, or 'null' if the app is not an active broadcast recipient.
15607    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15608        BroadcastRecord r = app.curReceiver;
15609        if (r != null) {
15610            return r.queue;
15611        }
15612
15613        // It's not the current receiver, but it might be starting up to become one
15614        synchronized (this) {
15615            for (BroadcastQueue queue : mBroadcastQueues) {
15616                r = queue.mPendingBroadcast;
15617                if (r != null && r.curApp == app) {
15618                    // found it; report which queue it's in
15619                    return queue;
15620                }
15621            }
15622        }
15623
15624        return null;
15625    }
15626
15627    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15628            boolean doingAll, long now) {
15629        if (mAdjSeq == app.adjSeq) {
15630            // This adjustment has already been computed.
15631            return app.curRawAdj;
15632        }
15633
15634        if (app.thread == null) {
15635            app.adjSeq = mAdjSeq;
15636            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15637            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15638            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15639        }
15640
15641        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15642        app.adjSource = null;
15643        app.adjTarget = null;
15644        app.empty = false;
15645        app.cached = false;
15646
15647        final int activitiesSize = app.activities.size();
15648
15649        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15650            // The max adjustment doesn't allow this app to be anything
15651            // below foreground, so it is not worth doing work for it.
15652            app.adjType = "fixed";
15653            app.adjSeq = mAdjSeq;
15654            app.curRawAdj = app.maxAdj;
15655            app.foregroundActivities = false;
15656            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15657            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15658            // System processes can do UI, and when they do we want to have
15659            // them trim their memory after the user leaves the UI.  To
15660            // facilitate this, here we need to determine whether or not it
15661            // is currently showing UI.
15662            app.systemNoUi = true;
15663            if (app == TOP_APP) {
15664                app.systemNoUi = false;
15665            } else if (activitiesSize > 0) {
15666                for (int j = 0; j < activitiesSize; j++) {
15667                    final ActivityRecord r = app.activities.get(j);
15668                    if (r.visible) {
15669                        app.systemNoUi = false;
15670                    }
15671                }
15672            }
15673            if (!app.systemNoUi) {
15674                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15675            }
15676            return (app.curAdj=app.maxAdj);
15677        }
15678
15679        app.systemNoUi = false;
15680
15681        // Determine the importance of the process, starting with most
15682        // important to least, and assign an appropriate OOM adjustment.
15683        int adj;
15684        int schedGroup;
15685        int procState;
15686        boolean foregroundActivities = false;
15687        BroadcastQueue queue;
15688        if (app == TOP_APP) {
15689            // The last app on the list is the foreground app.
15690            adj = ProcessList.FOREGROUND_APP_ADJ;
15691            schedGroup = Process.THREAD_GROUP_DEFAULT;
15692            app.adjType = "top-activity";
15693            foregroundActivities = true;
15694            procState = ActivityManager.PROCESS_STATE_TOP;
15695        } else if (app.instrumentationClass != null) {
15696            // Don't want to kill running instrumentation.
15697            adj = ProcessList.FOREGROUND_APP_ADJ;
15698            schedGroup = Process.THREAD_GROUP_DEFAULT;
15699            app.adjType = "instrumentation";
15700            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15701        } else if ((queue = isReceivingBroadcast(app)) != null) {
15702            // An app that is currently receiving a broadcast also
15703            // counts as being in the foreground for OOM killer purposes.
15704            // It's placed in a sched group based on the nature of the
15705            // broadcast as reflected by which queue it's active in.
15706            adj = ProcessList.FOREGROUND_APP_ADJ;
15707            schedGroup = (queue == mFgBroadcastQueue)
15708                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15709            app.adjType = "broadcast";
15710            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15711        } else if (app.executingServices.size() > 0) {
15712            // An app that is currently executing a service callback also
15713            // counts as being in the foreground.
15714            adj = ProcessList.FOREGROUND_APP_ADJ;
15715            schedGroup = app.execServicesFg ?
15716                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15717            app.adjType = "exec-service";
15718            procState = ActivityManager.PROCESS_STATE_SERVICE;
15719            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15720        } else {
15721            // As far as we know the process is empty.  We may change our mind later.
15722            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15723            // At this point we don't actually know the adjustment.  Use the cached adj
15724            // value that the caller wants us to.
15725            adj = cachedAdj;
15726            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15727            app.cached = true;
15728            app.empty = true;
15729            app.adjType = "cch-empty";
15730        }
15731
15732        // Examine all activities if not already foreground.
15733        if (!foregroundActivities && activitiesSize > 0) {
15734            for (int j = 0; j < activitiesSize; j++) {
15735                final ActivityRecord r = app.activities.get(j);
15736                if (r.app != app) {
15737                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15738                            + app + "?!?");
15739                    continue;
15740                }
15741                if (r.visible) {
15742                    // App has a visible activity; only upgrade adjustment.
15743                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15744                        adj = ProcessList.VISIBLE_APP_ADJ;
15745                        app.adjType = "visible";
15746                    }
15747                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15748                        procState = ActivityManager.PROCESS_STATE_TOP;
15749                    }
15750                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15751                    app.cached = false;
15752                    app.empty = false;
15753                    foregroundActivities = true;
15754                    break;
15755                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15756                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15757                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15758                        app.adjType = "pausing";
15759                    }
15760                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15761                        procState = ActivityManager.PROCESS_STATE_TOP;
15762                    }
15763                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15764                    app.cached = false;
15765                    app.empty = false;
15766                    foregroundActivities = true;
15767                } else if (r.state == ActivityState.STOPPING) {
15768                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15769                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15770                        app.adjType = "stopping";
15771                    }
15772                    // For the process state, we will at this point consider the
15773                    // process to be cached.  It will be cached either as an activity
15774                    // or empty depending on whether the activity is finishing.  We do
15775                    // this so that we can treat the process as cached for purposes of
15776                    // memory trimming (determing current memory level, trim command to
15777                    // send to process) since there can be an arbitrary number of stopping
15778                    // processes and they should soon all go into the cached state.
15779                    if (!r.finishing) {
15780                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15781                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15782                        }
15783                    }
15784                    app.cached = false;
15785                    app.empty = false;
15786                    foregroundActivities = true;
15787                } else {
15788                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15789                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15790                        app.adjType = "cch-act";
15791                    }
15792                }
15793            }
15794        }
15795
15796        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15797            if (app.foregroundServices) {
15798                // The user is aware of this app, so make it visible.
15799                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15800                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15801                app.cached = false;
15802                app.adjType = "fg-service";
15803                schedGroup = Process.THREAD_GROUP_DEFAULT;
15804            } else if (app.forcingToForeground != null) {
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 = "force-fg";
15810                app.adjSource = app.forcingToForeground;
15811                schedGroup = Process.THREAD_GROUP_DEFAULT;
15812            }
15813        }
15814
15815        if (app == mHeavyWeightProcess) {
15816            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15817                // We don't want to kill the current heavy-weight process.
15818                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15819                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15820                app.cached = false;
15821                app.adjType = "heavy";
15822            }
15823            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15824                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15825            }
15826        }
15827
15828        if (app == mHomeProcess) {
15829            if (adj > ProcessList.HOME_APP_ADJ) {
15830                // This process is hosting what we currently consider to be the
15831                // home app, so we don't want to let it go into the background.
15832                adj = ProcessList.HOME_APP_ADJ;
15833                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15834                app.cached = false;
15835                app.adjType = "home";
15836            }
15837            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15838                procState = ActivityManager.PROCESS_STATE_HOME;
15839            }
15840        }
15841
15842        if (app == mPreviousProcess && app.activities.size() > 0) {
15843            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15844                // This was the previous process that showed UI to the user.
15845                // We want to try to keep it around more aggressively, to give
15846                // a good experience around switching between two apps.
15847                adj = ProcessList.PREVIOUS_APP_ADJ;
15848                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15849                app.cached = false;
15850                app.adjType = "previous";
15851            }
15852            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15853                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15854            }
15855        }
15856
15857        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15858                + " reason=" + app.adjType);
15859
15860        // By default, we use the computed adjustment.  It may be changed if
15861        // there are applications dependent on our services or providers, but
15862        // this gives us a baseline and makes sure we don't get into an
15863        // infinite recursion.
15864        app.adjSeq = mAdjSeq;
15865        app.curRawAdj = adj;
15866        app.hasStartedServices = false;
15867
15868        if (mBackupTarget != null && app == mBackupTarget.app) {
15869            // If possible we want to avoid killing apps while they're being backed up
15870            if (adj > ProcessList.BACKUP_APP_ADJ) {
15871                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15872                adj = ProcessList.BACKUP_APP_ADJ;
15873                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15874                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15875                }
15876                app.adjType = "backup";
15877                app.cached = false;
15878            }
15879            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15880                procState = ActivityManager.PROCESS_STATE_BACKUP;
15881            }
15882        }
15883
15884        boolean mayBeTop = false;
15885
15886        for (int is = app.services.size()-1;
15887                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15888                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15889                        || procState > ActivityManager.PROCESS_STATE_TOP);
15890                is--) {
15891            ServiceRecord s = app.services.valueAt(is);
15892            if (s.startRequested) {
15893                app.hasStartedServices = true;
15894                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15895                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15896                }
15897                if (app.hasShownUi && app != mHomeProcess) {
15898                    // If this process has shown some UI, let it immediately
15899                    // go to the LRU list because it may be pretty heavy with
15900                    // UI stuff.  We'll tag it with a label just to help
15901                    // debug and understand what is going on.
15902                    if (adj > ProcessList.SERVICE_ADJ) {
15903                        app.adjType = "cch-started-ui-services";
15904                    }
15905                } else {
15906                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15907                        // This service has seen some activity within
15908                        // recent memory, so we will keep its process ahead
15909                        // of the background processes.
15910                        if (adj > ProcessList.SERVICE_ADJ) {
15911                            adj = ProcessList.SERVICE_ADJ;
15912                            app.adjType = "started-services";
15913                            app.cached = false;
15914                        }
15915                    }
15916                    // If we have let the service slide into the background
15917                    // state, still have some text describing what it is doing
15918                    // even though the service no longer has an impact.
15919                    if (adj > ProcessList.SERVICE_ADJ) {
15920                        app.adjType = "cch-started-services";
15921                    }
15922                }
15923            }
15924            for (int conni = s.connections.size()-1;
15925                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15926                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15927                            || procState > ActivityManager.PROCESS_STATE_TOP);
15928                    conni--) {
15929                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15930                for (int i = 0;
15931                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15932                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15933                                || procState > ActivityManager.PROCESS_STATE_TOP);
15934                        i++) {
15935                    // XXX should compute this based on the max of
15936                    // all connected clients.
15937                    ConnectionRecord cr = clist.get(i);
15938                    if (cr.binding.client == app) {
15939                        // Binding to ourself is not interesting.
15940                        continue;
15941                    }
15942                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15943                        ProcessRecord client = cr.binding.client;
15944                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15945                                TOP_APP, doingAll, now);
15946                        int clientProcState = client.curProcState;
15947                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15948                            // If the other app is cached for any reason, for purposes here
15949                            // we are going to consider it empty.  The specific cached state
15950                            // doesn't propagate except under certain conditions.
15951                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15952                        }
15953                        String adjType = null;
15954                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15955                            // Not doing bind OOM management, so treat
15956                            // this guy more like a started service.
15957                            if (app.hasShownUi && app != mHomeProcess) {
15958                                // If this process has shown some UI, let it immediately
15959                                // go to the LRU list because it may be pretty heavy with
15960                                // UI stuff.  We'll tag it with a label just to help
15961                                // debug and understand what is going on.
15962                                if (adj > clientAdj) {
15963                                    adjType = "cch-bound-ui-services";
15964                                }
15965                                app.cached = false;
15966                                clientAdj = adj;
15967                                clientProcState = procState;
15968                            } else {
15969                                if (now >= (s.lastActivity
15970                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15971                                    // This service has not seen activity within
15972                                    // recent memory, so allow it to drop to the
15973                                    // LRU list if there is no other reason to keep
15974                                    // it around.  We'll also tag it with a label just
15975                                    // to help debug and undertand what is going on.
15976                                    if (adj > clientAdj) {
15977                                        adjType = "cch-bound-services";
15978                                    }
15979                                    clientAdj = adj;
15980                                }
15981                            }
15982                        }
15983                        if (adj > clientAdj) {
15984                            // If this process has recently shown UI, and
15985                            // the process that is binding to it is less
15986                            // important than being visible, then we don't
15987                            // care about the binding as much as we care
15988                            // about letting this process get into the LRU
15989                            // list to be killed and restarted if needed for
15990                            // memory.
15991                            if (app.hasShownUi && app != mHomeProcess
15992                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15993                                adjType = "cch-bound-ui-services";
15994                            } else {
15995                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15996                                        |Context.BIND_IMPORTANT)) != 0) {
15997                                    adj = clientAdj;
15998                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15999                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16000                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16001                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16002                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16003                                    adj = clientAdj;
16004                                } else {
16005                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16006                                        adj = ProcessList.VISIBLE_APP_ADJ;
16007                                    }
16008                                }
16009                                if (!client.cached) {
16010                                    app.cached = false;
16011                                }
16012                                adjType = "service";
16013                            }
16014                        }
16015                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16016                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16017                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16018                            }
16019                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16020                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16021                                    // Special handling of clients who are in the top state.
16022                                    // We *may* want to consider this process to be in the
16023                                    // top state as well, but only if there is not another
16024                                    // reason for it to be running.  Being on the top is a
16025                                    // special state, meaning you are specifically running
16026                                    // for the current top app.  If the process is already
16027                                    // running in the background for some other reason, it
16028                                    // is more important to continue considering it to be
16029                                    // in the background state.
16030                                    mayBeTop = true;
16031                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16032                                } else {
16033                                    // Special handling for above-top states (persistent
16034                                    // processes).  These should not bring the current process
16035                                    // into the top state, since they are not on top.  Instead
16036                                    // give them the best state after that.
16037                                    clientProcState =
16038                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16039                                }
16040                            }
16041                        } else {
16042                            if (clientProcState <
16043                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16044                                clientProcState =
16045                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16046                            }
16047                        }
16048                        if (procState > clientProcState) {
16049                            procState = clientProcState;
16050                        }
16051                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16052                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16053                            app.pendingUiClean = true;
16054                        }
16055                        if (adjType != null) {
16056                            app.adjType = adjType;
16057                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16058                                    .REASON_SERVICE_IN_USE;
16059                            app.adjSource = cr.binding.client;
16060                            app.adjSourceProcState = clientProcState;
16061                            app.adjTarget = s.name;
16062                        }
16063                    }
16064                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16065                        app.treatLikeActivity = true;
16066                    }
16067                    final ActivityRecord a = cr.activity;
16068                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16069                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16070                                (a.visible || a.state == ActivityState.RESUMED
16071                                 || a.state == ActivityState.PAUSING)) {
16072                            adj = ProcessList.FOREGROUND_APP_ADJ;
16073                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16074                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16075                            }
16076                            app.cached = false;
16077                            app.adjType = "service";
16078                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16079                                    .REASON_SERVICE_IN_USE;
16080                            app.adjSource = a;
16081                            app.adjSourceProcState = procState;
16082                            app.adjTarget = s.name;
16083                        }
16084                    }
16085                }
16086            }
16087        }
16088
16089        for (int provi = app.pubProviders.size()-1;
16090                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16091                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16092                        || procState > ActivityManager.PROCESS_STATE_TOP);
16093                provi--) {
16094            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16095            for (int i = cpr.connections.size()-1;
16096                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16097                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16098                            || procState > ActivityManager.PROCESS_STATE_TOP);
16099                    i--) {
16100                ContentProviderConnection conn = cpr.connections.get(i);
16101                ProcessRecord client = conn.client;
16102                if (client == app) {
16103                    // Being our own client is not interesting.
16104                    continue;
16105                }
16106                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16107                int clientProcState = client.curProcState;
16108                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16109                    // If the other app is cached for any reason, for purposes here
16110                    // we are going to consider it empty.
16111                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16112                }
16113                if (adj > clientAdj) {
16114                    if (app.hasShownUi && app != mHomeProcess
16115                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16116                        app.adjType = "cch-ui-provider";
16117                    } else {
16118                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16119                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16120                        app.adjType = "provider";
16121                    }
16122                    app.cached &= client.cached;
16123                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16124                            .REASON_PROVIDER_IN_USE;
16125                    app.adjSource = client;
16126                    app.adjSourceProcState = clientProcState;
16127                    app.adjTarget = cpr.name;
16128                }
16129                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16130                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16131                        // Special handling of clients who are in the top state.
16132                        // We *may* want to consider this process to be in the
16133                        // top state as well, but only if there is not another
16134                        // reason for it to be running.  Being on the top is a
16135                        // special state, meaning you are specifically running
16136                        // for the current top app.  If the process is already
16137                        // running in the background for some other reason, it
16138                        // is more important to continue considering it to be
16139                        // in the background state.
16140                        mayBeTop = true;
16141                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16142                    } else {
16143                        // Special handling for above-top states (persistent
16144                        // processes).  These should not bring the current process
16145                        // into the top state, since they are not on top.  Instead
16146                        // give them the best state after that.
16147                        clientProcState =
16148                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16149                    }
16150                }
16151                if (procState > clientProcState) {
16152                    procState = clientProcState;
16153                }
16154                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16155                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16156                }
16157            }
16158            // If the provider has external (non-framework) process
16159            // dependencies, ensure that its adjustment is at least
16160            // FOREGROUND_APP_ADJ.
16161            if (cpr.hasExternalProcessHandles()) {
16162                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16163                    adj = ProcessList.FOREGROUND_APP_ADJ;
16164                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16165                    app.cached = false;
16166                    app.adjType = "provider";
16167                    app.adjTarget = cpr.name;
16168                }
16169                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16170                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16171                }
16172            }
16173        }
16174
16175        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16176            // A client of one of our services or providers is in the top state.  We
16177            // *may* want to be in the top state, but not if we are already running in
16178            // the background for some other reason.  For the decision here, we are going
16179            // to pick out a few specific states that we want to remain in when a client
16180            // is top (states that tend to be longer-term) and otherwise allow it to go
16181            // to the top state.
16182            switch (procState) {
16183                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16184                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16185                case ActivityManager.PROCESS_STATE_SERVICE:
16186                    // These all are longer-term states, so pull them up to the top
16187                    // of the background states, but not all the way to the top state.
16188                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16189                    break;
16190                default:
16191                    // Otherwise, top is a better choice, so take it.
16192                    procState = ActivityManager.PROCESS_STATE_TOP;
16193                    break;
16194            }
16195        }
16196
16197        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16198            if (app.hasClientActivities) {
16199                // This is a cached process, but with client activities.  Mark it so.
16200                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16201                app.adjType = "cch-client-act";
16202            } else if (app.treatLikeActivity) {
16203                // This is a cached process, but somebody wants us to treat it like it has
16204                // an activity, okay!
16205                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16206                app.adjType = "cch-as-act";
16207            }
16208        }
16209
16210        if (adj == ProcessList.SERVICE_ADJ) {
16211            if (doingAll) {
16212                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16213                mNewNumServiceProcs++;
16214                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16215                if (!app.serviceb) {
16216                    // This service isn't far enough down on the LRU list to
16217                    // normally be a B service, but if we are low on RAM and it
16218                    // is large we want to force it down since we would prefer to
16219                    // keep launcher over it.
16220                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16221                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16222                        app.serviceHighRam = true;
16223                        app.serviceb = true;
16224                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16225                    } else {
16226                        mNewNumAServiceProcs++;
16227                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16228                    }
16229                } else {
16230                    app.serviceHighRam = false;
16231                }
16232            }
16233            if (app.serviceb) {
16234                adj = ProcessList.SERVICE_B_ADJ;
16235            }
16236        }
16237
16238        app.curRawAdj = adj;
16239
16240        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16241        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16242        if (adj > app.maxAdj) {
16243            adj = app.maxAdj;
16244            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16245                schedGroup = Process.THREAD_GROUP_DEFAULT;
16246            }
16247        }
16248
16249        // Do final modification to adj.  Everything we do between here and applying
16250        // the final setAdj must be done in this function, because we will also use
16251        // it when computing the final cached adj later.  Note that we don't need to
16252        // worry about this for max adj above, since max adj will always be used to
16253        // keep it out of the cached vaues.
16254        app.curAdj = app.modifyRawOomAdj(adj);
16255        app.curSchedGroup = schedGroup;
16256        app.curProcState = procState;
16257        app.foregroundActivities = foregroundActivities;
16258
16259        return app.curRawAdj;
16260    }
16261
16262    /**
16263     * Schedule PSS collection of a process.
16264     */
16265    void requestPssLocked(ProcessRecord proc, int procState) {
16266        if (mPendingPssProcesses.contains(proc)) {
16267            return;
16268        }
16269        if (mPendingPssProcesses.size() == 0) {
16270            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16271        }
16272        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16273        proc.pssProcState = procState;
16274        mPendingPssProcesses.add(proc);
16275    }
16276
16277    /**
16278     * Schedule PSS collection of all processes.
16279     */
16280    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16281        if (!always) {
16282            if (now < (mLastFullPssTime +
16283                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16284                return;
16285            }
16286        }
16287        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16288        mLastFullPssTime = now;
16289        mFullPssPending = true;
16290        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16291        mPendingPssProcesses.clear();
16292        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16293            ProcessRecord app = mLruProcesses.get(i);
16294            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16295                app.pssProcState = app.setProcState;
16296                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16297                        isSleeping(), now);
16298                mPendingPssProcesses.add(app);
16299            }
16300        }
16301        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16302    }
16303
16304    /**
16305     * Ask a given process to GC right now.
16306     */
16307    final void performAppGcLocked(ProcessRecord app) {
16308        try {
16309            app.lastRequestedGc = SystemClock.uptimeMillis();
16310            if (app.thread != null) {
16311                if (app.reportLowMemory) {
16312                    app.reportLowMemory = false;
16313                    app.thread.scheduleLowMemory();
16314                } else {
16315                    app.thread.processInBackground();
16316                }
16317            }
16318        } catch (Exception e) {
16319            // whatever.
16320        }
16321    }
16322
16323    /**
16324     * Returns true if things are idle enough to perform GCs.
16325     */
16326    private final boolean canGcNowLocked() {
16327        boolean processingBroadcasts = false;
16328        for (BroadcastQueue q : mBroadcastQueues) {
16329            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16330                processingBroadcasts = true;
16331            }
16332        }
16333        return !processingBroadcasts
16334                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16335    }
16336
16337    /**
16338     * Perform GCs on all processes that are waiting for it, but only
16339     * if things are idle.
16340     */
16341    final void performAppGcsLocked() {
16342        final int N = mProcessesToGc.size();
16343        if (N <= 0) {
16344            return;
16345        }
16346        if (canGcNowLocked()) {
16347            while (mProcessesToGc.size() > 0) {
16348                ProcessRecord proc = mProcessesToGc.remove(0);
16349                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16350                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16351                            <= SystemClock.uptimeMillis()) {
16352                        // To avoid spamming the system, we will GC processes one
16353                        // at a time, waiting a few seconds between each.
16354                        performAppGcLocked(proc);
16355                        scheduleAppGcsLocked();
16356                        return;
16357                    } else {
16358                        // It hasn't been long enough since we last GCed this
16359                        // process...  put it in the list to wait for its time.
16360                        addProcessToGcListLocked(proc);
16361                        break;
16362                    }
16363                }
16364            }
16365
16366            scheduleAppGcsLocked();
16367        }
16368    }
16369
16370    /**
16371     * If all looks good, perform GCs on all processes waiting for them.
16372     */
16373    final void performAppGcsIfAppropriateLocked() {
16374        if (canGcNowLocked()) {
16375            performAppGcsLocked();
16376            return;
16377        }
16378        // Still not idle, wait some more.
16379        scheduleAppGcsLocked();
16380    }
16381
16382    /**
16383     * Schedule the execution of all pending app GCs.
16384     */
16385    final void scheduleAppGcsLocked() {
16386        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16387
16388        if (mProcessesToGc.size() > 0) {
16389            // Schedule a GC for the time to the next process.
16390            ProcessRecord proc = mProcessesToGc.get(0);
16391            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16392
16393            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16394            long now = SystemClock.uptimeMillis();
16395            if (when < (now+GC_TIMEOUT)) {
16396                when = now + GC_TIMEOUT;
16397            }
16398            mHandler.sendMessageAtTime(msg, when);
16399        }
16400    }
16401
16402    /**
16403     * Add a process to the array of processes waiting to be GCed.  Keeps the
16404     * list in sorted order by the last GC time.  The process can't already be
16405     * on the list.
16406     */
16407    final void addProcessToGcListLocked(ProcessRecord proc) {
16408        boolean added = false;
16409        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16410            if (mProcessesToGc.get(i).lastRequestedGc <
16411                    proc.lastRequestedGc) {
16412                added = true;
16413                mProcessesToGc.add(i+1, proc);
16414                break;
16415            }
16416        }
16417        if (!added) {
16418            mProcessesToGc.add(0, proc);
16419        }
16420    }
16421
16422    /**
16423     * Set up to ask a process to GC itself.  This will either do it
16424     * immediately, or put it on the list of processes to gc the next
16425     * time things are idle.
16426     */
16427    final void scheduleAppGcLocked(ProcessRecord app) {
16428        long now = SystemClock.uptimeMillis();
16429        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16430            return;
16431        }
16432        if (!mProcessesToGc.contains(app)) {
16433            addProcessToGcListLocked(app);
16434            scheduleAppGcsLocked();
16435        }
16436    }
16437
16438    final void checkExcessivePowerUsageLocked(boolean doKills) {
16439        updateCpuStatsNow();
16440
16441        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16442        boolean doWakeKills = doKills;
16443        boolean doCpuKills = doKills;
16444        if (mLastPowerCheckRealtime == 0) {
16445            doWakeKills = false;
16446        }
16447        if (mLastPowerCheckUptime == 0) {
16448            doCpuKills = false;
16449        }
16450        if (stats.isScreenOn()) {
16451            doWakeKills = false;
16452        }
16453        final long curRealtime = SystemClock.elapsedRealtime();
16454        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16455        final long curUptime = SystemClock.uptimeMillis();
16456        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16457        mLastPowerCheckRealtime = curRealtime;
16458        mLastPowerCheckUptime = curUptime;
16459        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16460            doWakeKills = false;
16461        }
16462        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16463            doCpuKills = false;
16464        }
16465        int i = mLruProcesses.size();
16466        while (i > 0) {
16467            i--;
16468            ProcessRecord app = mLruProcesses.get(i);
16469            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16470                long wtime;
16471                synchronized (stats) {
16472                    wtime = stats.getProcessWakeTime(app.info.uid,
16473                            app.pid, curRealtime);
16474                }
16475                long wtimeUsed = wtime - app.lastWakeTime;
16476                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16477                if (DEBUG_POWER) {
16478                    StringBuilder sb = new StringBuilder(128);
16479                    sb.append("Wake for ");
16480                    app.toShortString(sb);
16481                    sb.append(": over ");
16482                    TimeUtils.formatDuration(realtimeSince, sb);
16483                    sb.append(" used ");
16484                    TimeUtils.formatDuration(wtimeUsed, sb);
16485                    sb.append(" (");
16486                    sb.append((wtimeUsed*100)/realtimeSince);
16487                    sb.append("%)");
16488                    Slog.i(TAG, sb.toString());
16489                    sb.setLength(0);
16490                    sb.append("CPU for ");
16491                    app.toShortString(sb);
16492                    sb.append(": over ");
16493                    TimeUtils.formatDuration(uptimeSince, sb);
16494                    sb.append(" used ");
16495                    TimeUtils.formatDuration(cputimeUsed, sb);
16496                    sb.append(" (");
16497                    sb.append((cputimeUsed*100)/uptimeSince);
16498                    sb.append("%)");
16499                    Slog.i(TAG, sb.toString());
16500                }
16501                // If a process has held a wake lock for more
16502                // than 50% of the time during this period,
16503                // that sounds bad.  Kill!
16504                if (doWakeKills && realtimeSince > 0
16505                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16506                    synchronized (stats) {
16507                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16508                                realtimeSince, wtimeUsed);
16509                    }
16510                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16511                            + " during " + realtimeSince);
16512                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16513                } else if (doCpuKills && uptimeSince > 0
16514                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16515                    synchronized (stats) {
16516                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16517                                uptimeSince, cputimeUsed);
16518                    }
16519                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16520                            + " during " + uptimeSince);
16521                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16522                } else {
16523                    app.lastWakeTime = wtime;
16524                    app.lastCpuTime = app.curCpuTime;
16525                }
16526            }
16527        }
16528    }
16529
16530    private final boolean applyOomAdjLocked(ProcessRecord app,
16531            ProcessRecord TOP_APP, boolean doingAll, long now) {
16532        boolean success = true;
16533
16534        if (app.curRawAdj != app.setRawAdj) {
16535            app.setRawAdj = app.curRawAdj;
16536        }
16537
16538        int changes = 0;
16539
16540        if (app.curAdj != app.setAdj) {
16541            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16542            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16543                TAG, "Set " + app.pid + " " + app.processName +
16544                " adj " + app.curAdj + ": " + app.adjType);
16545            app.setAdj = app.curAdj;
16546        }
16547
16548        if (app.setSchedGroup != app.curSchedGroup) {
16549            app.setSchedGroup = app.curSchedGroup;
16550            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16551                    "Setting process group of " + app.processName
16552                    + " to " + app.curSchedGroup);
16553            if (app.waitingToKill != null &&
16554                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16555                killUnneededProcessLocked(app, app.waitingToKill);
16556                success = false;
16557            } else {
16558                if (true) {
16559                    long oldId = Binder.clearCallingIdentity();
16560                    try {
16561                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16562                    } catch (Exception e) {
16563                        Slog.w(TAG, "Failed setting process group of " + app.pid
16564                                + " to " + app.curSchedGroup);
16565                        e.printStackTrace();
16566                    } finally {
16567                        Binder.restoreCallingIdentity(oldId);
16568                    }
16569                } else {
16570                    if (app.thread != null) {
16571                        try {
16572                            app.thread.setSchedulingGroup(app.curSchedGroup);
16573                        } catch (RemoteException e) {
16574                        }
16575                    }
16576                }
16577                Process.setSwappiness(app.pid,
16578                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16579            }
16580        }
16581        if (app.repForegroundActivities != app.foregroundActivities) {
16582            app.repForegroundActivities = app.foregroundActivities;
16583            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16584        }
16585        if (app.repProcState != app.curProcState) {
16586            app.repProcState = app.curProcState;
16587            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16588            if (app.thread != null) {
16589                try {
16590                    if (false) {
16591                        //RuntimeException h = new RuntimeException("here");
16592                        Slog.i(TAG, "Sending new process state " + app.repProcState
16593                                + " to " + app /*, h*/);
16594                    }
16595                    app.thread.setProcessState(app.repProcState);
16596                } catch (RemoteException e) {
16597                }
16598            }
16599        }
16600        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16601                app.setProcState)) {
16602            app.lastStateTime = now;
16603            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16604                    isSleeping(), now);
16605            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16606                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16607                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16608                    + (app.nextPssTime-now) + ": " + app);
16609        } else {
16610            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16611                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16612                requestPssLocked(app, app.setProcState);
16613                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16614                        isSleeping(), now);
16615            } else if (false && DEBUG_PSS) {
16616                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16617            }
16618        }
16619        if (app.setProcState != app.curProcState) {
16620            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16621                    "Proc state change of " + app.processName
16622                    + " to " + app.curProcState);
16623            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16624            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16625            if (setImportant && !curImportant) {
16626                // This app is no longer something we consider important enough to allow to
16627                // use arbitrary amounts of battery power.  Note
16628                // its current wake lock time to later know to kill it if
16629                // it is not behaving well.
16630                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16631                synchronized (stats) {
16632                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16633                            app.pid, SystemClock.elapsedRealtime());
16634                }
16635                app.lastCpuTime = app.curCpuTime;
16636
16637            }
16638            app.setProcState = app.curProcState;
16639            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16640                app.notCachedSinceIdle = false;
16641            }
16642            if (!doingAll) {
16643                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16644            } else {
16645                app.procStateChanged = true;
16646            }
16647        }
16648
16649        if (changes != 0) {
16650            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16651            int i = mPendingProcessChanges.size()-1;
16652            ProcessChangeItem item = null;
16653            while (i >= 0) {
16654                item = mPendingProcessChanges.get(i);
16655                if (item.pid == app.pid) {
16656                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16657                    break;
16658                }
16659                i--;
16660            }
16661            if (i < 0) {
16662                // No existing item in pending changes; need a new one.
16663                final int NA = mAvailProcessChanges.size();
16664                if (NA > 0) {
16665                    item = mAvailProcessChanges.remove(NA-1);
16666                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16667                } else {
16668                    item = new ProcessChangeItem();
16669                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16670                }
16671                item.changes = 0;
16672                item.pid = app.pid;
16673                item.uid = app.info.uid;
16674                if (mPendingProcessChanges.size() == 0) {
16675                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16676                            "*** Enqueueing dispatch processes changed!");
16677                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16678                }
16679                mPendingProcessChanges.add(item);
16680            }
16681            item.changes |= changes;
16682            item.processState = app.repProcState;
16683            item.foregroundActivities = app.repForegroundActivities;
16684            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16685                    + Integer.toHexString(System.identityHashCode(item))
16686                    + " " + app.toShortString() + ": changes=" + item.changes
16687                    + " procState=" + item.processState
16688                    + " foreground=" + item.foregroundActivities
16689                    + " type=" + app.adjType + " source=" + app.adjSource
16690                    + " target=" + app.adjTarget);
16691        }
16692
16693        return success;
16694    }
16695
16696    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16697        if (proc.thread != null) {
16698            if (proc.baseProcessTracker != null) {
16699                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16700            }
16701            if (proc.repProcState >= 0) {
16702                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16703                        proc.repProcState);
16704            }
16705        }
16706    }
16707
16708    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16709            ProcessRecord TOP_APP, boolean doingAll, long now) {
16710        if (app.thread == null) {
16711            return false;
16712        }
16713
16714        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16715
16716        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16717    }
16718
16719    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16720            boolean oomAdj) {
16721        if (isForeground != proc.foregroundServices) {
16722            proc.foregroundServices = isForeground;
16723            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16724                    proc.info.uid);
16725            if (isForeground) {
16726                if (curProcs == null) {
16727                    curProcs = new ArrayList<ProcessRecord>();
16728                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16729                }
16730                if (!curProcs.contains(proc)) {
16731                    curProcs.add(proc);
16732                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16733                            proc.info.packageName, proc.info.uid);
16734                }
16735            } else {
16736                if (curProcs != null) {
16737                    if (curProcs.remove(proc)) {
16738                        mBatteryStatsService.noteEvent(
16739                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16740                                proc.info.packageName, proc.info.uid);
16741                        if (curProcs.size() <= 0) {
16742                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16743                        }
16744                    }
16745                }
16746            }
16747            if (oomAdj) {
16748                updateOomAdjLocked();
16749            }
16750        }
16751    }
16752
16753    private final ActivityRecord resumedAppLocked() {
16754        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16755        String pkg;
16756        int uid;
16757        if (act != null) {
16758            pkg = act.packageName;
16759            uid = act.info.applicationInfo.uid;
16760        } else {
16761            pkg = null;
16762            uid = -1;
16763        }
16764        // Has the UID or resumed package name changed?
16765        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16766                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16767            if (mCurResumedPackage != null) {
16768                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16769                        mCurResumedPackage, mCurResumedUid);
16770            }
16771            mCurResumedPackage = pkg;
16772            mCurResumedUid = uid;
16773            if (mCurResumedPackage != null) {
16774                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16775                        mCurResumedPackage, mCurResumedUid);
16776            }
16777        }
16778        return act;
16779    }
16780
16781    final boolean updateOomAdjLocked(ProcessRecord app) {
16782        final ActivityRecord TOP_ACT = resumedAppLocked();
16783        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16784        final boolean wasCached = app.cached;
16785
16786        mAdjSeq++;
16787
16788        // This is the desired cached adjusment we want to tell it to use.
16789        // If our app is currently cached, we know it, and that is it.  Otherwise,
16790        // we don't know it yet, and it needs to now be cached we will then
16791        // need to do a complete oom adj.
16792        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16793                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16794        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16795                SystemClock.uptimeMillis());
16796        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16797            // Changed to/from cached state, so apps after it in the LRU
16798            // list may also be changed.
16799            updateOomAdjLocked();
16800        }
16801        return success;
16802    }
16803
16804    final void updateOomAdjLocked() {
16805        final ActivityRecord TOP_ACT = resumedAppLocked();
16806        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16807        final long now = SystemClock.uptimeMillis();
16808        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16809        final int N = mLruProcesses.size();
16810
16811        if (false) {
16812            RuntimeException e = new RuntimeException();
16813            e.fillInStackTrace();
16814            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16815        }
16816
16817        mAdjSeq++;
16818        mNewNumServiceProcs = 0;
16819        mNewNumAServiceProcs = 0;
16820
16821        final int emptyProcessLimit;
16822        final int cachedProcessLimit;
16823        if (mProcessLimit <= 0) {
16824            emptyProcessLimit = cachedProcessLimit = 0;
16825        } else if (mProcessLimit == 1) {
16826            emptyProcessLimit = 1;
16827            cachedProcessLimit = 0;
16828        } else {
16829            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16830            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16831        }
16832
16833        // Let's determine how many processes we have running vs.
16834        // how many slots we have for background processes; we may want
16835        // to put multiple processes in a slot of there are enough of
16836        // them.
16837        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16838                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16839        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16840        if (numEmptyProcs > cachedProcessLimit) {
16841            // If there are more empty processes than our limit on cached
16842            // processes, then use the cached process limit for the factor.
16843            // This ensures that the really old empty processes get pushed
16844            // down to the bottom, so if we are running low on memory we will
16845            // have a better chance at keeping around more cached processes
16846            // instead of a gazillion empty processes.
16847            numEmptyProcs = cachedProcessLimit;
16848        }
16849        int emptyFactor = numEmptyProcs/numSlots;
16850        if (emptyFactor < 1) emptyFactor = 1;
16851        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16852        if (cachedFactor < 1) cachedFactor = 1;
16853        int stepCached = 0;
16854        int stepEmpty = 0;
16855        int numCached = 0;
16856        int numEmpty = 0;
16857        int numTrimming = 0;
16858
16859        mNumNonCachedProcs = 0;
16860        mNumCachedHiddenProcs = 0;
16861
16862        // First update the OOM adjustment for each of the
16863        // application processes based on their current state.
16864        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16865        int nextCachedAdj = curCachedAdj+1;
16866        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16867        int nextEmptyAdj = curEmptyAdj+2;
16868        for (int i=N-1; i>=0; i--) {
16869            ProcessRecord app = mLruProcesses.get(i);
16870            if (!app.killedByAm && app.thread != null) {
16871                app.procStateChanged = false;
16872                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16873
16874                // If we haven't yet assigned the final cached adj
16875                // to the process, do that now.
16876                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16877                    switch (app.curProcState) {
16878                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16879                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16880                            // This process is a cached process holding activities...
16881                            // assign it the next cached value for that type, and then
16882                            // step that cached level.
16883                            app.curRawAdj = curCachedAdj;
16884                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16885                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16886                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16887                                    + ")");
16888                            if (curCachedAdj != nextCachedAdj) {
16889                                stepCached++;
16890                                if (stepCached >= cachedFactor) {
16891                                    stepCached = 0;
16892                                    curCachedAdj = nextCachedAdj;
16893                                    nextCachedAdj += 2;
16894                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16895                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16896                                    }
16897                                }
16898                            }
16899                            break;
16900                        default:
16901                            // For everything else, assign next empty cached process
16902                            // level and bump that up.  Note that this means that
16903                            // long-running services that have dropped down to the
16904                            // cached level will be treated as empty (since their process
16905                            // state is still as a service), which is what we want.
16906                            app.curRawAdj = curEmptyAdj;
16907                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16908                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16909                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16910                                    + ")");
16911                            if (curEmptyAdj != nextEmptyAdj) {
16912                                stepEmpty++;
16913                                if (stepEmpty >= emptyFactor) {
16914                                    stepEmpty = 0;
16915                                    curEmptyAdj = nextEmptyAdj;
16916                                    nextEmptyAdj += 2;
16917                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16918                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16919                                    }
16920                                }
16921                            }
16922                            break;
16923                    }
16924                }
16925
16926                applyOomAdjLocked(app, TOP_APP, true, now);
16927
16928                // Count the number of process types.
16929                switch (app.curProcState) {
16930                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16931                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16932                        mNumCachedHiddenProcs++;
16933                        numCached++;
16934                        if (numCached > cachedProcessLimit) {
16935                            killUnneededProcessLocked(app, "cached #" + numCached);
16936                        }
16937                        break;
16938                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16939                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16940                                && app.lastActivityTime < oldTime) {
16941                            killUnneededProcessLocked(app, "empty for "
16942                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16943                                    / 1000) + "s");
16944                        } else {
16945                            numEmpty++;
16946                            if (numEmpty > emptyProcessLimit) {
16947                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16948                            }
16949                        }
16950                        break;
16951                    default:
16952                        mNumNonCachedProcs++;
16953                        break;
16954                }
16955
16956                if (app.isolated && app.services.size() <= 0) {
16957                    // If this is an isolated process, and there are no
16958                    // services running in it, then the process is no longer
16959                    // needed.  We agressively kill these because we can by
16960                    // definition not re-use the same process again, and it is
16961                    // good to avoid having whatever code was running in them
16962                    // left sitting around after no longer needed.
16963                    killUnneededProcessLocked(app, "isolated not needed");
16964                }
16965
16966                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16967                        && !app.killedByAm) {
16968                    numTrimming++;
16969                }
16970            }
16971        }
16972
16973        mNumServiceProcs = mNewNumServiceProcs;
16974
16975        // Now determine the memory trimming level of background processes.
16976        // Unfortunately we need to start at the back of the list to do this
16977        // properly.  We only do this if the number of background apps we
16978        // are managing to keep around is less than half the maximum we desire;
16979        // if we are keeping a good number around, we'll let them use whatever
16980        // memory they want.
16981        final int numCachedAndEmpty = numCached + numEmpty;
16982        int memFactor;
16983        if (numCached <= ProcessList.TRIM_CACHED_APPS
16984                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16985            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16986                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16987            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16988                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16989            } else {
16990                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16991            }
16992        } else {
16993            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16994        }
16995        // We always allow the memory level to go up (better).  We only allow it to go
16996        // down if we are in a state where that is allowed, *and* the total number of processes
16997        // has gone down since last time.
16998        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16999                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17000                + " last=" + mLastNumProcesses);
17001        if (memFactor > mLastMemoryLevel) {
17002            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17003                memFactor = mLastMemoryLevel;
17004                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17005            }
17006        }
17007        mLastMemoryLevel = memFactor;
17008        mLastNumProcesses = mLruProcesses.size();
17009        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17010        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17011        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17012            if (mLowRamStartTime == 0) {
17013                mLowRamStartTime = now;
17014            }
17015            int step = 0;
17016            int fgTrimLevel;
17017            switch (memFactor) {
17018                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17019                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17020                    break;
17021                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17022                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17023                    break;
17024                default:
17025                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17026                    break;
17027            }
17028            int factor = numTrimming/3;
17029            int minFactor = 2;
17030            if (mHomeProcess != null) minFactor++;
17031            if (mPreviousProcess != null) minFactor++;
17032            if (factor < minFactor) factor = minFactor;
17033            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17034            for (int i=N-1; i>=0; i--) {
17035                ProcessRecord app = mLruProcesses.get(i);
17036                if (allChanged || app.procStateChanged) {
17037                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17038                    app.procStateChanged = false;
17039                }
17040                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17041                        && !app.killedByAm) {
17042                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17043                        try {
17044                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17045                                    "Trimming memory of " + app.processName
17046                                    + " to " + curLevel);
17047                            app.thread.scheduleTrimMemory(curLevel);
17048                        } catch (RemoteException e) {
17049                        }
17050                        if (false) {
17051                            // For now we won't do this; our memory trimming seems
17052                            // to be good enough at this point that destroying
17053                            // activities causes more harm than good.
17054                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17055                                    && app != mHomeProcess && app != mPreviousProcess) {
17056                                // Need to do this on its own message because the stack may not
17057                                // be in a consistent state at this point.
17058                                // For these apps we will also finish their activities
17059                                // to help them free memory.
17060                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17061                            }
17062                        }
17063                    }
17064                    app.trimMemoryLevel = curLevel;
17065                    step++;
17066                    if (step >= factor) {
17067                        step = 0;
17068                        switch (curLevel) {
17069                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17070                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17071                                break;
17072                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17073                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17074                                break;
17075                        }
17076                    }
17077                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17078                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17079                            && app.thread != null) {
17080                        try {
17081                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17082                                    "Trimming memory of heavy-weight " + app.processName
17083                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17084                            app.thread.scheduleTrimMemory(
17085                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17086                        } catch (RemoteException e) {
17087                        }
17088                    }
17089                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17090                } else {
17091                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17092                            || app.systemNoUi) && app.pendingUiClean) {
17093                        // If this application is now in the background and it
17094                        // had done UI, then give it the special trim level to
17095                        // have it free UI resources.
17096                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17097                        if (app.trimMemoryLevel < level && app.thread != null) {
17098                            try {
17099                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17100                                        "Trimming memory of bg-ui " + app.processName
17101                                        + " to " + level);
17102                                app.thread.scheduleTrimMemory(level);
17103                            } catch (RemoteException e) {
17104                            }
17105                        }
17106                        app.pendingUiClean = false;
17107                    }
17108                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17109                        try {
17110                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17111                                    "Trimming memory of fg " + app.processName
17112                                    + " to " + fgTrimLevel);
17113                            app.thread.scheduleTrimMemory(fgTrimLevel);
17114                        } catch (RemoteException e) {
17115                        }
17116                    }
17117                    app.trimMemoryLevel = fgTrimLevel;
17118                }
17119            }
17120        } else {
17121            if (mLowRamStartTime != 0) {
17122                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17123                mLowRamStartTime = 0;
17124            }
17125            for (int i=N-1; i>=0; i--) {
17126                ProcessRecord app = mLruProcesses.get(i);
17127                if (allChanged || app.procStateChanged) {
17128                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17129                    app.procStateChanged = false;
17130                }
17131                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17132                        || app.systemNoUi) && app.pendingUiClean) {
17133                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17134                            && app.thread != null) {
17135                        try {
17136                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17137                                    "Trimming memory of ui hidden " + app.processName
17138                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17139                            app.thread.scheduleTrimMemory(
17140                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17141                        } catch (RemoteException e) {
17142                        }
17143                    }
17144                    app.pendingUiClean = false;
17145                }
17146                app.trimMemoryLevel = 0;
17147            }
17148        }
17149
17150        if (mAlwaysFinishActivities) {
17151            // Need to do this on its own message because the stack may not
17152            // be in a consistent state at this point.
17153            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17154        }
17155
17156        if (allChanged) {
17157            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17158        }
17159
17160        if (mProcessStats.shouldWriteNowLocked(now)) {
17161            mHandler.post(new Runnable() {
17162                @Override public void run() {
17163                    synchronized (ActivityManagerService.this) {
17164                        mProcessStats.writeStateAsyncLocked();
17165                    }
17166                }
17167            });
17168        }
17169
17170        if (DEBUG_OOM_ADJ) {
17171            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17172        }
17173    }
17174
17175    final void trimApplications() {
17176        synchronized (this) {
17177            int i;
17178
17179            // First remove any unused application processes whose package
17180            // has been removed.
17181            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17182                final ProcessRecord app = mRemovedProcesses.get(i);
17183                if (app.activities.size() == 0
17184                        && app.curReceiver == null && app.services.size() == 0) {
17185                    Slog.i(
17186                        TAG, "Exiting empty application process "
17187                        + app.processName + " ("
17188                        + (app.thread != null ? app.thread.asBinder() : null)
17189                        + ")\n");
17190                    if (app.pid > 0 && app.pid != MY_PID) {
17191                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
17192                                app.processName, app.setAdj, "empty");
17193                        app.killedByAm = true;
17194                        Process.killProcessQuiet(app.pid);
17195                        Process.killProcessGroup(app.info.uid, app.pid);
17196                    } else {
17197                        try {
17198                            app.thread.scheduleExit();
17199                        } catch (Exception e) {
17200                            // Ignore exceptions.
17201                        }
17202                    }
17203                    cleanUpApplicationRecordLocked(app, false, true, -1);
17204                    mRemovedProcesses.remove(i);
17205
17206                    if (app.persistent) {
17207                        addAppLocked(app.info, false, null /* ABI override */);
17208                    }
17209                }
17210            }
17211
17212            // Now update the oom adj for all processes.
17213            updateOomAdjLocked();
17214        }
17215    }
17216
17217    /** This method sends the specified signal to each of the persistent apps */
17218    public void signalPersistentProcesses(int sig) throws RemoteException {
17219        if (sig != Process.SIGNAL_USR1) {
17220            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17221        }
17222
17223        synchronized (this) {
17224            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17225                    != PackageManager.PERMISSION_GRANTED) {
17226                throw new SecurityException("Requires permission "
17227                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17228            }
17229
17230            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17231                ProcessRecord r = mLruProcesses.get(i);
17232                if (r.thread != null && r.persistent) {
17233                    Process.sendSignal(r.pid, sig);
17234                }
17235            }
17236        }
17237    }
17238
17239    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17240        if (proc == null || proc == mProfileProc) {
17241            proc = mProfileProc;
17242            path = mProfileFile;
17243            profileType = mProfileType;
17244            clearProfilerLocked();
17245        }
17246        if (proc == null) {
17247            return;
17248        }
17249        try {
17250            proc.thread.profilerControl(false, path, null, profileType);
17251        } catch (RemoteException e) {
17252            throw new IllegalStateException("Process disappeared");
17253        }
17254    }
17255
17256    private void clearProfilerLocked() {
17257        if (mProfileFd != null) {
17258            try {
17259                mProfileFd.close();
17260            } catch (IOException e) {
17261            }
17262        }
17263        mProfileApp = null;
17264        mProfileProc = null;
17265        mProfileFile = null;
17266        mProfileType = 0;
17267        mAutoStopProfiler = false;
17268    }
17269
17270    public boolean profileControl(String process, int userId, boolean start,
17271            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17272
17273        try {
17274            synchronized (this) {
17275                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17276                // its own permission.
17277                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17278                        != PackageManager.PERMISSION_GRANTED) {
17279                    throw new SecurityException("Requires permission "
17280                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17281                }
17282
17283                if (start && fd == null) {
17284                    throw new IllegalArgumentException("null fd");
17285                }
17286
17287                ProcessRecord proc = null;
17288                if (process != null) {
17289                    proc = findProcessLocked(process, userId, "profileControl");
17290                }
17291
17292                if (start && (proc == null || proc.thread == null)) {
17293                    throw new IllegalArgumentException("Unknown process: " + process);
17294                }
17295
17296                if (start) {
17297                    stopProfilerLocked(null, null, 0);
17298                    setProfileApp(proc.info, proc.processName, path, fd, false);
17299                    mProfileProc = proc;
17300                    mProfileType = profileType;
17301                    try {
17302                        fd = fd.dup();
17303                    } catch (IOException e) {
17304                        fd = null;
17305                    }
17306                    proc.thread.profilerControl(start, path, fd, profileType);
17307                    fd = null;
17308                    mProfileFd = null;
17309                } else {
17310                    stopProfilerLocked(proc, path, profileType);
17311                    if (fd != null) {
17312                        try {
17313                            fd.close();
17314                        } catch (IOException e) {
17315                        }
17316                    }
17317                }
17318
17319                return true;
17320            }
17321        } catch (RemoteException e) {
17322            throw new IllegalStateException("Process disappeared");
17323        } finally {
17324            if (fd != null) {
17325                try {
17326                    fd.close();
17327                } catch (IOException e) {
17328                }
17329            }
17330        }
17331    }
17332
17333    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17334        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17335                userId, true, ALLOW_FULL_ONLY, callName, null);
17336        ProcessRecord proc = null;
17337        try {
17338            int pid = Integer.parseInt(process);
17339            synchronized (mPidsSelfLocked) {
17340                proc = mPidsSelfLocked.get(pid);
17341            }
17342        } catch (NumberFormatException e) {
17343        }
17344
17345        if (proc == null) {
17346            ArrayMap<String, SparseArray<ProcessRecord>> all
17347                    = mProcessNames.getMap();
17348            SparseArray<ProcessRecord> procs = all.get(process);
17349            if (procs != null && procs.size() > 0) {
17350                proc = procs.valueAt(0);
17351                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17352                    for (int i=1; i<procs.size(); i++) {
17353                        ProcessRecord thisProc = procs.valueAt(i);
17354                        if (thisProc.userId == userId) {
17355                            proc = thisProc;
17356                            break;
17357                        }
17358                    }
17359                }
17360            }
17361        }
17362
17363        return proc;
17364    }
17365
17366    public boolean dumpHeap(String process, int userId, boolean managed,
17367            String path, ParcelFileDescriptor fd) throws RemoteException {
17368
17369        try {
17370            synchronized (this) {
17371                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17372                // its own permission (same as profileControl).
17373                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17374                        != PackageManager.PERMISSION_GRANTED) {
17375                    throw new SecurityException("Requires permission "
17376                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17377                }
17378
17379                if (fd == null) {
17380                    throw new IllegalArgumentException("null fd");
17381                }
17382
17383                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17384                if (proc == null || proc.thread == null) {
17385                    throw new IllegalArgumentException("Unknown process: " + process);
17386                }
17387
17388                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17389                if (!isDebuggable) {
17390                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17391                        throw new SecurityException("Process not debuggable: " + proc);
17392                    }
17393                }
17394
17395                proc.thread.dumpHeap(managed, path, fd);
17396                fd = null;
17397                return true;
17398            }
17399        } catch (RemoteException e) {
17400            throw new IllegalStateException("Process disappeared");
17401        } finally {
17402            if (fd != null) {
17403                try {
17404                    fd.close();
17405                } catch (IOException e) {
17406                }
17407            }
17408        }
17409    }
17410
17411    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17412    public void monitor() {
17413        synchronized (this) { }
17414    }
17415
17416    void onCoreSettingsChange(Bundle settings) {
17417        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17418            ProcessRecord processRecord = mLruProcesses.get(i);
17419            try {
17420                if (processRecord.thread != null) {
17421                    processRecord.thread.setCoreSettings(settings);
17422                }
17423            } catch (RemoteException re) {
17424                /* ignore */
17425            }
17426        }
17427    }
17428
17429    // Multi-user methods
17430
17431    /**
17432     * Start user, if its not already running, but don't bring it to foreground.
17433     */
17434    @Override
17435    public boolean startUserInBackground(final int userId) {
17436        return startUser(userId, /* foreground */ false);
17437    }
17438
17439    /**
17440     * Refreshes the list of users related to the current user when either a
17441     * user switch happens or when a new related user is started in the
17442     * background.
17443     */
17444    private void updateCurrentProfileIdsLocked() {
17445        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17446                mCurrentUserId, false /* enabledOnly */);
17447        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17448        for (int i = 0; i < currentProfileIds.length; i++) {
17449            currentProfileIds[i] = profiles.get(i).id;
17450        }
17451        mCurrentProfileIds = currentProfileIds;
17452
17453        synchronized (mUserProfileGroupIdsSelfLocked) {
17454            mUserProfileGroupIdsSelfLocked.clear();
17455            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17456            for (int i = 0; i < users.size(); i++) {
17457                UserInfo user = users.get(i);
17458                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17459                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17460                }
17461            }
17462        }
17463    }
17464
17465    private Set getProfileIdsLocked(int userId) {
17466        Set userIds = new HashSet<Integer>();
17467        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17468                userId, false /* enabledOnly */);
17469        for (UserInfo user : profiles) {
17470            userIds.add(Integer.valueOf(user.id));
17471        }
17472        return userIds;
17473    }
17474
17475    @Override
17476    public boolean switchUser(final int userId) {
17477        return startUser(userId, /* foregound */ true);
17478    }
17479
17480    private boolean startUser(final int userId, boolean foreground) {
17481        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17482                != PackageManager.PERMISSION_GRANTED) {
17483            String msg = "Permission Denial: switchUser() from pid="
17484                    + Binder.getCallingPid()
17485                    + ", uid=" + Binder.getCallingUid()
17486                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17487            Slog.w(TAG, msg);
17488            throw new SecurityException(msg);
17489        }
17490
17491        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17492
17493        final long ident = Binder.clearCallingIdentity();
17494        try {
17495            synchronized (this) {
17496                final int oldUserId = mCurrentUserId;
17497                if (oldUserId == userId) {
17498                    return true;
17499                }
17500
17501                mStackSupervisor.setLockTaskModeLocked(null, false);
17502
17503                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17504                if (userInfo == null) {
17505                    Slog.w(TAG, "No user info for user #" + userId);
17506                    return false;
17507                }
17508                if (foreground && userInfo.isManagedProfile()) {
17509                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17510                    return false;
17511                }
17512
17513                if (foreground) {
17514                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17515                            R.anim.screen_user_enter);
17516                }
17517
17518                boolean needStart = false;
17519
17520                // If the user we are switching to is not currently started, then
17521                // we need to start it now.
17522                if (mStartedUsers.get(userId) == null) {
17523                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17524                    updateStartedUserArrayLocked();
17525                    needStart = true;
17526                }
17527
17528                final Integer userIdInt = Integer.valueOf(userId);
17529                mUserLru.remove(userIdInt);
17530                mUserLru.add(userIdInt);
17531
17532                if (foreground) {
17533                    mCurrentUserId = userId;
17534                    updateCurrentProfileIdsLocked();
17535                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17536                    // Once the internal notion of the active user has switched, we lock the device
17537                    // with the option to show the user switcher on the keyguard.
17538                    mWindowManager.lockNow(null);
17539                } else {
17540                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17541                    updateCurrentProfileIdsLocked();
17542                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17543                    mUserLru.remove(currentUserIdInt);
17544                    mUserLru.add(currentUserIdInt);
17545                }
17546
17547                final UserStartedState uss = mStartedUsers.get(userId);
17548
17549                // Make sure user is in the started state.  If it is currently
17550                // stopping, we need to knock that off.
17551                if (uss.mState == UserStartedState.STATE_STOPPING) {
17552                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17553                    // so we can just fairly silently bring the user back from
17554                    // the almost-dead.
17555                    uss.mState = UserStartedState.STATE_RUNNING;
17556                    updateStartedUserArrayLocked();
17557                    needStart = true;
17558                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17559                    // This means ACTION_SHUTDOWN has been sent, so we will
17560                    // need to treat this as a new boot of the user.
17561                    uss.mState = UserStartedState.STATE_BOOTING;
17562                    updateStartedUserArrayLocked();
17563                    needStart = true;
17564                }
17565
17566                if (uss.mState == UserStartedState.STATE_BOOTING) {
17567                    // Booting up a new user, need to tell system services about it.
17568                    // Note that this is on the same handler as scheduling of broadcasts,
17569                    // which is important because it needs to go first.
17570                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17571                }
17572
17573                if (foreground) {
17574                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17575                            oldUserId));
17576                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17577                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17578                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17579                            oldUserId, userId, uss));
17580                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17581                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17582                }
17583
17584                if (needStart) {
17585                    // Send USER_STARTED broadcast
17586                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17587                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17588                            | Intent.FLAG_RECEIVER_FOREGROUND);
17589                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17590                    broadcastIntentLocked(null, null, intent,
17591                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17592                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17593                }
17594
17595                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17596                    if (userId != UserHandle.USER_OWNER) {
17597                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17598                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17599                        broadcastIntentLocked(null, null, intent, null,
17600                                new IIntentReceiver.Stub() {
17601                                    public void performReceive(Intent intent, int resultCode,
17602                                            String data, Bundle extras, boolean ordered,
17603                                            boolean sticky, int sendingUser) {
17604                                        userInitialized(uss, userId);
17605                                    }
17606                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17607                                true, false, MY_PID, Process.SYSTEM_UID,
17608                                userId);
17609                        uss.initializing = true;
17610                    } else {
17611                        getUserManagerLocked().makeInitialized(userInfo.id);
17612                    }
17613                }
17614
17615                if (foreground) {
17616                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17617                    if (homeInFront) {
17618                        startHomeActivityLocked(userId);
17619                    } else {
17620                        mStackSupervisor.resumeTopActivitiesLocked();
17621                    }
17622                    EventLogTags.writeAmSwitchUser(userId);
17623                    getUserManagerLocked().userForeground(userId);
17624                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17625                } else {
17626                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17627                }
17628
17629                if (needStart) {
17630                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17631                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17632                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17633                    broadcastIntentLocked(null, null, intent,
17634                            null, new IIntentReceiver.Stub() {
17635                                @Override
17636                                public void performReceive(Intent intent, int resultCode, String data,
17637                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17638                                        throws RemoteException {
17639                                }
17640                            }, 0, null, null,
17641                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17642                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17643                }
17644            }
17645        } finally {
17646            Binder.restoreCallingIdentity(ident);
17647        }
17648
17649        return true;
17650    }
17651
17652    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17653        long ident = Binder.clearCallingIdentity();
17654        try {
17655            Intent intent;
17656            if (oldUserId >= 0) {
17657                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17658                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17659                int count = profiles.size();
17660                for (int i = 0; i < count; i++) {
17661                    int profileUserId = profiles.get(i).id;
17662                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17663                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17664                            | Intent.FLAG_RECEIVER_FOREGROUND);
17665                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17666                    broadcastIntentLocked(null, null, intent,
17667                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17668                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17669                }
17670            }
17671            if (newUserId >= 0) {
17672                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17673                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17674                int count = profiles.size();
17675                for (int i = 0; i < count; i++) {
17676                    int profileUserId = profiles.get(i).id;
17677                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17678                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17679                            | Intent.FLAG_RECEIVER_FOREGROUND);
17680                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17681                    broadcastIntentLocked(null, null, intent,
17682                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17683                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17684                }
17685                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17686                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17687                        | Intent.FLAG_RECEIVER_FOREGROUND);
17688                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17689                broadcastIntentLocked(null, null, intent,
17690                        null, null, 0, null, null,
17691                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17692                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17693            }
17694        } finally {
17695            Binder.restoreCallingIdentity(ident);
17696        }
17697    }
17698
17699    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17700            final int newUserId) {
17701        final int N = mUserSwitchObservers.beginBroadcast();
17702        if (N > 0) {
17703            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17704                int mCount = 0;
17705                @Override
17706                public void sendResult(Bundle data) throws RemoteException {
17707                    synchronized (ActivityManagerService.this) {
17708                        if (mCurUserSwitchCallback == this) {
17709                            mCount++;
17710                            if (mCount == N) {
17711                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17712                            }
17713                        }
17714                    }
17715                }
17716            };
17717            synchronized (this) {
17718                uss.switching = true;
17719                mCurUserSwitchCallback = callback;
17720            }
17721            for (int i=0; i<N; i++) {
17722                try {
17723                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17724                            newUserId, callback);
17725                } catch (RemoteException e) {
17726                }
17727            }
17728        } else {
17729            synchronized (this) {
17730                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17731            }
17732        }
17733        mUserSwitchObservers.finishBroadcast();
17734    }
17735
17736    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17737        synchronized (this) {
17738            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17739            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17740        }
17741    }
17742
17743    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17744        mCurUserSwitchCallback = null;
17745        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17746        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17747                oldUserId, newUserId, uss));
17748    }
17749
17750    void userInitialized(UserStartedState uss, int newUserId) {
17751        completeSwitchAndInitalize(uss, newUserId, true, false);
17752    }
17753
17754    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17755        completeSwitchAndInitalize(uss, newUserId, false, true);
17756    }
17757
17758    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17759            boolean clearInitializing, boolean clearSwitching) {
17760        boolean unfrozen = false;
17761        synchronized (this) {
17762            if (clearInitializing) {
17763                uss.initializing = false;
17764                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17765            }
17766            if (clearSwitching) {
17767                uss.switching = false;
17768            }
17769            if (!uss.switching && !uss.initializing) {
17770                mWindowManager.stopFreezingScreen();
17771                unfrozen = true;
17772            }
17773        }
17774        if (unfrozen) {
17775            final int N = mUserSwitchObservers.beginBroadcast();
17776            for (int i=0; i<N; i++) {
17777                try {
17778                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17779                } catch (RemoteException e) {
17780                }
17781            }
17782            mUserSwitchObservers.finishBroadcast();
17783        }
17784    }
17785
17786    void scheduleStartProfilesLocked() {
17787        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17788            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17789                    DateUtils.SECOND_IN_MILLIS);
17790        }
17791    }
17792
17793    void startProfilesLocked() {
17794        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17795        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17796                mCurrentUserId, false /* enabledOnly */);
17797        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17798        for (UserInfo user : profiles) {
17799            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17800                    && user.id != mCurrentUserId) {
17801                toStart.add(user);
17802            }
17803        }
17804        final int n = toStart.size();
17805        int i = 0;
17806        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17807            startUserInBackground(toStart.get(i).id);
17808        }
17809        if (i < n) {
17810            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17811        }
17812    }
17813
17814    void finishUserBoot(UserStartedState uss) {
17815        synchronized (this) {
17816            if (uss.mState == UserStartedState.STATE_BOOTING
17817                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17818                uss.mState = UserStartedState.STATE_RUNNING;
17819                final int userId = uss.mHandle.getIdentifier();
17820                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17821                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17822                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17823                broadcastIntentLocked(null, null, intent,
17824                        null, null, 0, null, null,
17825                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17826                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17827            }
17828        }
17829    }
17830
17831    void finishUserSwitch(UserStartedState uss) {
17832        synchronized (this) {
17833            finishUserBoot(uss);
17834
17835            startProfilesLocked();
17836
17837            int num = mUserLru.size();
17838            int i = 0;
17839            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17840                Integer oldUserId = mUserLru.get(i);
17841                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17842                if (oldUss == null) {
17843                    // Shouldn't happen, but be sane if it does.
17844                    mUserLru.remove(i);
17845                    num--;
17846                    continue;
17847                }
17848                if (oldUss.mState == UserStartedState.STATE_STOPPING
17849                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17850                    // This user is already stopping, doesn't count.
17851                    num--;
17852                    i++;
17853                    continue;
17854                }
17855                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17856                    // Owner and current can't be stopped, but count as running.
17857                    i++;
17858                    continue;
17859                }
17860                // This is a user to be stopped.
17861                stopUserLocked(oldUserId, null);
17862                num--;
17863                i++;
17864            }
17865        }
17866    }
17867
17868    @Override
17869    public int stopUser(final int userId, final IStopUserCallback callback) {
17870        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17871                != PackageManager.PERMISSION_GRANTED) {
17872            String msg = "Permission Denial: switchUser() from pid="
17873                    + Binder.getCallingPid()
17874                    + ", uid=" + Binder.getCallingUid()
17875                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17876            Slog.w(TAG, msg);
17877            throw new SecurityException(msg);
17878        }
17879        if (userId <= 0) {
17880            throw new IllegalArgumentException("Can't stop primary user " + userId);
17881        }
17882        synchronized (this) {
17883            return stopUserLocked(userId, callback);
17884        }
17885    }
17886
17887    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17888        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17889        if (mCurrentUserId == userId) {
17890            return ActivityManager.USER_OP_IS_CURRENT;
17891        }
17892
17893        final UserStartedState uss = mStartedUsers.get(userId);
17894        if (uss == null) {
17895            // User is not started, nothing to do...  but we do need to
17896            // callback if requested.
17897            if (callback != null) {
17898                mHandler.post(new Runnable() {
17899                    @Override
17900                    public void run() {
17901                        try {
17902                            callback.userStopped(userId);
17903                        } catch (RemoteException e) {
17904                        }
17905                    }
17906                });
17907            }
17908            return ActivityManager.USER_OP_SUCCESS;
17909        }
17910
17911        if (callback != null) {
17912            uss.mStopCallbacks.add(callback);
17913        }
17914
17915        if (uss.mState != UserStartedState.STATE_STOPPING
17916                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17917            uss.mState = UserStartedState.STATE_STOPPING;
17918            updateStartedUserArrayLocked();
17919
17920            long ident = Binder.clearCallingIdentity();
17921            try {
17922                // We are going to broadcast ACTION_USER_STOPPING and then
17923                // once that is done send a final ACTION_SHUTDOWN and then
17924                // stop the user.
17925                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17926                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17927                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17928                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17929                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17930                // This is the result receiver for the final shutdown broadcast.
17931                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17932                    @Override
17933                    public void performReceive(Intent intent, int resultCode, String data,
17934                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17935                        finishUserStop(uss);
17936                    }
17937                };
17938                // This is the result receiver for the initial stopping broadcast.
17939                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17940                    @Override
17941                    public void performReceive(Intent intent, int resultCode, String data,
17942                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17943                        // On to the next.
17944                        synchronized (ActivityManagerService.this) {
17945                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17946                                // Whoops, we are being started back up.  Abort, abort!
17947                                return;
17948                            }
17949                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17950                        }
17951                        mBatteryStatsService.noteEvent(
17952                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17953                                Integer.toString(userId), userId);
17954                        mSystemServiceManager.stopUser(userId);
17955                        broadcastIntentLocked(null, null, shutdownIntent,
17956                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17957                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17958                    }
17959                };
17960                // Kick things off.
17961                broadcastIntentLocked(null, null, stoppingIntent,
17962                        null, stoppingReceiver, 0, null, null,
17963                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17964                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17965            } finally {
17966                Binder.restoreCallingIdentity(ident);
17967            }
17968        }
17969
17970        return ActivityManager.USER_OP_SUCCESS;
17971    }
17972
17973    void finishUserStop(UserStartedState uss) {
17974        final int userId = uss.mHandle.getIdentifier();
17975        boolean stopped;
17976        ArrayList<IStopUserCallback> callbacks;
17977        synchronized (this) {
17978            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17979            if (mStartedUsers.get(userId) != uss) {
17980                stopped = false;
17981            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17982                stopped = false;
17983            } else {
17984                stopped = true;
17985                // User can no longer run.
17986                mStartedUsers.remove(userId);
17987                mUserLru.remove(Integer.valueOf(userId));
17988                updateStartedUserArrayLocked();
17989
17990                // Clean up all state and processes associated with the user.
17991                // Kill all the processes for the user.
17992                forceStopUserLocked(userId, "finish user");
17993            }
17994
17995            // Explicitly remove the old information in mRecentTasks.
17996            removeRecentTasksForUserLocked(userId);
17997        }
17998
17999        for (int i=0; i<callbacks.size(); i++) {
18000            try {
18001                if (stopped) callbacks.get(i).userStopped(userId);
18002                else callbacks.get(i).userStopAborted(userId);
18003            } catch (RemoteException e) {
18004            }
18005        }
18006
18007        if (stopped) {
18008            mSystemServiceManager.cleanupUser(userId);
18009            synchronized (this) {
18010                mStackSupervisor.removeUserLocked(userId);
18011            }
18012        }
18013    }
18014
18015    @Override
18016    public UserInfo getCurrentUser() {
18017        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18018                != PackageManager.PERMISSION_GRANTED) && (
18019                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18020                != PackageManager.PERMISSION_GRANTED)) {
18021            String msg = "Permission Denial: getCurrentUser() from pid="
18022                    + Binder.getCallingPid()
18023                    + ", uid=" + Binder.getCallingUid()
18024                    + " requires " + INTERACT_ACROSS_USERS;
18025            Slog.w(TAG, msg);
18026            throw new SecurityException(msg);
18027        }
18028        synchronized (this) {
18029            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18030        }
18031    }
18032
18033    int getCurrentUserIdLocked() {
18034        return mCurrentUserId;
18035    }
18036
18037    @Override
18038    public boolean isUserRunning(int userId, boolean orStopped) {
18039        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18040                != PackageManager.PERMISSION_GRANTED) {
18041            String msg = "Permission Denial: isUserRunning() from pid="
18042                    + Binder.getCallingPid()
18043                    + ", uid=" + Binder.getCallingUid()
18044                    + " requires " + INTERACT_ACROSS_USERS;
18045            Slog.w(TAG, msg);
18046            throw new SecurityException(msg);
18047        }
18048        synchronized (this) {
18049            return isUserRunningLocked(userId, orStopped);
18050        }
18051    }
18052
18053    boolean isUserRunningLocked(int userId, boolean orStopped) {
18054        UserStartedState state = mStartedUsers.get(userId);
18055        if (state == null) {
18056            return false;
18057        }
18058        if (orStopped) {
18059            return true;
18060        }
18061        return state.mState != UserStartedState.STATE_STOPPING
18062                && state.mState != UserStartedState.STATE_SHUTDOWN;
18063    }
18064
18065    @Override
18066    public int[] getRunningUserIds() {
18067        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18068                != PackageManager.PERMISSION_GRANTED) {
18069            String msg = "Permission Denial: isUserRunning() from pid="
18070                    + Binder.getCallingPid()
18071                    + ", uid=" + Binder.getCallingUid()
18072                    + " requires " + INTERACT_ACROSS_USERS;
18073            Slog.w(TAG, msg);
18074            throw new SecurityException(msg);
18075        }
18076        synchronized (this) {
18077            return mStartedUserArray;
18078        }
18079    }
18080
18081    private void updateStartedUserArrayLocked() {
18082        int num = 0;
18083        for (int i=0; i<mStartedUsers.size();  i++) {
18084            UserStartedState uss = mStartedUsers.valueAt(i);
18085            // This list does not include stopping users.
18086            if (uss.mState != UserStartedState.STATE_STOPPING
18087                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18088                num++;
18089            }
18090        }
18091        mStartedUserArray = new int[num];
18092        num = 0;
18093        for (int i=0; i<mStartedUsers.size();  i++) {
18094            UserStartedState uss = mStartedUsers.valueAt(i);
18095            if (uss.mState != UserStartedState.STATE_STOPPING
18096                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18097                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18098                num++;
18099            }
18100        }
18101    }
18102
18103    @Override
18104    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18105        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18106                != PackageManager.PERMISSION_GRANTED) {
18107            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18108                    + Binder.getCallingPid()
18109                    + ", uid=" + Binder.getCallingUid()
18110                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18111            Slog.w(TAG, msg);
18112            throw new SecurityException(msg);
18113        }
18114
18115        mUserSwitchObservers.register(observer);
18116    }
18117
18118    @Override
18119    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18120        mUserSwitchObservers.unregister(observer);
18121    }
18122
18123    private boolean userExists(int userId) {
18124        if (userId == 0) {
18125            return true;
18126        }
18127        UserManagerService ums = getUserManagerLocked();
18128        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18129    }
18130
18131    int[] getUsersLocked() {
18132        UserManagerService ums = getUserManagerLocked();
18133        return ums != null ? ums.getUserIds() : new int[] { 0 };
18134    }
18135
18136    UserManagerService getUserManagerLocked() {
18137        if (mUserManager == null) {
18138            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18139            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18140        }
18141        return mUserManager;
18142    }
18143
18144    private int applyUserId(int uid, int userId) {
18145        return UserHandle.getUid(userId, uid);
18146    }
18147
18148    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18149        if (info == null) return null;
18150        ApplicationInfo newInfo = new ApplicationInfo(info);
18151        newInfo.uid = applyUserId(info.uid, userId);
18152        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18153                + info.packageName;
18154        return newInfo;
18155    }
18156
18157    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18158        if (aInfo == null
18159                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18160            return aInfo;
18161        }
18162
18163        ActivityInfo info = new ActivityInfo(aInfo);
18164        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18165        return info;
18166    }
18167
18168    private final class LocalService extends ActivityManagerInternal {
18169        @Override
18170        public void goingToSleep() {
18171            ActivityManagerService.this.goingToSleep();
18172        }
18173
18174        @Override
18175        public void wakingUp() {
18176            ActivityManagerService.this.wakingUp();
18177        }
18178
18179        @Override
18180        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18181                String processName, String abiOverride, int uid, Runnable crashHandler) {
18182            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18183                    processName, abiOverride, uid, crashHandler);
18184        }
18185    }
18186
18187    /**
18188     * An implementation of IAppTask, that allows an app to manage its own tasks via
18189     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18190     * only the process that calls getAppTasks() can call the AppTask methods.
18191     */
18192    class AppTaskImpl extends IAppTask.Stub {
18193        private int mTaskId;
18194        private int mCallingUid;
18195
18196        public AppTaskImpl(int taskId, int callingUid) {
18197            mTaskId = taskId;
18198            mCallingUid = callingUid;
18199        }
18200
18201        private void checkCaller() {
18202            if (mCallingUid != Binder.getCallingUid()) {
18203                throw new SecurityException("Caller " + mCallingUid
18204                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18205            }
18206        }
18207
18208        @Override
18209        public void finishAndRemoveTask() {
18210            checkCaller();
18211
18212            synchronized (ActivityManagerService.this) {
18213                long origId = Binder.clearCallingIdentity();
18214                try {
18215                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18216                    if (tr != null) {
18217                        // Only kill the process if we are not a new document
18218                        int flags = tr.getBaseIntent().getFlags();
18219                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18220                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18221                        removeTaskByIdLocked(mTaskId,
18222                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18223                    }
18224                } finally {
18225                    Binder.restoreCallingIdentity(origId);
18226                }
18227            }
18228        }
18229
18230        @Override
18231        public ActivityManager.RecentTaskInfo getTaskInfo() {
18232            checkCaller();
18233
18234            synchronized (ActivityManagerService.this) {
18235                long origId = Binder.clearCallingIdentity();
18236                try {
18237                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18238                    if (tr != null) {
18239                        return createRecentTaskInfoFromTaskRecord(tr);
18240                    }
18241                } finally {
18242                    Binder.restoreCallingIdentity(origId);
18243                }
18244                return null;
18245            }
18246        }
18247
18248        @Override
18249        public void setExcludeFromRecents(boolean exclude) {
18250            checkCaller();
18251
18252            synchronized (ActivityManagerService.this) {
18253                long origId = Binder.clearCallingIdentity();
18254                try {
18255                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18256                    if (tr != null) {
18257                        Intent intent = tr.getBaseIntent();
18258                        if (exclude) {
18259                            intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18260                        } else {
18261                            intent.setFlags(intent.getFlags()
18262                                    & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18263                        }
18264                    }
18265                } finally {
18266                    Binder.restoreCallingIdentity(origId);
18267                }
18268            }
18269        }
18270    }
18271}
18272