ActivityManagerService.java revision 83bb610fad994b9046acc3feeba9d9a5264fd918
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageEvents;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.content.res.Resources;
44import android.graphics.Bitmap;
45import android.graphics.Point;
46import android.graphics.Rect;
47import android.os.BatteryStats;
48import android.os.PersistableBundle;
49import android.service.voice.IVoiceInteractionSession;
50import android.util.ArrayMap;
51import android.util.ArraySet;
52import android.util.SparseIntArray;
53
54import com.android.internal.R;
55import com.android.internal.annotations.GuardedBy;
56import com.android.internal.app.IAppOpsService;
57import com.android.internal.app.IVoiceInteractor;
58import com.android.internal.app.ProcessMap;
59import com.android.internal.app.ProcessStats;
60import com.android.internal.content.PackageMonitor;
61import com.android.internal.os.BackgroundThread;
62import com.android.internal.os.BatteryStatsImpl;
63import com.android.internal.os.ProcessCpuTracker;
64import com.android.internal.os.TransferPipe;
65import com.android.internal.os.Zygote;
66import com.android.internal.util.FastPrintWriter;
67import com.android.internal.util.FastXmlSerializer;
68import com.android.internal.util.MemInfoReader;
69import com.android.internal.util.Preconditions;
70import com.android.server.AppOpsService;
71import com.android.server.AttributeCache;
72import com.android.server.IntentResolver;
73import com.android.server.LocalServices;
74import com.android.server.ServiceThread;
75import com.android.server.SystemService;
76import com.android.server.SystemServiceManager;
77import com.android.server.Watchdog;
78import com.android.server.am.ActivityStack.ActivityState;
79import com.android.server.firewall.IntentFirewall;
80import com.android.server.pm.UserManagerService;
81import com.android.server.wm.AppTransition;
82import com.android.server.wm.WindowManagerService;
83import com.google.android.collect.Lists;
84import com.google.android.collect.Maps;
85
86import libcore.io.IoUtils;
87
88import org.xmlpull.v1.XmlPullParser;
89import org.xmlpull.v1.XmlPullParserException;
90import org.xmlpull.v1.XmlSerializer;
91
92import android.app.Activity;
93import android.app.ActivityManager;
94import android.app.ActivityManager.RunningTaskInfo;
95import android.app.ActivityManager.StackInfo;
96import android.app.ActivityManagerInternal;
97import android.app.ActivityManagerNative;
98import android.app.ActivityOptions;
99import android.app.ActivityThread;
100import android.app.AlertDialog;
101import android.app.AppGlobals;
102import android.app.ApplicationErrorReport;
103import android.app.Dialog;
104import android.app.IActivityController;
105import android.app.IApplicationThread;
106import android.app.IInstrumentationWatcher;
107import android.app.INotificationManager;
108import android.app.IProcessObserver;
109import android.app.IServiceConnection;
110import android.app.IStopUserCallback;
111import android.app.IUiAutomationConnection;
112import android.app.IUserSwitchObserver;
113import android.app.Instrumentation;
114import android.app.Notification;
115import android.app.NotificationManager;
116import android.app.PendingIntent;
117import android.app.backup.IBackupManager;
118import android.content.ActivityNotFoundException;
119import android.content.BroadcastReceiver;
120import android.content.ClipData;
121import android.content.ComponentCallbacks2;
122import android.content.ComponentName;
123import android.content.ContentProvider;
124import android.content.ContentResolver;
125import android.content.Context;
126import android.content.DialogInterface;
127import android.content.IContentProvider;
128import android.content.IIntentReceiver;
129import android.content.IIntentSender;
130import android.content.Intent;
131import android.content.IntentFilter;
132import android.content.IntentSender;
133import android.content.pm.ActivityInfo;
134import android.content.pm.ApplicationInfo;
135import android.content.pm.ConfigurationInfo;
136import android.content.pm.IPackageDataObserver;
137import android.content.pm.IPackageManager;
138import android.content.pm.InstrumentationInfo;
139import android.content.pm.PackageInfo;
140import android.content.pm.PackageManager;
141import android.content.pm.ParceledListSlice;
142import android.content.pm.UserInfo;
143import android.content.pm.PackageManager.NameNotFoundException;
144import android.content.pm.PathPermission;
145import android.content.pm.ProviderInfo;
146import android.content.pm.ResolveInfo;
147import android.content.pm.ServiceInfo;
148import android.content.res.CompatibilityInfo;
149import android.content.res.Configuration;
150import android.net.Proxy;
151import android.net.ProxyInfo;
152import android.net.Uri;
153import android.os.Binder;
154import android.os.Build;
155import android.os.Bundle;
156import android.os.Debug;
157import android.os.DropBoxManager;
158import android.os.Environment;
159import android.os.FactoryTest;
160import android.os.FileObserver;
161import android.os.FileUtils;
162import android.os.Handler;
163import android.os.IBinder;
164import android.os.IPermissionController;
165import android.os.IRemoteCallback;
166import android.os.IUserManager;
167import android.os.Looper;
168import android.os.Message;
169import android.os.Parcel;
170import android.os.ParcelFileDescriptor;
171import android.os.Process;
172import android.os.RemoteCallbackList;
173import android.os.RemoteException;
174import android.os.SELinux;
175import android.os.ServiceManager;
176import android.os.StrictMode;
177import android.os.SystemClock;
178import android.os.SystemProperties;
179import android.os.UpdateLock;
180import android.os.UserHandle;
181import android.provider.Settings;
182import android.text.format.DateUtils;
183import android.text.format.Time;
184import android.util.AtomicFile;
185import android.util.EventLog;
186import android.util.Log;
187import android.util.Pair;
188import android.util.PrintWriterPrinter;
189import android.util.Slog;
190import android.util.SparseArray;
191import android.util.TimeUtils;
192import android.util.Xml;
193import android.view.Gravity;
194import android.view.LayoutInflater;
195import android.view.View;
196import android.view.WindowManager;
197
198import java.io.BufferedInputStream;
199import java.io.BufferedOutputStream;
200import java.io.DataInputStream;
201import java.io.DataOutputStream;
202import java.io.File;
203import java.io.FileDescriptor;
204import java.io.FileInputStream;
205import java.io.FileNotFoundException;
206import java.io.FileOutputStream;
207import java.io.IOException;
208import java.io.InputStreamReader;
209import java.io.PrintWriter;
210import java.io.StringWriter;
211import java.lang.ref.WeakReference;
212import java.util.ArrayList;
213import java.util.Arrays;
214import java.util.Collections;
215import java.util.Comparator;
216import java.util.HashMap;
217import java.util.HashSet;
218import java.util.Iterator;
219import java.util.List;
220import java.util.Locale;
221import java.util.Map;
222import java.util.Set;
223import java.util.concurrent.atomic.AtomicBoolean;
224import java.util.concurrent.atomic.AtomicLong;
225
226public final class ActivityManagerService extends ActivityManagerNative
227        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
228
229    private static final String USER_DATA_DIR = "/data/user/";
230    // File that stores last updated system version and called preboot receivers
231    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
232
233    static final String TAG = "ActivityManager";
234    static final String TAG_MU = "ActivityManagerServiceMU";
235    static final boolean DEBUG = false;
236    static final boolean localLOGV = DEBUG;
237    static final boolean DEBUG_BACKUP = localLOGV || false;
238    static final boolean DEBUG_BROADCAST = localLOGV || false;
239    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
240    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
241    static final boolean DEBUG_CLEANUP = localLOGV || false;
242    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
243    static final boolean DEBUG_FOCUS = false;
244    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
245    static final boolean DEBUG_MU = localLOGV || false;
246    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
247    static final boolean DEBUG_LRU = localLOGV || false;
248    static final boolean DEBUG_PAUSE = localLOGV || false;
249    static final boolean DEBUG_POWER = localLOGV || false;
250    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
251    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
252    static final boolean DEBUG_PROCESSES = localLOGV || false;
253    static final boolean DEBUG_PROVIDER = localLOGV || false;
254    static final boolean DEBUG_RESULTS = localLOGV || false;
255    static final boolean DEBUG_SERVICE = localLOGV || false;
256    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
257    static final boolean DEBUG_STACK = localLOGV || false;
258    static final boolean DEBUG_SWITCH = localLOGV || false;
259    static final boolean DEBUG_TASKS = localLOGV || false;
260    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
261    static final boolean DEBUG_TRANSITION = localLOGV || false;
262    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
263    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
264    static final boolean DEBUG_VISBILITY = localLOGV || false;
265    static final boolean DEBUG_PSS = localLOGV || false;
266    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
267    static final boolean DEBUG_RECENTS = localLOGV || false;
268    static final boolean VALIDATE_TOKENS = false;
269    static final boolean SHOW_ACTIVITY_START_TIME = true;
270
271    // Control over CPU and battery monitoring.
272    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
273    static final boolean MONITOR_CPU_USAGE = true;
274    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
275    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
276    static final boolean MONITOR_THREAD_CPU_USAGE = false;
277
278    // The flags that are set for all calls we make to the package manager.
279    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
280
281    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
282
283    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
284
285    // Maximum number of recent tasks that we can remember.
286    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
287
288    // Maximum number recent bitmaps to keep in memory.
289    static final int MAX_RECENT_BITMAPS = 5;
290
291    // Amount of time after a call to stopAppSwitches() during which we will
292    // prevent further untrusted switches from happening.
293    static final long APP_SWITCH_DELAY_TIME = 5*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real.
297    static final int PROC_START_TIMEOUT = 10*1000;
298
299    // How long we wait for a launched process to attach to the activity manager
300    // before we decide it's never going to come up for real, when the process was
301    // started with a wrapper for instrumentation (such as Valgrind) because it
302    // could take much longer than usual.
303    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
304
305    // How long to wait after going idle before forcing apps to GC.
306    static final int GC_TIMEOUT = 5*1000;
307
308    // The minimum amount of time between successive GC requests for a process.
309    static final int GC_MIN_INTERVAL = 60*1000;
310
311    // The minimum amount of time between successive PSS requests for a process.
312    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process
315    // when the request is due to the memory state being lowered.
316    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
317
318    // The rate at which we check for apps using excessive power -- 15 mins.
319    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on wake locks to start killing things.
323    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on CPU usage to start killing things.
327    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // How long we allow a receiver to run before giving up on it.
330    static final int BROADCAST_FG_TIMEOUT = 10*1000;
331    static final int BROADCAST_BG_TIMEOUT = 60*1000;
332
333    // How long we wait until we timeout on key dispatching.
334    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
335
336    // How long we wait until we timeout on key dispatching during instrumentation.
337    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
338
339    // Amount of time we wait for observers to handle a user switch before
340    // giving up on them and unfreezing the screen.
341    static final int USER_SWITCH_TIMEOUT = 2*1000;
342
343    // Maximum number of users we allow to be running at a time.
344    static final int MAX_RUNNING_USERS = 3;
345
346    // How long to wait in getAssistContextExtras for the activity and foreground services
347    // to respond with the result.
348    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
349
350    // Maximum number of persisted Uri grants a package is allowed
351    static final int MAX_PERSISTED_URI_GRANTS = 128;
352
353    static final int MY_PID = Process.myPid();
354
355    static final String[] EMPTY_STRING_ARRAY = new String[0];
356
357    // How many bytes to write into the dropbox log before truncating
358    static final int DROPBOX_MAX_SIZE = 256 * 1024;
359
360    // Access modes for handleIncomingUser.
361    static final int ALLOW_NON_FULL = 0;
362    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
363    static final int ALLOW_FULL_ONLY = 2;
364
365    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
366
367    /** All system services */
368    SystemServiceManager mSystemServiceManager;
369
370    /** Run all ActivityStacks through this */
371    ActivityStackSupervisor mStackSupervisor;
372
373    public IntentFirewall mIntentFirewall;
374
375    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
376    // default actuion automatically.  Important for devices without direct input
377    // devices.
378    private boolean mShowDialogs = true;
379
380    BroadcastQueue mFgBroadcastQueue;
381    BroadcastQueue mBgBroadcastQueue;
382    // Convenient for easy iteration over the queues. Foreground is first
383    // so that dispatch of foreground broadcasts gets precedence.
384    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
385
386    BroadcastQueue broadcastQueueForIntent(Intent intent) {
387        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
388        if (DEBUG_BACKGROUND_BROADCAST) {
389            Slog.i(TAG, "Broadcast intent " + intent + " on "
390                    + (isFg ? "foreground" : "background")
391                    + " queue");
392        }
393        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
394    }
395
396    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
397        for (BroadcastQueue queue : mBroadcastQueues) {
398            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
399            if (r != null) {
400                return r;
401            }
402        }
403        return null;
404    }
405
406    /**
407     * Activity we have told the window manager to have key focus.
408     */
409    ActivityRecord mFocusedActivity = null;
410
411    /**
412     * List of intents that were used to start the most recent tasks.
413     */
414    ArrayList<TaskRecord> mRecentTasks;
415    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
416
417    /**
418     * For addAppTask: cached of the last activity component that was added.
419     */
420    ComponentName mLastAddedTaskComponent;
421
422    /**
423     * For addAppTask: cached of the last activity uid that was added.
424     */
425    int mLastAddedTaskUid;
426
427    /**
428     * For addAppTask: cached of the last ActivityInfo that was added.
429     */
430    ActivityInfo mLastAddedTaskActivity;
431
432    public class PendingAssistExtras extends Binder implements Runnable {
433        public final ActivityRecord activity;
434        public boolean haveResult = false;
435        public Bundle result = null;
436        public PendingAssistExtras(ActivityRecord _activity) {
437            activity = _activity;
438        }
439        @Override
440        public void run() {
441            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
442            synchronized (this) {
443                haveResult = true;
444                notifyAll();
445            }
446        }
447    }
448
449    final ArrayList<PendingAssistExtras> mPendingAssistExtras
450            = new ArrayList<PendingAssistExtras>();
451
452    /**
453     * Process management.
454     */
455    final ProcessList mProcessList = new ProcessList();
456
457    /**
458     * All of the applications we currently have running organized by name.
459     * The keys are strings of the application package name (as
460     * returned by the package manager), and the keys are ApplicationRecord
461     * objects.
462     */
463    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
464
465    /**
466     * Tracking long-term execution of processes to look for abuse and other
467     * bad app behavior.
468     */
469    final ProcessStatsService mProcessStats;
470
471    /**
472     * The currently running isolated processes.
473     */
474    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
475
476    /**
477     * Counter for assigning isolated process uids, to avoid frequently reusing the
478     * same ones.
479     */
480    int mNextIsolatedProcessUid = 0;
481
482    /**
483     * The currently running heavy-weight process, if any.
484     */
485    ProcessRecord mHeavyWeightProcess = null;
486
487    /**
488     * The last time that various processes have crashed.
489     */
490    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
491
492    /**
493     * Information about a process that is currently marked as bad.
494     */
495    static final class BadProcessInfo {
496        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
497            this.time = time;
498            this.shortMsg = shortMsg;
499            this.longMsg = longMsg;
500            this.stack = stack;
501        }
502
503        final long time;
504        final String shortMsg;
505        final String longMsg;
506        final String stack;
507    }
508
509    /**
510     * Set of applications that we consider to be bad, and will reject
511     * incoming broadcasts from (which the user has no control over).
512     * Processes are added to this set when they have crashed twice within
513     * a minimum amount of time; they are removed from it when they are
514     * later restarted (hopefully due to some user action).  The value is the
515     * time it was added to the list.
516     */
517    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
518
519    /**
520     * All of the processes we currently have running organized by pid.
521     * The keys are the pid running the application.
522     *
523     * <p>NOTE: This object is protected by its own lock, NOT the global
524     * activity manager lock!
525     */
526    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
527
528    /**
529     * All of the processes that have been forced to be foreground.  The key
530     * is the pid of the caller who requested it (we hold a death
531     * link on it).
532     */
533    abstract class ForegroundToken implements IBinder.DeathRecipient {
534        int pid;
535        IBinder token;
536    }
537    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
538
539    /**
540     * List of records for processes that someone had tried to start before the
541     * system was ready.  We don't start them at that point, but ensure they
542     * are started by the time booting is complete.
543     */
544    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
545
546    /**
547     * List of persistent applications that are in the process
548     * of being started.
549     */
550    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
551
552    /**
553     * Processes that are being forcibly torn down.
554     */
555    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
556
557    /**
558     * List of running applications, sorted by recent usage.
559     * The first entry in the list is the least recently used.
560     */
561    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
562
563    /**
564     * Where in mLruProcesses that the processes hosting activities start.
565     */
566    int mLruProcessActivityStart = 0;
567
568    /**
569     * Where in mLruProcesses that the processes hosting services start.
570     * This is after (lower index) than mLruProcessesActivityStart.
571     */
572    int mLruProcessServiceStart = 0;
573
574    /**
575     * List of processes that should gc as soon as things are idle.
576     */
577    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
578
579    /**
580     * Processes we want to collect PSS data from.
581     */
582    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
583
584    /**
585     * Last time we requested PSS data of all processes.
586     */
587    long mLastFullPssTime = SystemClock.uptimeMillis();
588
589    /**
590     * If set, the next time we collect PSS data we should do a full collection
591     * with data from native processes and the kernel.
592     */
593    boolean mFullPssPending = false;
594
595    /**
596     * This is the process holding what we currently consider to be
597     * the "home" activity.
598     */
599    ProcessRecord mHomeProcess;
600
601    /**
602     * This is the process holding the activity the user last visited that
603     * is in a different process from the one they are currently in.
604     */
605    ProcessRecord mPreviousProcess;
606
607    /**
608     * The time at which the previous process was last visible.
609     */
610    long mPreviousProcessVisibleTime;
611
612    /**
613     * Which uses have been started, so are allowed to run code.
614     */
615    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
616
617    /**
618     * LRU list of history of current users.  Most recently current is at the end.
619     */
620    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
621
622    /**
623     * Constant array of the users that are currently started.
624     */
625    int[] mStartedUserArray = new int[] { 0 };
626
627    /**
628     * Registered observers of the user switching mechanics.
629     */
630    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
631            = new RemoteCallbackList<IUserSwitchObserver>();
632
633    /**
634     * Currently active user switch.
635     */
636    Object mCurUserSwitchCallback;
637
638    /**
639     * Packages that the user has asked to have run in screen size
640     * compatibility mode instead of filling the screen.
641     */
642    final CompatModePackages mCompatModePackages;
643
644    /**
645     * Set of IntentSenderRecord objects that are currently active.
646     */
647    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
648            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
649
650    /**
651     * Fingerprints (hashCode()) of stack traces that we've
652     * already logged DropBox entries for.  Guarded by itself.  If
653     * something (rogue user app) forces this over
654     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
655     */
656    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
657    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
658
659    /**
660     * Strict Mode background batched logging state.
661     *
662     * The string buffer is guarded by itself, and its lock is also
663     * used to determine if another batched write is already
664     * in-flight.
665     */
666    private final StringBuilder mStrictModeBuffer = new StringBuilder();
667
668    /**
669     * Keeps track of all IIntentReceivers that have been registered for
670     * broadcasts.  Hash keys are the receiver IBinder, hash value is
671     * a ReceiverList.
672     */
673    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
674            new HashMap<IBinder, ReceiverList>();
675
676    /**
677     * Resolver for broadcast intents to registered receivers.
678     * Holds BroadcastFilter (subclass of IntentFilter).
679     */
680    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
681            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
682        @Override
683        protected boolean allowFilterResult(
684                BroadcastFilter filter, List<BroadcastFilter> dest) {
685            IBinder target = filter.receiverList.receiver.asBinder();
686            for (int i=dest.size()-1; i>=0; i--) {
687                if (dest.get(i).receiverList.receiver.asBinder() == target) {
688                    return false;
689                }
690            }
691            return true;
692        }
693
694        @Override
695        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
696            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
697                    || userId == filter.owningUserId) {
698                return super.newResult(filter, match, userId);
699            }
700            return null;
701        }
702
703        @Override
704        protected BroadcastFilter[] newArray(int size) {
705            return new BroadcastFilter[size];
706        }
707
708        @Override
709        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
710            return packageName.equals(filter.packageName);
711        }
712    };
713
714    /**
715     * State of all active sticky broadcasts per user.  Keys are the action of the
716     * sticky Intent, values are an ArrayList of all broadcasted intents with
717     * that action (which should usually be one).  The SparseArray is keyed
718     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
719     * for stickies that are sent to all users.
720     */
721    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
722            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
723
724    final ActiveServices mServices;
725
726    /**
727     * Backup/restore process management
728     */
729    String mBackupAppName = null;
730    BackupRecord mBackupTarget = null;
731
732    final ProviderMap mProviderMap;
733
734    /**
735     * List of content providers who have clients waiting for them.  The
736     * application is currently being launched and the provider will be
737     * removed from this list once it is published.
738     */
739    final ArrayList<ContentProviderRecord> mLaunchingProviders
740            = new ArrayList<ContentProviderRecord>();
741
742    /**
743     * File storing persisted {@link #mGrantedUriPermissions}.
744     */
745    private final AtomicFile mGrantFile;
746
747    /** XML constants used in {@link #mGrantFile} */
748    private static final String TAG_URI_GRANTS = "uri-grants";
749    private static final String TAG_URI_GRANT = "uri-grant";
750    private static final String ATTR_USER_HANDLE = "userHandle";
751    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
752    private static final String ATTR_TARGET_USER_ID = "targetUserId";
753    private static final String ATTR_SOURCE_PKG = "sourcePkg";
754    private static final String ATTR_TARGET_PKG = "targetPkg";
755    private static final String ATTR_URI = "uri";
756    private static final String ATTR_MODE_FLAGS = "modeFlags";
757    private static final String ATTR_CREATED_TIME = "createdTime";
758    private static final String ATTR_PREFIX = "prefix";
759
760    /**
761     * Global set of specific {@link Uri} permissions that have been granted.
762     * This optimized lookup structure maps from {@link UriPermission#targetUid}
763     * to {@link UriPermission#uri} to {@link UriPermission}.
764     */
765    @GuardedBy("this")
766    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
767            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
768
769    public static class GrantUri {
770        public final int sourceUserId;
771        public final Uri uri;
772        public boolean prefix;
773
774        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
775            this.sourceUserId = sourceUserId;
776            this.uri = uri;
777            this.prefix = prefix;
778        }
779
780        @Override
781        public int hashCode() {
782            return toString().hashCode();
783        }
784
785        @Override
786        public boolean equals(Object o) {
787            if (o instanceof GrantUri) {
788                GrantUri other = (GrantUri) o;
789                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
790                        && prefix == other.prefix;
791            }
792            return false;
793        }
794
795        @Override
796        public String toString() {
797            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
798            if (prefix) result += " [prefix]";
799            return result;
800        }
801
802        public String toSafeString() {
803            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
804            if (prefix) result += " [prefix]";
805            return result;
806        }
807
808        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
809            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
810                    ContentProvider.getUriWithoutUserId(uri), false);
811        }
812    }
813
814    CoreSettingsObserver mCoreSettingsObserver;
815
816    /**
817     * Thread-local storage used to carry caller permissions over through
818     * indirect content-provider access.
819     */
820    private class Identity {
821        public int pid;
822        public int uid;
823
824        Identity(int _pid, int _uid) {
825            pid = _pid;
826            uid = _uid;
827        }
828    }
829
830    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
831
832    /**
833     * All information we have collected about the runtime performance of
834     * any user id that can impact battery performance.
835     */
836    final BatteryStatsService mBatteryStatsService;
837
838    /**
839     * Information about component usage
840     */
841    UsageStatsManagerInternal mUsageStatsService;
842
843    /**
844     * Information about and control over application operations
845     */
846    final AppOpsService mAppOpsService;
847
848    /**
849     * Save recent tasks information across reboots.
850     */
851    final TaskPersister mTaskPersister;
852
853    /**
854     * Current configuration information.  HistoryRecord objects are given
855     * a reference to this object to indicate which configuration they are
856     * currently running in, so this object must be kept immutable.
857     */
858    Configuration mConfiguration = new Configuration();
859
860    /**
861     * Current sequencing integer of the configuration, for skipping old
862     * configurations.
863     */
864    int mConfigurationSeq = 0;
865
866    /**
867     * Hardware-reported OpenGLES version.
868     */
869    final int GL_ES_VERSION;
870
871    /**
872     * List of initialization arguments to pass to all processes when binding applications to them.
873     * For example, references to the commonly used services.
874     */
875    HashMap<String, IBinder> mAppBindArgs;
876
877    /**
878     * Temporary to avoid allocations.  Protected by main lock.
879     */
880    final StringBuilder mStringBuilder = new StringBuilder(256);
881
882    /**
883     * Used to control how we initialize the service.
884     */
885    ComponentName mTopComponent;
886    String mTopAction = Intent.ACTION_MAIN;
887    String mTopData;
888    boolean mProcessesReady = false;
889    boolean mSystemReady = false;
890    boolean mBooting = false;
891    boolean mWaitingUpdate = false;
892    boolean mDidUpdate = false;
893    boolean mOnBattery = false;
894    boolean mLaunchWarningShown = false;
895
896    Context mContext;
897
898    int mFactoryTest;
899
900    boolean mCheckedForSetup;
901
902    /**
903     * The time at which we will allow normal application switches again,
904     * after a call to {@link #stopAppSwitches()}.
905     */
906    long mAppSwitchesAllowedTime;
907
908    /**
909     * This is set to true after the first switch after mAppSwitchesAllowedTime
910     * is set; any switches after that will clear the time.
911     */
912    boolean mDidAppSwitch;
913
914    /**
915     * Last time (in realtime) at which we checked for power usage.
916     */
917    long mLastPowerCheckRealtime;
918
919    /**
920     * Last time (in uptime) at which we checked for power usage.
921     */
922    long mLastPowerCheckUptime;
923
924    /**
925     * Set while we are wanting to sleep, to prevent any
926     * activities from being started/resumed.
927     */
928    private boolean mSleeping = false;
929
930    /**
931     * Set while we are running a voice interaction.  This overrides
932     * sleeping while it is active.
933     */
934    private boolean mRunningVoice = false;
935
936    /**
937     * State of external calls telling us if the device is asleep.
938     */
939    private boolean mWentToSleep = false;
940
941    /**
942     * State of external call telling us if the lock screen is shown.
943     */
944    private boolean mLockScreenShown = false;
945
946    /**
947     * Set if we are shutting down the system, similar to sleeping.
948     */
949    boolean mShuttingDown = false;
950
951    /**
952     * Current sequence id for oom_adj computation traversal.
953     */
954    int mAdjSeq = 0;
955
956    /**
957     * Current sequence id for process LRU updating.
958     */
959    int mLruSeq = 0;
960
961    /**
962     * Keep track of the non-cached/empty process we last found, to help
963     * determine how to distribute cached/empty processes next time.
964     */
965    int mNumNonCachedProcs = 0;
966
967    /**
968     * Keep track of the number of cached hidden procs, to balance oom adj
969     * distribution between those and empty procs.
970     */
971    int mNumCachedHiddenProcs = 0;
972
973    /**
974     * Keep track of the number of service processes we last found, to
975     * determine on the next iteration which should be B services.
976     */
977    int mNumServiceProcs = 0;
978    int mNewNumAServiceProcs = 0;
979    int mNewNumServiceProcs = 0;
980
981    /**
982     * Allow the current computed overall memory level of the system to go down?
983     * This is set to false when we are killing processes for reasons other than
984     * memory management, so that the now smaller process list will not be taken as
985     * an indication that memory is tighter.
986     */
987    boolean mAllowLowerMemLevel = false;
988
989    /**
990     * The last computed memory level, for holding when we are in a state that
991     * processes are going away for other reasons.
992     */
993    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
994
995    /**
996     * The last total number of process we have, to determine if changes actually look
997     * like a shrinking number of process due to lower RAM.
998     */
999    int mLastNumProcesses;
1000
1001    /**
1002     * The uptime of the last time we performed idle maintenance.
1003     */
1004    long mLastIdleTime = SystemClock.uptimeMillis();
1005
1006    /**
1007     * Total time spent with RAM that has been added in the past since the last idle time.
1008     */
1009    long mLowRamTimeSinceLastIdle = 0;
1010
1011    /**
1012     * If RAM is currently low, when that horrible situation started.
1013     */
1014    long mLowRamStartTime = 0;
1015
1016    /**
1017     * For reporting to battery stats the current top application.
1018     */
1019    private String mCurResumedPackage = null;
1020    private int mCurResumedUid = -1;
1021
1022    /**
1023     * For reporting to battery stats the apps currently running foreground
1024     * service.  The ProcessMap is package/uid tuples; each of these contain
1025     * an array of the currently foreground processes.
1026     */
1027    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1028            = new ProcessMap<ArrayList<ProcessRecord>>();
1029
1030    /**
1031     * This is set if we had to do a delayed dexopt of an app before launching
1032     * it, to increase the ANR timeouts in that case.
1033     */
1034    boolean mDidDexOpt;
1035
1036    /**
1037     * Set if the systemServer made a call to enterSafeMode.
1038     */
1039    boolean mSafeMode;
1040
1041    String mDebugApp = null;
1042    boolean mWaitForDebugger = false;
1043    boolean mDebugTransient = false;
1044    String mOrigDebugApp = null;
1045    boolean mOrigWaitForDebugger = false;
1046    boolean mAlwaysFinishActivities = false;
1047    IActivityController mController = null;
1048    String mProfileApp = null;
1049    ProcessRecord mProfileProc = null;
1050    String mProfileFile;
1051    ParcelFileDescriptor mProfileFd;
1052    int mProfileType = 0;
1053    boolean mAutoStopProfiler = false;
1054    String mOpenGlTraceApp = null;
1055
1056    static class ProcessChangeItem {
1057        static final int CHANGE_ACTIVITIES = 1<<0;
1058        static final int CHANGE_PROCESS_STATE = 1<<1;
1059        int changes;
1060        int uid;
1061        int pid;
1062        int processState;
1063        boolean foregroundActivities;
1064    }
1065
1066    final RemoteCallbackList<IProcessObserver> mProcessObservers
1067            = new RemoteCallbackList<IProcessObserver>();
1068    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1069
1070    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1071            = new ArrayList<ProcessChangeItem>();
1072    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1073            = new ArrayList<ProcessChangeItem>();
1074
1075    /**
1076     * Runtime CPU use collection thread.  This object's lock is used to
1077     * protect all related state.
1078     */
1079    final Thread mProcessCpuThread;
1080
1081    /**
1082     * Used to collect process stats when showing not responding dialog.
1083     * Protected by mProcessCpuThread.
1084     */
1085    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1086            MONITOR_THREAD_CPU_USAGE);
1087    final AtomicLong mLastCpuTime = new AtomicLong(0);
1088    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1089
1090    long mLastWriteTime = 0;
1091
1092    /**
1093     * Used to retain an update lock when the foreground activity is in
1094     * immersive mode.
1095     */
1096    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1097
1098    /**
1099     * Set to true after the system has finished booting.
1100     */
1101    boolean mBooted = false;
1102
1103    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1104    int mProcessLimitOverride = -1;
1105
1106    WindowManagerService mWindowManager;
1107
1108    final ActivityThread mSystemThread;
1109
1110    int mCurrentUserId = 0;
1111    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1112
1113    /**
1114     * Mapping from each known user ID to the profile group ID it is associated with.
1115     */
1116    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1117
1118    private UserManagerService mUserManager;
1119
1120    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1121        final ProcessRecord mApp;
1122        final int mPid;
1123        final IApplicationThread mAppThread;
1124
1125        AppDeathRecipient(ProcessRecord app, int pid,
1126                IApplicationThread thread) {
1127            if (localLOGV) Slog.v(
1128                TAG, "New death recipient " + this
1129                + " for thread " + thread.asBinder());
1130            mApp = app;
1131            mPid = pid;
1132            mAppThread = thread;
1133        }
1134
1135        @Override
1136        public void binderDied() {
1137            if (localLOGV) Slog.v(
1138                TAG, "Death received in " + this
1139                + " for thread " + mAppThread.asBinder());
1140            synchronized(ActivityManagerService.this) {
1141                appDiedLocked(mApp, mPid, mAppThread);
1142            }
1143        }
1144    }
1145
1146    static final int SHOW_ERROR_MSG = 1;
1147    static final int SHOW_NOT_RESPONDING_MSG = 2;
1148    static final int SHOW_FACTORY_ERROR_MSG = 3;
1149    static final int UPDATE_CONFIGURATION_MSG = 4;
1150    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1151    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1152    static final int SERVICE_TIMEOUT_MSG = 12;
1153    static final int UPDATE_TIME_ZONE = 13;
1154    static final int SHOW_UID_ERROR_MSG = 14;
1155    static final int IM_FEELING_LUCKY_MSG = 15;
1156    static final int PROC_START_TIMEOUT_MSG = 20;
1157    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1158    static final int KILL_APPLICATION_MSG = 22;
1159    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1160    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1161    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1162    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1163    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1164    static final int CLEAR_DNS_CACHE_MSG = 28;
1165    static final int UPDATE_HTTP_PROXY_MSG = 29;
1166    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1167    static final int DISPATCH_PROCESSES_CHANGED = 31;
1168    static final int DISPATCH_PROCESS_DIED = 32;
1169    static final int REPORT_MEM_USAGE_MSG = 33;
1170    static final int REPORT_USER_SWITCH_MSG = 34;
1171    static final int CONTINUE_USER_SWITCH_MSG = 35;
1172    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1173    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1174    static final int PERSIST_URI_GRANTS_MSG = 38;
1175    static final int REQUEST_ALL_PSS_MSG = 39;
1176    static final int START_PROFILES_MSG = 40;
1177    static final int UPDATE_TIME = 41;
1178    static final int SYSTEM_USER_START_MSG = 42;
1179    static final int SYSTEM_USER_CURRENT_MSG = 43;
1180    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1181    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1182    static final int START_USER_SWITCH_MSG = 46;
1183
1184    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1185    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1186    static final int FIRST_COMPAT_MODE_MSG = 300;
1187    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1188
1189    AlertDialog mUidAlert;
1190    CompatModeDialog mCompatModeDialog;
1191    long mLastMemUsageReportTime = 0;
1192
1193    private LockToAppRequestDialog mLockToAppRequest;
1194
1195    /**
1196     * Flag whether the current user is a "monkey", i.e. whether
1197     * the UI is driven by a UI automation tool.
1198     */
1199    private boolean mUserIsMonkey;
1200
1201    /** Flag whether the device has a recents UI */
1202    final boolean mHasRecents;
1203
1204    final int mThumbnailWidth;
1205    final int mThumbnailHeight;
1206
1207    final ServiceThread mHandlerThread;
1208    final MainHandler mHandler;
1209
1210    final class MainHandler extends Handler {
1211        public MainHandler(Looper looper) {
1212            super(looper, null, true);
1213        }
1214
1215        @Override
1216        public void handleMessage(Message msg) {
1217            switch (msg.what) {
1218            case SHOW_ERROR_MSG: {
1219                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1220                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1221                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1222                synchronized (ActivityManagerService.this) {
1223                    ProcessRecord proc = (ProcessRecord)data.get("app");
1224                    AppErrorResult res = (AppErrorResult) data.get("result");
1225                    if (proc != null && proc.crashDialog != null) {
1226                        Slog.e(TAG, "App already has crash dialog: " + proc);
1227                        if (res != null) {
1228                            res.set(0);
1229                        }
1230                        return;
1231                    }
1232                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1233                            >= Process.FIRST_APPLICATION_UID
1234                            && proc.pid != MY_PID);
1235                    for (int userId : mCurrentProfileIds) {
1236                        isBackground &= (proc.userId != userId);
1237                    }
1238                    if (isBackground && !showBackground) {
1239                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1240                        if (res != null) {
1241                            res.set(0);
1242                        }
1243                        return;
1244                    }
1245                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1246                        Dialog d = new AppErrorDialog(mContext,
1247                                ActivityManagerService.this, res, proc);
1248                        d.show();
1249                        proc.crashDialog = d;
1250                    } else {
1251                        // The device is asleep, so just pretend that the user
1252                        // saw a crash dialog and hit "force quit".
1253                        if (res != null) {
1254                            res.set(0);
1255                        }
1256                    }
1257                }
1258
1259                ensureBootCompleted();
1260            } break;
1261            case SHOW_NOT_RESPONDING_MSG: {
1262                synchronized (ActivityManagerService.this) {
1263                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1264                    ProcessRecord proc = (ProcessRecord)data.get("app");
1265                    if (proc != null && proc.anrDialog != null) {
1266                        Slog.e(TAG, "App already has anr dialog: " + proc);
1267                        return;
1268                    }
1269
1270                    Intent intent = new Intent("android.intent.action.ANR");
1271                    if (!mProcessesReady) {
1272                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1273                                | Intent.FLAG_RECEIVER_FOREGROUND);
1274                    }
1275                    broadcastIntentLocked(null, null, intent,
1276                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1277                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1278
1279                    if (mShowDialogs) {
1280                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1281                                mContext, proc, (ActivityRecord)data.get("activity"),
1282                                msg.arg1 != 0);
1283                        d.show();
1284                        proc.anrDialog = d;
1285                    } else {
1286                        // Just kill the app if there is no dialog to be shown.
1287                        killAppAtUsersRequest(proc, null);
1288                    }
1289                }
1290
1291                ensureBootCompleted();
1292            } break;
1293            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1294                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1295                synchronized (ActivityManagerService.this) {
1296                    ProcessRecord proc = (ProcessRecord) data.get("app");
1297                    if (proc == null) {
1298                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1299                        break;
1300                    }
1301                    if (proc.crashDialog != null) {
1302                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1303                        return;
1304                    }
1305                    AppErrorResult res = (AppErrorResult) data.get("result");
1306                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1307                        Dialog d = new StrictModeViolationDialog(mContext,
1308                                ActivityManagerService.this, res, proc);
1309                        d.show();
1310                        proc.crashDialog = d;
1311                    } else {
1312                        // The device is asleep, so just pretend that the user
1313                        // saw a crash dialog and hit "force quit".
1314                        res.set(0);
1315                    }
1316                }
1317                ensureBootCompleted();
1318            } break;
1319            case SHOW_FACTORY_ERROR_MSG: {
1320                Dialog d = new FactoryErrorDialog(
1321                    mContext, msg.getData().getCharSequence("msg"));
1322                d.show();
1323                ensureBootCompleted();
1324            } break;
1325            case UPDATE_CONFIGURATION_MSG: {
1326                final ContentResolver resolver = mContext.getContentResolver();
1327                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1328            } break;
1329            case GC_BACKGROUND_PROCESSES_MSG: {
1330                synchronized (ActivityManagerService.this) {
1331                    performAppGcsIfAppropriateLocked();
1332                }
1333            } break;
1334            case WAIT_FOR_DEBUGGER_MSG: {
1335                synchronized (ActivityManagerService.this) {
1336                    ProcessRecord app = (ProcessRecord)msg.obj;
1337                    if (msg.arg1 != 0) {
1338                        if (!app.waitedForDebugger) {
1339                            Dialog d = new AppWaitingForDebuggerDialog(
1340                                    ActivityManagerService.this,
1341                                    mContext, app);
1342                            app.waitDialog = d;
1343                            app.waitedForDebugger = true;
1344                            d.show();
1345                        }
1346                    } else {
1347                        if (app.waitDialog != null) {
1348                            app.waitDialog.dismiss();
1349                            app.waitDialog = null;
1350                        }
1351                    }
1352                }
1353            } break;
1354            case SERVICE_TIMEOUT_MSG: {
1355                if (mDidDexOpt) {
1356                    mDidDexOpt = false;
1357                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1358                    nmsg.obj = msg.obj;
1359                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1360                    return;
1361                }
1362                mServices.serviceTimeout((ProcessRecord)msg.obj);
1363            } break;
1364            case UPDATE_TIME_ZONE: {
1365                synchronized (ActivityManagerService.this) {
1366                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1367                        ProcessRecord r = mLruProcesses.get(i);
1368                        if (r.thread != null) {
1369                            try {
1370                                r.thread.updateTimeZone();
1371                            } catch (RemoteException ex) {
1372                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1373                            }
1374                        }
1375                    }
1376                }
1377            } break;
1378            case CLEAR_DNS_CACHE_MSG: {
1379                synchronized (ActivityManagerService.this) {
1380                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1381                        ProcessRecord r = mLruProcesses.get(i);
1382                        if (r.thread != null) {
1383                            try {
1384                                r.thread.clearDnsCache();
1385                            } catch (RemoteException ex) {
1386                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1387                            }
1388                        }
1389                    }
1390                }
1391            } break;
1392            case UPDATE_HTTP_PROXY_MSG: {
1393                ProxyInfo proxy = (ProxyInfo)msg.obj;
1394                String host = "";
1395                String port = "";
1396                String exclList = "";
1397                Uri pacFileUrl = Uri.EMPTY;
1398                if (proxy != null) {
1399                    host = proxy.getHost();
1400                    port = Integer.toString(proxy.getPort());
1401                    exclList = proxy.getExclusionListAsString();
1402                    pacFileUrl = proxy.getPacFileUrl();
1403                }
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to update http proxy for: " +
1412                                        r.info.processName);
1413                            }
1414                        }
1415                    }
1416                }
1417            } break;
1418            case SHOW_UID_ERROR_MSG: {
1419                String title = "System UIDs Inconsistent";
1420                String text = "UIDs on the system are inconsistent, you need to wipe your"
1421                        + " data partition or your device will be unstable.";
1422                Log.e(TAG, title + ": " + text);
1423                if (mShowDialogs) {
1424                    // XXX This is a temporary dialog, no need to localize.
1425                    AlertDialog d = new BaseErrorDialog(mContext);
1426                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1427                    d.setCancelable(false);
1428                    d.setTitle(title);
1429                    d.setMessage(text);
1430                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1431                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1432                    mUidAlert = d;
1433                    d.show();
1434                }
1435            } break;
1436            case IM_FEELING_LUCKY_MSG: {
1437                if (mUidAlert != null) {
1438                    mUidAlert.dismiss();
1439                    mUidAlert = null;
1440                }
1441            } break;
1442            case PROC_START_TIMEOUT_MSG: {
1443                if (mDidDexOpt) {
1444                    mDidDexOpt = false;
1445                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1446                    nmsg.obj = msg.obj;
1447                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1448                    return;
1449                }
1450                ProcessRecord app = (ProcessRecord)msg.obj;
1451                synchronized (ActivityManagerService.this) {
1452                    processStartTimedOutLocked(app);
1453                }
1454            } break;
1455            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1456                synchronized (ActivityManagerService.this) {
1457                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1458                }
1459            } break;
1460            case KILL_APPLICATION_MSG: {
1461                synchronized (ActivityManagerService.this) {
1462                    int appid = msg.arg1;
1463                    boolean restart = (msg.arg2 == 1);
1464                    Bundle bundle = (Bundle)msg.obj;
1465                    String pkg = bundle.getString("pkg");
1466                    String reason = bundle.getString("reason");
1467                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1468                            false, UserHandle.USER_ALL, reason);
1469                }
1470            } break;
1471            case FINALIZE_PENDING_INTENT_MSG: {
1472                ((PendingIntentRecord)msg.obj).completeFinalize();
1473            } break;
1474            case POST_HEAVY_NOTIFICATION_MSG: {
1475                INotificationManager inm = NotificationManager.getService();
1476                if (inm == null) {
1477                    return;
1478                }
1479
1480                ActivityRecord root = (ActivityRecord)msg.obj;
1481                ProcessRecord process = root.app;
1482                if (process == null) {
1483                    return;
1484                }
1485
1486                try {
1487                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1488                    String text = mContext.getString(R.string.heavy_weight_notification,
1489                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1490                    Notification notification = new Notification();
1491                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1492                    notification.when = 0;
1493                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1494                    notification.tickerText = text;
1495                    notification.defaults = 0; // please be quiet
1496                    notification.sound = null;
1497                    notification.vibrate = null;
1498                    notification.color = mContext.getResources().getColor(
1499                            com.android.internal.R.color.system_notification_accent_color);
1500                    notification.setLatestEventInfo(context, text,
1501                            mContext.getText(R.string.heavy_weight_notification_detail),
1502                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1503                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1504                                    new UserHandle(root.userId)));
1505
1506                    try {
1507                        int[] outId = new int[1];
1508                        inm.enqueueNotificationWithTag("android", "android", null,
1509                                R.string.heavy_weight_notification,
1510                                notification, outId, root.userId);
1511                    } catch (RuntimeException e) {
1512                        Slog.w(ActivityManagerService.TAG,
1513                                "Error showing notification for heavy-weight app", e);
1514                    } catch (RemoteException e) {
1515                    }
1516                } catch (NameNotFoundException e) {
1517                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1518                }
1519            } break;
1520            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1521                INotificationManager inm = NotificationManager.getService();
1522                if (inm == null) {
1523                    return;
1524                }
1525                try {
1526                    inm.cancelNotificationWithTag("android", null,
1527                            R.string.heavy_weight_notification,  msg.arg1);
1528                } catch (RuntimeException e) {
1529                    Slog.w(ActivityManagerService.TAG,
1530                            "Error canceling notification for service", e);
1531                } catch (RemoteException e) {
1532                }
1533            } break;
1534            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1535                synchronized (ActivityManagerService.this) {
1536                    checkExcessivePowerUsageLocked(true);
1537                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1538                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1539                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1540                }
1541            } break;
1542            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1543                synchronized (ActivityManagerService.this) {
1544                    ActivityRecord ar = (ActivityRecord)msg.obj;
1545                    if (mCompatModeDialog != null) {
1546                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1547                                ar.info.applicationInfo.packageName)) {
1548                            return;
1549                        }
1550                        mCompatModeDialog.dismiss();
1551                        mCompatModeDialog = null;
1552                    }
1553                    if (ar != null && false) {
1554                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1555                                ar.packageName)) {
1556                            int mode = mCompatModePackages.computeCompatModeLocked(
1557                                    ar.info.applicationInfo);
1558                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1559                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1560                                mCompatModeDialog = new CompatModeDialog(
1561                                        ActivityManagerService.this, mContext,
1562                                        ar.info.applicationInfo);
1563                                mCompatModeDialog.show();
1564                            }
1565                        }
1566                    }
1567                }
1568                break;
1569            }
1570            case DISPATCH_PROCESSES_CHANGED: {
1571                dispatchProcessesChanged();
1572                break;
1573            }
1574            case DISPATCH_PROCESS_DIED: {
1575                final int pid = msg.arg1;
1576                final int uid = msg.arg2;
1577                dispatchProcessDied(pid, uid);
1578                break;
1579            }
1580            case REPORT_MEM_USAGE_MSG: {
1581                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1582                Thread thread = new Thread() {
1583                    @Override public void run() {
1584                        final SparseArray<ProcessMemInfo> infoMap
1585                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1586                        for (int i=0, N=memInfos.size(); i<N; i++) {
1587                            ProcessMemInfo mi = memInfos.get(i);
1588                            infoMap.put(mi.pid, mi);
1589                        }
1590                        updateCpuStatsNow();
1591                        synchronized (mProcessCpuThread) {
1592                            final int N = mProcessCpuTracker.countStats();
1593                            for (int i=0; i<N; i++) {
1594                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1595                                if (st.vsize > 0) {
1596                                    long pss = Debug.getPss(st.pid, null);
1597                                    if (pss > 0) {
1598                                        if (infoMap.indexOfKey(st.pid) < 0) {
1599                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1600                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1601                                            mi.pss = pss;
1602                                            memInfos.add(mi);
1603                                        }
1604                                    }
1605                                }
1606                            }
1607                        }
1608
1609                        long totalPss = 0;
1610                        for (int i=0, N=memInfos.size(); i<N; i++) {
1611                            ProcessMemInfo mi = memInfos.get(i);
1612                            if (mi.pss == 0) {
1613                                mi.pss = Debug.getPss(mi.pid, null);
1614                            }
1615                            totalPss += mi.pss;
1616                        }
1617                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1618                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1619                                if (lhs.oomAdj != rhs.oomAdj) {
1620                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1621                                }
1622                                if (lhs.pss != rhs.pss) {
1623                                    return lhs.pss < rhs.pss ? 1 : -1;
1624                                }
1625                                return 0;
1626                            }
1627                        });
1628
1629                        StringBuilder tag = new StringBuilder(128);
1630                        StringBuilder stack = new StringBuilder(128);
1631                        tag.append("Low on memory -- ");
1632                        appendMemBucket(tag, totalPss, "total", false);
1633                        appendMemBucket(stack, totalPss, "total", true);
1634
1635                        StringBuilder logBuilder = new StringBuilder(1024);
1636                        logBuilder.append("Low on memory:\n");
1637
1638                        boolean firstLine = true;
1639                        int lastOomAdj = Integer.MIN_VALUE;
1640                        for (int i=0, N=memInfos.size(); i<N; i++) {
1641                            ProcessMemInfo mi = memInfos.get(i);
1642
1643                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1644                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1645                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1646                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1647                                if (lastOomAdj != mi.oomAdj) {
1648                                    lastOomAdj = mi.oomAdj;
1649                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1650                                        tag.append(" / ");
1651                                    }
1652                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1653                                        if (firstLine) {
1654                                            stack.append(":");
1655                                            firstLine = false;
1656                                        }
1657                                        stack.append("\n\t at ");
1658                                    } else {
1659                                        stack.append("$");
1660                                    }
1661                                } else {
1662                                    tag.append(" ");
1663                                    stack.append("$");
1664                                }
1665                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1666                                    appendMemBucket(tag, mi.pss, mi.name, false);
1667                                }
1668                                appendMemBucket(stack, mi.pss, mi.name, true);
1669                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1670                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1671                                    stack.append("(");
1672                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1673                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1674                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1675                                            stack.append(":");
1676                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1677                                        }
1678                                    }
1679                                    stack.append(")");
1680                                }
1681                            }
1682
1683                            logBuilder.append("  ");
1684                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1685                            logBuilder.append(' ');
1686                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1687                            logBuilder.append(' ');
1688                            ProcessList.appendRamKb(logBuilder, mi.pss);
1689                            logBuilder.append(" kB: ");
1690                            logBuilder.append(mi.name);
1691                            logBuilder.append(" (");
1692                            logBuilder.append(mi.pid);
1693                            logBuilder.append(") ");
1694                            logBuilder.append(mi.adjType);
1695                            logBuilder.append('\n');
1696                            if (mi.adjReason != null) {
1697                                logBuilder.append("                      ");
1698                                logBuilder.append(mi.adjReason);
1699                                logBuilder.append('\n');
1700                            }
1701                        }
1702
1703                        logBuilder.append("           ");
1704                        ProcessList.appendRamKb(logBuilder, totalPss);
1705                        logBuilder.append(" kB: TOTAL\n");
1706
1707                        long[] infos = new long[Debug.MEMINFO_COUNT];
1708                        Debug.getMemInfo(infos);
1709                        logBuilder.append("  MemInfo: ");
1710                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1711                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1712                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1713                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1714                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1715                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1716                            logBuilder.append("  ZRAM: ");
1717                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1718                            logBuilder.append(" kB RAM, ");
1719                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1720                            logBuilder.append(" kB swap total, ");
1721                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1722                            logBuilder.append(" kB swap free\n");
1723                        }
1724                        Slog.i(TAG, logBuilder.toString());
1725
1726                        StringBuilder dropBuilder = new StringBuilder(1024);
1727                        /*
1728                        StringWriter oomSw = new StringWriter();
1729                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1730                        StringWriter catSw = new StringWriter();
1731                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1732                        String[] emptyArgs = new String[] { };
1733                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1734                        oomPw.flush();
1735                        String oomString = oomSw.toString();
1736                        */
1737                        dropBuilder.append(stack);
1738                        dropBuilder.append('\n');
1739                        dropBuilder.append('\n');
1740                        dropBuilder.append(logBuilder);
1741                        dropBuilder.append('\n');
1742                        /*
1743                        dropBuilder.append(oomString);
1744                        dropBuilder.append('\n');
1745                        */
1746                        StringWriter catSw = new StringWriter();
1747                        synchronized (ActivityManagerService.this) {
1748                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1749                            String[] emptyArgs = new String[] { };
1750                            catPw.println();
1751                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1752                            catPw.println();
1753                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1754                                    false, false, null);
1755                            catPw.println();
1756                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1757                            catPw.flush();
1758                        }
1759                        dropBuilder.append(catSw.toString());
1760                        addErrorToDropBox("lowmem", null, "system_server", null,
1761                                null, tag.toString(), dropBuilder.toString(), null, null);
1762                        //Slog.i(TAG, "Sent to dropbox:");
1763                        //Slog.i(TAG, dropBuilder.toString());
1764                        synchronized (ActivityManagerService.this) {
1765                            long now = SystemClock.uptimeMillis();
1766                            if (mLastMemUsageReportTime < now) {
1767                                mLastMemUsageReportTime = now;
1768                            }
1769                        }
1770                    }
1771                };
1772                thread.start();
1773                break;
1774            }
1775            case START_USER_SWITCH_MSG: {
1776                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1777                break;
1778            }
1779            case REPORT_USER_SWITCH_MSG: {
1780                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1781                break;
1782            }
1783            case CONTINUE_USER_SWITCH_MSG: {
1784                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1785                break;
1786            }
1787            case USER_SWITCH_TIMEOUT_MSG: {
1788                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1789                break;
1790            }
1791            case IMMERSIVE_MODE_LOCK_MSG: {
1792                final boolean nextState = (msg.arg1 != 0);
1793                if (mUpdateLock.isHeld() != nextState) {
1794                    if (DEBUG_IMMERSIVE) {
1795                        final ActivityRecord r = (ActivityRecord) msg.obj;
1796                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1797                    }
1798                    if (nextState) {
1799                        mUpdateLock.acquire();
1800                    } else {
1801                        mUpdateLock.release();
1802                    }
1803                }
1804                break;
1805            }
1806            case PERSIST_URI_GRANTS_MSG: {
1807                writeGrantedUriPermissions();
1808                break;
1809            }
1810            case REQUEST_ALL_PSS_MSG: {
1811                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1812                break;
1813            }
1814            case START_PROFILES_MSG: {
1815                synchronized (ActivityManagerService.this) {
1816                    startProfilesLocked();
1817                }
1818                break;
1819            }
1820            case UPDATE_TIME: {
1821                synchronized (ActivityManagerService.this) {
1822                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1823                        ProcessRecord r = mLruProcesses.get(i);
1824                        if (r.thread != null) {
1825                            try {
1826                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1827                            } catch (RemoteException ex) {
1828                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1829                            }
1830                        }
1831                    }
1832                }
1833                break;
1834            }
1835            case SYSTEM_USER_START_MSG: {
1836                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1837                        Integer.toString(msg.arg1), msg.arg1);
1838                mSystemServiceManager.startUser(msg.arg1);
1839                break;
1840            }
1841            case SYSTEM_USER_CURRENT_MSG: {
1842                mBatteryStatsService.noteEvent(
1843                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1844                        Integer.toString(msg.arg2), msg.arg2);
1845                mBatteryStatsService.noteEvent(
1846                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1847                        Integer.toString(msg.arg1), msg.arg1);
1848                mSystemServiceManager.switchUser(msg.arg1);
1849                mLockToAppRequest.clearPrompt();
1850                break;
1851            }
1852            case ENTER_ANIMATION_COMPLETE_MSG: {
1853                synchronized (ActivityManagerService.this) {
1854                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1855                    if (r != null && r.app != null && r.app.thread != null) {
1856                        try {
1857                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1858                        } catch (RemoteException e) {
1859                        }
1860                    }
1861                }
1862                break;
1863            }
1864            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1865                enableScreenAfterBoot();
1866                break;
1867            }
1868            }
1869        }
1870    };
1871
1872    static final int COLLECT_PSS_BG_MSG = 1;
1873
1874    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1875        @Override
1876        public void handleMessage(Message msg) {
1877            switch (msg.what) {
1878            case COLLECT_PSS_BG_MSG: {
1879                long start = SystemClock.uptimeMillis();
1880                MemInfoReader memInfo = null;
1881                synchronized (ActivityManagerService.this) {
1882                    if (mFullPssPending) {
1883                        mFullPssPending = false;
1884                        memInfo = new MemInfoReader();
1885                    }
1886                }
1887                if (memInfo != null) {
1888                    updateCpuStatsNow();
1889                    long nativeTotalPss = 0;
1890                    synchronized (mProcessCpuThread) {
1891                        final int N = mProcessCpuTracker.countStats();
1892                        for (int j=0; j<N; j++) {
1893                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1894                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1895                                // This is definitely an application process; skip it.
1896                                continue;
1897                            }
1898                            synchronized (mPidsSelfLocked) {
1899                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1900                                    // This is one of our own processes; skip it.
1901                                    continue;
1902                                }
1903                            }
1904                            nativeTotalPss += Debug.getPss(st.pid, null);
1905                        }
1906                    }
1907                    memInfo.readMemInfo();
1908                    synchronized (this) {
1909                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1910                                + (SystemClock.uptimeMillis()-start) + "ms");
1911                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1912                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1913                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1914                                        +memInfo.getSlabSizeKb(),
1915                                nativeTotalPss);
1916                    }
1917                }
1918
1919                int i=0, num=0;
1920                long[] tmp = new long[1];
1921                do {
1922                    ProcessRecord proc;
1923                    int procState;
1924                    int pid;
1925                    synchronized (ActivityManagerService.this) {
1926                        if (i >= mPendingPssProcesses.size()) {
1927                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1928                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1929                            mPendingPssProcesses.clear();
1930                            return;
1931                        }
1932                        proc = mPendingPssProcesses.get(i);
1933                        procState = proc.pssProcState;
1934                        if (proc.thread != null && procState == proc.setProcState) {
1935                            pid = proc.pid;
1936                        } else {
1937                            proc = null;
1938                            pid = 0;
1939                        }
1940                        i++;
1941                    }
1942                    if (proc != null) {
1943                        long pss = Debug.getPss(pid, tmp);
1944                        synchronized (ActivityManagerService.this) {
1945                            if (proc.thread != null && proc.setProcState == procState
1946                                    && proc.pid == pid) {
1947                                num++;
1948                                proc.lastPssTime = SystemClock.uptimeMillis();
1949                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1950                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1951                                        + ": " + pss + " lastPss=" + proc.lastPss
1952                                        + " state=" + ProcessList.makeProcStateString(procState));
1953                                if (proc.initialIdlePss == 0) {
1954                                    proc.initialIdlePss = pss;
1955                                }
1956                                proc.lastPss = pss;
1957                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1958                                    proc.lastCachedPss = pss;
1959                                }
1960                            }
1961                        }
1962                    }
1963                } while (true);
1964            }
1965            }
1966        }
1967    };
1968
1969    /**
1970     * Monitor for package changes and update our internal state.
1971     */
1972    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1973        @Override
1974        public void onPackageRemoved(String packageName, int uid) {
1975            // Remove all tasks with activities in the specified package from the list of recent tasks
1976            synchronized (ActivityManagerService.this) {
1977                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1978                    TaskRecord tr = mRecentTasks.get(i);
1979                    ComponentName cn = tr.intent.getComponent();
1980                    if (cn != null && cn.getPackageName().equals(packageName)) {
1981                        // If the package name matches, remove the task and kill the process
1982                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1983                    }
1984                }
1985            }
1986        }
1987
1988        @Override
1989        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1990            onPackageModified(packageName);
1991            return true;
1992        }
1993
1994        @Override
1995        public void onPackageModified(String packageName) {
1996            final PackageManager pm = mContext.getPackageManager();
1997            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1998                    new ArrayList<Pair<Intent, Integer>>();
1999            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2000            // Copy the list of recent tasks so that we don't hold onto the lock on
2001            // ActivityManagerService for long periods while checking if components exist.
2002            synchronized (ActivityManagerService.this) {
2003                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2004                    TaskRecord tr = mRecentTasks.get(i);
2005                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2006                }
2007            }
2008            // Check the recent tasks and filter out all tasks with components that no longer exist.
2009            Intent tmpI = new Intent();
2010            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2011                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2012                ComponentName cn = p.first.getComponent();
2013                if (cn != null && cn.getPackageName().equals(packageName)) {
2014                    try {
2015                        // Add the task to the list to remove if the component no longer exists
2016                        tmpI.setComponent(cn);
2017                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2018                            tasksToRemove.add(p.second);
2019                        }
2020                    } catch (Exception e) {}
2021                }
2022            }
2023            // Prune all the tasks with removed components from the list of recent tasks
2024            synchronized (ActivityManagerService.this) {
2025                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2026                    // Remove the task but don't kill the process (since other components in that
2027                    // package may still be running and in the background)
2028                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2029                }
2030            }
2031        }
2032
2033        @Override
2034        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2035            // Force stop the specified packages
2036            if (packages != null) {
2037                for (String pkg : packages) {
2038                    synchronized (ActivityManagerService.this) {
2039                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2040                                "finished booting")) {
2041                            return true;
2042                        }
2043                    }
2044                }
2045            }
2046            return false;
2047        }
2048    };
2049
2050    public void setSystemProcess() {
2051        try {
2052            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2053            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2054            ServiceManager.addService("meminfo", new MemBinder(this));
2055            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2056            ServiceManager.addService("dbinfo", new DbBinder(this));
2057            if (MONITOR_CPU_USAGE) {
2058                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2059            }
2060            ServiceManager.addService("permission", new PermissionController(this));
2061
2062            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2063                    "android", STOCK_PM_FLAGS);
2064            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2065
2066            synchronized (this) {
2067                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2068                app.persistent = true;
2069                app.pid = MY_PID;
2070                app.maxAdj = ProcessList.SYSTEM_ADJ;
2071                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2072                mProcessNames.put(app.processName, app.uid, app);
2073                synchronized (mPidsSelfLocked) {
2074                    mPidsSelfLocked.put(app.pid, app);
2075                }
2076                updateLruProcessLocked(app, false, null);
2077                updateOomAdjLocked();
2078            }
2079        } catch (PackageManager.NameNotFoundException e) {
2080            throw new RuntimeException(
2081                    "Unable to find android system package", e);
2082        }
2083    }
2084
2085    public void setWindowManager(WindowManagerService wm) {
2086        mWindowManager = wm;
2087        mStackSupervisor.setWindowManager(wm);
2088    }
2089
2090    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2091        mUsageStatsService = usageStatsManager;
2092    }
2093
2094    public void startObservingNativeCrashes() {
2095        final NativeCrashListener ncl = new NativeCrashListener(this);
2096        ncl.start();
2097    }
2098
2099    public IAppOpsService getAppOpsService() {
2100        return mAppOpsService;
2101    }
2102
2103    static class MemBinder extends Binder {
2104        ActivityManagerService mActivityManagerService;
2105        MemBinder(ActivityManagerService activityManagerService) {
2106            mActivityManagerService = activityManagerService;
2107        }
2108
2109        @Override
2110        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2111            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2112                    != PackageManager.PERMISSION_GRANTED) {
2113                pw.println("Permission Denial: can't dump meminfo from from pid="
2114                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2115                        + " without permission " + android.Manifest.permission.DUMP);
2116                return;
2117            }
2118
2119            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2120        }
2121    }
2122
2123    static class GraphicsBinder extends Binder {
2124        ActivityManagerService mActivityManagerService;
2125        GraphicsBinder(ActivityManagerService activityManagerService) {
2126            mActivityManagerService = activityManagerService;
2127        }
2128
2129        @Override
2130        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2131            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2132                    != PackageManager.PERMISSION_GRANTED) {
2133                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2134                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2135                        + " without permission " + android.Manifest.permission.DUMP);
2136                return;
2137            }
2138
2139            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2140        }
2141    }
2142
2143    static class DbBinder extends Binder {
2144        ActivityManagerService mActivityManagerService;
2145        DbBinder(ActivityManagerService activityManagerService) {
2146            mActivityManagerService = activityManagerService;
2147        }
2148
2149        @Override
2150        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2151            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2152                    != PackageManager.PERMISSION_GRANTED) {
2153                pw.println("Permission Denial: can't dump dbinfo from from pid="
2154                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2155                        + " without permission " + android.Manifest.permission.DUMP);
2156                return;
2157            }
2158
2159            mActivityManagerService.dumpDbInfo(fd, pw, args);
2160        }
2161    }
2162
2163    static class CpuBinder extends Binder {
2164        ActivityManagerService mActivityManagerService;
2165        CpuBinder(ActivityManagerService activityManagerService) {
2166            mActivityManagerService = activityManagerService;
2167        }
2168
2169        @Override
2170        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2171            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2172                    != PackageManager.PERMISSION_GRANTED) {
2173                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2174                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2175                        + " without permission " + android.Manifest.permission.DUMP);
2176                return;
2177            }
2178
2179            synchronized (mActivityManagerService.mProcessCpuThread) {
2180                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2181                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2182                        SystemClock.uptimeMillis()));
2183            }
2184        }
2185    }
2186
2187    public static final class Lifecycle extends SystemService {
2188        private final ActivityManagerService mService;
2189
2190        public Lifecycle(Context context) {
2191            super(context);
2192            mService = new ActivityManagerService(context);
2193        }
2194
2195        @Override
2196        public void onStart() {
2197            mService.start();
2198        }
2199
2200        public ActivityManagerService getService() {
2201            return mService;
2202        }
2203    }
2204
2205    // Note: This method is invoked on the main thread but may need to attach various
2206    // handlers to other threads.  So take care to be explicit about the looper.
2207    public ActivityManagerService(Context systemContext) {
2208        mContext = systemContext;
2209        mFactoryTest = FactoryTest.getMode();
2210        mSystemThread = ActivityThread.currentActivityThread();
2211
2212        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2213
2214        mHandlerThread = new ServiceThread(TAG,
2215                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2216        mHandlerThread.start();
2217        mHandler = new MainHandler(mHandlerThread.getLooper());
2218
2219        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2220                "foreground", BROADCAST_FG_TIMEOUT, false);
2221        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2222                "background", BROADCAST_BG_TIMEOUT, true);
2223        mBroadcastQueues[0] = mFgBroadcastQueue;
2224        mBroadcastQueues[1] = mBgBroadcastQueue;
2225
2226        mServices = new ActiveServices(this);
2227        mProviderMap = new ProviderMap(this);
2228
2229        // TODO: Move creation of battery stats service outside of activity manager service.
2230        File dataDir = Environment.getDataDirectory();
2231        File systemDir = new File(dataDir, "system");
2232        systemDir.mkdirs();
2233        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2234        mBatteryStatsService.getActiveStatistics().readLocked();
2235        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2236        mOnBattery = DEBUG_POWER ? true
2237                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2238        mBatteryStatsService.getActiveStatistics().setCallback(this);
2239
2240        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2241
2242        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2243
2244        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2245
2246        // User 0 is the first and only user that runs at boot.
2247        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2248        mUserLru.add(Integer.valueOf(0));
2249        updateStartedUserArrayLocked();
2250
2251        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2252            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2253
2254        mConfiguration.setToDefaults();
2255        mConfiguration.setLocale(Locale.getDefault());
2256
2257        mConfigurationSeq = mConfiguration.seq = 1;
2258        mProcessCpuTracker.init();
2259
2260        final Resources res = mContext.getResources();
2261        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
2262        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2263        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2264
2265        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2266        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2267        mStackSupervisor = new ActivityStackSupervisor(this);
2268        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2269
2270        mProcessCpuThread = new Thread("CpuTracker") {
2271            @Override
2272            public void run() {
2273                while (true) {
2274                    try {
2275                        try {
2276                            synchronized(this) {
2277                                final long now = SystemClock.uptimeMillis();
2278                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2279                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2280                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2281                                //        + ", write delay=" + nextWriteDelay);
2282                                if (nextWriteDelay < nextCpuDelay) {
2283                                    nextCpuDelay = nextWriteDelay;
2284                                }
2285                                if (nextCpuDelay > 0) {
2286                                    mProcessCpuMutexFree.set(true);
2287                                    this.wait(nextCpuDelay);
2288                                }
2289                            }
2290                        } catch (InterruptedException e) {
2291                        }
2292                        updateCpuStatsNow();
2293                    } catch (Exception e) {
2294                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2295                    }
2296                }
2297            }
2298        };
2299
2300        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2301
2302        Watchdog.getInstance().addMonitor(this);
2303        Watchdog.getInstance().addThread(mHandler);
2304    }
2305
2306    public void setSystemServiceManager(SystemServiceManager mgr) {
2307        mSystemServiceManager = mgr;
2308    }
2309
2310    private void start() {
2311        Process.removeAllProcessGroups();
2312        mProcessCpuThread.start();
2313
2314        mBatteryStatsService.publish(mContext);
2315        mAppOpsService.publish(mContext);
2316        Slog.d("AppOps", "AppOpsService published");
2317        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2318    }
2319
2320    public void initPowerManagement() {
2321        mStackSupervisor.initPowerManagement();
2322        mBatteryStatsService.initPowerManagement();
2323    }
2324
2325    @Override
2326    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2327            throws RemoteException {
2328        if (code == SYSPROPS_TRANSACTION) {
2329            // We need to tell all apps about the system property change.
2330            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2331            synchronized(this) {
2332                final int NP = mProcessNames.getMap().size();
2333                for (int ip=0; ip<NP; ip++) {
2334                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2335                    final int NA = apps.size();
2336                    for (int ia=0; ia<NA; ia++) {
2337                        ProcessRecord app = apps.valueAt(ia);
2338                        if (app.thread != null) {
2339                            procs.add(app.thread.asBinder());
2340                        }
2341                    }
2342                }
2343            }
2344
2345            int N = procs.size();
2346            for (int i=0; i<N; i++) {
2347                Parcel data2 = Parcel.obtain();
2348                try {
2349                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2350                } catch (RemoteException e) {
2351                }
2352                data2.recycle();
2353            }
2354        }
2355        try {
2356            return super.onTransact(code, data, reply, flags);
2357        } catch (RuntimeException e) {
2358            // The activity manager only throws security exceptions, so let's
2359            // log all others.
2360            if (!(e instanceof SecurityException)) {
2361                Slog.wtf(TAG, "Activity Manager Crash", e);
2362            }
2363            throw e;
2364        }
2365    }
2366
2367    void updateCpuStats() {
2368        final long now = SystemClock.uptimeMillis();
2369        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2370            return;
2371        }
2372        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2373            synchronized (mProcessCpuThread) {
2374                mProcessCpuThread.notify();
2375            }
2376        }
2377    }
2378
2379    void updateCpuStatsNow() {
2380        synchronized (mProcessCpuThread) {
2381            mProcessCpuMutexFree.set(false);
2382            final long now = SystemClock.uptimeMillis();
2383            boolean haveNewCpuStats = false;
2384
2385            if (MONITOR_CPU_USAGE &&
2386                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2387                mLastCpuTime.set(now);
2388                haveNewCpuStats = true;
2389                mProcessCpuTracker.update();
2390                //Slog.i(TAG, mProcessCpu.printCurrentState());
2391                //Slog.i(TAG, "Total CPU usage: "
2392                //        + mProcessCpu.getTotalCpuPercent() + "%");
2393
2394                // Slog the cpu usage if the property is set.
2395                if ("true".equals(SystemProperties.get("events.cpu"))) {
2396                    int user = mProcessCpuTracker.getLastUserTime();
2397                    int system = mProcessCpuTracker.getLastSystemTime();
2398                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2399                    int irq = mProcessCpuTracker.getLastIrqTime();
2400                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2401                    int idle = mProcessCpuTracker.getLastIdleTime();
2402
2403                    int total = user + system + iowait + irq + softIrq + idle;
2404                    if (total == 0) total = 1;
2405
2406                    EventLog.writeEvent(EventLogTags.CPU,
2407                            ((user+system+iowait+irq+softIrq) * 100) / total,
2408                            (user * 100) / total,
2409                            (system * 100) / total,
2410                            (iowait * 100) / total,
2411                            (irq * 100) / total,
2412                            (softIrq * 100) / total);
2413                }
2414            }
2415
2416            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2417            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2418            synchronized(bstats) {
2419                synchronized(mPidsSelfLocked) {
2420                    if (haveNewCpuStats) {
2421                        if (mOnBattery) {
2422                            int perc = bstats.startAddingCpuLocked();
2423                            int totalUTime = 0;
2424                            int totalSTime = 0;
2425                            final int N = mProcessCpuTracker.countStats();
2426                            for (int i=0; i<N; i++) {
2427                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2428                                if (!st.working) {
2429                                    continue;
2430                                }
2431                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2432                                int otherUTime = (st.rel_utime*perc)/100;
2433                                int otherSTime = (st.rel_stime*perc)/100;
2434                                totalUTime += otherUTime;
2435                                totalSTime += otherSTime;
2436                                if (pr != null) {
2437                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2438                                    if (ps == null || !ps.isActive()) {
2439                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2440                                                pr.info.uid, pr.processName);
2441                                    }
2442                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2443                                            st.rel_stime-otherSTime);
2444                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2445                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2446                                } else {
2447                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2448                                    if (ps == null || !ps.isActive()) {
2449                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2450                                                bstats.mapUid(st.uid), st.name);
2451                                    }
2452                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2453                                            st.rel_stime-otherSTime);
2454                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2455                                }
2456                            }
2457                            bstats.finishAddingCpuLocked(perc, totalUTime,
2458                                    totalSTime, cpuSpeedTimes);
2459                        }
2460                    }
2461                }
2462
2463                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2464                    mLastWriteTime = now;
2465                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2466                }
2467            }
2468        }
2469    }
2470
2471    @Override
2472    public void batteryNeedsCpuUpdate() {
2473        updateCpuStatsNow();
2474    }
2475
2476    @Override
2477    public void batteryPowerChanged(boolean onBattery) {
2478        // When plugging in, update the CPU stats first before changing
2479        // the plug state.
2480        updateCpuStatsNow();
2481        synchronized (this) {
2482            synchronized(mPidsSelfLocked) {
2483                mOnBattery = DEBUG_POWER ? true : onBattery;
2484            }
2485        }
2486    }
2487
2488    /**
2489     * Initialize the application bind args. These are passed to each
2490     * process when the bindApplication() IPC is sent to the process. They're
2491     * lazily setup to make sure the services are running when they're asked for.
2492     */
2493    private HashMap<String, IBinder> getCommonServicesLocked() {
2494        if (mAppBindArgs == null) {
2495            mAppBindArgs = new HashMap<String, IBinder>();
2496
2497            // Setup the application init args
2498            mAppBindArgs.put("package", ServiceManager.getService("package"));
2499            mAppBindArgs.put("window", ServiceManager.getService("window"));
2500            mAppBindArgs.put(Context.ALARM_SERVICE,
2501                    ServiceManager.getService(Context.ALARM_SERVICE));
2502        }
2503        return mAppBindArgs;
2504    }
2505
2506    final void setFocusedActivityLocked(ActivityRecord r) {
2507        if (mFocusedActivity != r) {
2508            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2509            mFocusedActivity = r;
2510            if (r.task != null && r.task.voiceInteractor != null) {
2511                startRunningVoiceLocked();
2512            } else {
2513                finishRunningVoiceLocked();
2514            }
2515            mStackSupervisor.setFocusedStack(r);
2516            if (r != null) {
2517                mWindowManager.setFocusedApp(r.appToken, true);
2518            }
2519            applyUpdateLockStateLocked(r);
2520        }
2521    }
2522
2523    final void clearFocusedActivity(ActivityRecord r) {
2524        if (mFocusedActivity == r) {
2525            mFocusedActivity = null;
2526        }
2527    }
2528
2529    @Override
2530    public void setFocusedStack(int stackId) {
2531        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2532        synchronized (ActivityManagerService.this) {
2533            ActivityStack stack = mStackSupervisor.getStack(stackId);
2534            if (stack != null) {
2535                ActivityRecord r = stack.topRunningActivityLocked(null);
2536                if (r != null) {
2537                    setFocusedActivityLocked(r);
2538                }
2539            }
2540        }
2541    }
2542
2543    @Override
2544    public void notifyActivityDrawn(IBinder token) {
2545        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2546        synchronized (this) {
2547            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2548            if (r != null) {
2549                r.task.stack.notifyActivityDrawnLocked(r);
2550            }
2551        }
2552    }
2553
2554    final void applyUpdateLockStateLocked(ActivityRecord r) {
2555        // Modifications to the UpdateLock state are done on our handler, outside
2556        // the activity manager's locks.  The new state is determined based on the
2557        // state *now* of the relevant activity record.  The object is passed to
2558        // the handler solely for logging detail, not to be consulted/modified.
2559        final boolean nextState = r != null && r.immersive;
2560        mHandler.sendMessage(
2561                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2562    }
2563
2564    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2565        Message msg = Message.obtain();
2566        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2567        msg.obj = r.task.askedCompatMode ? null : r;
2568        mHandler.sendMessage(msg);
2569    }
2570
2571    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2572            String what, Object obj, ProcessRecord srcApp) {
2573        app.lastActivityTime = now;
2574
2575        if (app.activities.size() > 0) {
2576            // Don't want to touch dependent processes that are hosting activities.
2577            return index;
2578        }
2579
2580        int lrui = mLruProcesses.lastIndexOf(app);
2581        if (lrui < 0) {
2582            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2583                    + what + " " + obj + " from " + srcApp);
2584            return index;
2585        }
2586
2587        if (lrui >= index) {
2588            // Don't want to cause this to move dependent processes *back* in the
2589            // list as if they were less frequently used.
2590            return index;
2591        }
2592
2593        if (lrui >= mLruProcessActivityStart) {
2594            // Don't want to touch dependent processes that are hosting activities.
2595            return index;
2596        }
2597
2598        mLruProcesses.remove(lrui);
2599        if (index > 0) {
2600            index--;
2601        }
2602        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2603                + " in LRU list: " + app);
2604        mLruProcesses.add(index, app);
2605        return index;
2606    }
2607
2608    final void removeLruProcessLocked(ProcessRecord app) {
2609        int lrui = mLruProcesses.lastIndexOf(app);
2610        if (lrui >= 0) {
2611            if (lrui <= mLruProcessActivityStart) {
2612                mLruProcessActivityStart--;
2613            }
2614            if (lrui <= mLruProcessServiceStart) {
2615                mLruProcessServiceStart--;
2616            }
2617            mLruProcesses.remove(lrui);
2618        }
2619    }
2620
2621    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2622            ProcessRecord client) {
2623        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2624                || app.treatLikeActivity;
2625        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2626        if (!activityChange && hasActivity) {
2627            // The process has activities, so we are only allowing activity-based adjustments
2628            // to move it.  It should be kept in the front of the list with other
2629            // processes that have activities, and we don't want those to change their
2630            // order except due to activity operations.
2631            return;
2632        }
2633
2634        mLruSeq++;
2635        final long now = SystemClock.uptimeMillis();
2636        app.lastActivityTime = now;
2637
2638        // First a quick reject: if the app is already at the position we will
2639        // put it, then there is nothing to do.
2640        if (hasActivity) {
2641            final int N = mLruProcesses.size();
2642            if (N > 0 && mLruProcesses.get(N-1) == app) {
2643                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2644                return;
2645            }
2646        } else {
2647            if (mLruProcessServiceStart > 0
2648                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2649                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2650                return;
2651            }
2652        }
2653
2654        int lrui = mLruProcesses.lastIndexOf(app);
2655
2656        if (app.persistent && lrui >= 0) {
2657            // We don't care about the position of persistent processes, as long as
2658            // they are in the list.
2659            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2660            return;
2661        }
2662
2663        /* In progress: compute new position first, so we can avoid doing work
2664           if the process is not actually going to move.  Not yet working.
2665        int addIndex;
2666        int nextIndex;
2667        boolean inActivity = false, inService = false;
2668        if (hasActivity) {
2669            // Process has activities, put it at the very tipsy-top.
2670            addIndex = mLruProcesses.size();
2671            nextIndex = mLruProcessServiceStart;
2672            inActivity = true;
2673        } else if (hasService) {
2674            // Process has services, put it at the top of the service list.
2675            addIndex = mLruProcessActivityStart;
2676            nextIndex = mLruProcessServiceStart;
2677            inActivity = true;
2678            inService = true;
2679        } else  {
2680            // Process not otherwise of interest, it goes to the top of the non-service area.
2681            addIndex = mLruProcessServiceStart;
2682            if (client != null) {
2683                int clientIndex = mLruProcesses.lastIndexOf(client);
2684                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2685                        + app);
2686                if (clientIndex >= 0 && addIndex > clientIndex) {
2687                    addIndex = clientIndex;
2688                }
2689            }
2690            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2691        }
2692
2693        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2694                + mLruProcessActivityStart + "): " + app);
2695        */
2696
2697        if (lrui >= 0) {
2698            if (lrui < mLruProcessActivityStart) {
2699                mLruProcessActivityStart--;
2700            }
2701            if (lrui < mLruProcessServiceStart) {
2702                mLruProcessServiceStart--;
2703            }
2704            /*
2705            if (addIndex > lrui) {
2706                addIndex--;
2707            }
2708            if (nextIndex > lrui) {
2709                nextIndex--;
2710            }
2711            */
2712            mLruProcesses.remove(lrui);
2713        }
2714
2715        /*
2716        mLruProcesses.add(addIndex, app);
2717        if (inActivity) {
2718            mLruProcessActivityStart++;
2719        }
2720        if (inService) {
2721            mLruProcessActivityStart++;
2722        }
2723        */
2724
2725        int nextIndex;
2726        if (hasActivity) {
2727            final int N = mLruProcesses.size();
2728            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2729                // Process doesn't have activities, but has clients with
2730                // activities...  move it up, but one below the top (the top
2731                // should always have a real activity).
2732                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2733                mLruProcesses.add(N-1, app);
2734                // To keep it from spamming the LRU list (by making a bunch of clients),
2735                // we will push down any other entries owned by the app.
2736                final int uid = app.info.uid;
2737                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2738                    ProcessRecord subProc = mLruProcesses.get(i);
2739                    if (subProc.info.uid == uid) {
2740                        // We want to push this one down the list.  If the process after
2741                        // it is for the same uid, however, don't do so, because we don't
2742                        // want them internally to be re-ordered.
2743                        if (mLruProcesses.get(i-1).info.uid != uid) {
2744                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2745                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2746                            ProcessRecord tmp = mLruProcesses.get(i);
2747                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2748                            mLruProcesses.set(i-1, tmp);
2749                            i--;
2750                        }
2751                    } else {
2752                        // A gap, we can stop here.
2753                        break;
2754                    }
2755                }
2756            } else {
2757                // Process has activities, put it at the very tipsy-top.
2758                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2759                mLruProcesses.add(app);
2760            }
2761            nextIndex = mLruProcessServiceStart;
2762        } else if (hasService) {
2763            // Process has services, put it at the top of the service list.
2764            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2765            mLruProcesses.add(mLruProcessActivityStart, app);
2766            nextIndex = mLruProcessServiceStart;
2767            mLruProcessActivityStart++;
2768        } else  {
2769            // Process not otherwise of interest, it goes to the top of the non-service area.
2770            int index = mLruProcessServiceStart;
2771            if (client != null) {
2772                // If there is a client, don't allow the process to be moved up higher
2773                // in the list than that client.
2774                int clientIndex = mLruProcesses.lastIndexOf(client);
2775                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2776                        + " when updating " + app);
2777                if (clientIndex <= lrui) {
2778                    // Don't allow the client index restriction to push it down farther in the
2779                    // list than it already is.
2780                    clientIndex = lrui;
2781                }
2782                if (clientIndex >= 0 && index > clientIndex) {
2783                    index = clientIndex;
2784                }
2785            }
2786            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2787            mLruProcesses.add(index, app);
2788            nextIndex = index-1;
2789            mLruProcessActivityStart++;
2790            mLruProcessServiceStart++;
2791        }
2792
2793        // If the app is currently using a content provider or service,
2794        // bump those processes as well.
2795        for (int j=app.connections.size()-1; j>=0; j--) {
2796            ConnectionRecord cr = app.connections.valueAt(j);
2797            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2798                    && cr.binding.service.app != null
2799                    && cr.binding.service.app.lruSeq != mLruSeq
2800                    && !cr.binding.service.app.persistent) {
2801                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2802                        "service connection", cr, app);
2803            }
2804        }
2805        for (int j=app.conProviders.size()-1; j>=0; j--) {
2806            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2807            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2808                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2809                        "provider reference", cpr, app);
2810            }
2811        }
2812    }
2813
2814    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2815        if (uid == Process.SYSTEM_UID) {
2816            // The system gets to run in any process.  If there are multiple
2817            // processes with the same uid, just pick the first (this
2818            // should never happen).
2819            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2820            if (procs == null) return null;
2821            final int N = procs.size();
2822            for (int i = 0; i < N; i++) {
2823                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2824            }
2825        }
2826        ProcessRecord proc = mProcessNames.get(processName, uid);
2827        if (false && proc != null && !keepIfLarge
2828                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2829                && proc.lastCachedPss >= 4000) {
2830            // Turn this condition on to cause killing to happen regularly, for testing.
2831            if (proc.baseProcessTracker != null) {
2832                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2833            }
2834            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2835                    + "k from cached");
2836        } else if (proc != null && !keepIfLarge
2837                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2838                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2839            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2840            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2841                if (proc.baseProcessTracker != null) {
2842                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2843                }
2844                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2845                        + "k from cached");
2846            }
2847        }
2848        return proc;
2849    }
2850
2851    void ensurePackageDexOpt(String packageName) {
2852        IPackageManager pm = AppGlobals.getPackageManager();
2853        try {
2854            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2855                mDidDexOpt = true;
2856            }
2857        } catch (RemoteException e) {
2858        }
2859    }
2860
2861    boolean isNextTransitionForward() {
2862        int transit = mWindowManager.getPendingAppTransition();
2863        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2864                || transit == AppTransition.TRANSIT_TASK_OPEN
2865                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2866    }
2867
2868    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2869            String processName, String abiOverride, int uid, Runnable crashHandler) {
2870        synchronized(this) {
2871            ApplicationInfo info = new ApplicationInfo();
2872            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2873            // For isolated processes, the former contains the parent's uid and the latter the
2874            // actual uid of the isolated process.
2875            // In the special case introduced by this method (which is, starting an isolated
2876            // process directly from the SystemServer without an actual parent app process) the
2877            // closest thing to a parent's uid is SYSTEM_UID.
2878            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2879            // the |isolated| logic in the ProcessRecord constructor.
2880            info.uid = Process.SYSTEM_UID;
2881            info.processName = processName;
2882            info.className = entryPoint;
2883            info.packageName = "android";
2884            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2885                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2886                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2887                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2888                    crashHandler);
2889            return proc != null ? proc.pid : 0;
2890        }
2891    }
2892
2893    final ProcessRecord startProcessLocked(String processName,
2894            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2895            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2896            boolean isolated, boolean keepIfLarge) {
2897        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2898                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2899                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2900                null /* crashHandler */);
2901    }
2902
2903    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2904            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2905            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2906            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2907        ProcessRecord app;
2908        if (!isolated) {
2909            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2910        } else {
2911            // If this is an isolated process, it can't re-use an existing process.
2912            app = null;
2913        }
2914        // We don't have to do anything more if:
2915        // (1) There is an existing application record; and
2916        // (2) The caller doesn't think it is dead, OR there is no thread
2917        //     object attached to it so we know it couldn't have crashed; and
2918        // (3) There is a pid assigned to it, so it is either starting or
2919        //     already running.
2920        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2921                + " app=" + app + " knownToBeDead=" + knownToBeDead
2922                + " thread=" + (app != null ? app.thread : null)
2923                + " pid=" + (app != null ? app.pid : -1));
2924        if (app != null && app.pid > 0) {
2925            if (!knownToBeDead || app.thread == null) {
2926                // We already have the app running, or are waiting for it to
2927                // come up (we have a pid but not yet its thread), so keep it.
2928                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2929                // If this is a new package in the process, add the package to the list
2930                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2931                return app;
2932            }
2933
2934            // An application record is attached to a previous process,
2935            // clean it up now.
2936            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2937            Process.killProcessGroup(app.info.uid, app.pid);
2938            handleAppDiedLocked(app, true, true);
2939        }
2940
2941        String hostingNameStr = hostingName != null
2942                ? hostingName.flattenToShortString() : null;
2943
2944        if (!isolated) {
2945            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2946                // If we are in the background, then check to see if this process
2947                // is bad.  If so, we will just silently fail.
2948                if (mBadProcesses.get(info.processName, info.uid) != null) {
2949                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2950                            + "/" + info.processName);
2951                    return null;
2952                }
2953            } else {
2954                // When the user is explicitly starting a process, then clear its
2955                // crash count so that we won't make it bad until they see at
2956                // least one crash dialog again, and make the process good again
2957                // if it had been bad.
2958                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2959                        + "/" + info.processName);
2960                mProcessCrashTimes.remove(info.processName, info.uid);
2961                if (mBadProcesses.get(info.processName, info.uid) != null) {
2962                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2963                            UserHandle.getUserId(info.uid), info.uid,
2964                            info.processName);
2965                    mBadProcesses.remove(info.processName, info.uid);
2966                    if (app != null) {
2967                        app.bad = false;
2968                    }
2969                }
2970            }
2971        }
2972
2973        if (app == null) {
2974            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2975            app.crashHandler = crashHandler;
2976            if (app == null) {
2977                Slog.w(TAG, "Failed making new process record for "
2978                        + processName + "/" + info.uid + " isolated=" + isolated);
2979                return null;
2980            }
2981            mProcessNames.put(processName, app.uid, app);
2982            if (isolated) {
2983                mIsolatedProcesses.put(app.uid, app);
2984            }
2985        } else {
2986            // If this is a new package in the process, add the package to the list
2987            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2988        }
2989
2990        // If the system is not ready yet, then hold off on starting this
2991        // process until it is.
2992        if (!mProcessesReady
2993                && !isAllowedWhileBooting(info)
2994                && !allowWhileBooting) {
2995            if (!mProcessesOnHold.contains(app)) {
2996                mProcessesOnHold.add(app);
2997            }
2998            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2999            return app;
3000        }
3001
3002        startProcessLocked(
3003                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3004        return (app.pid != 0) ? app : null;
3005    }
3006
3007    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3008        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3009    }
3010
3011    private final void startProcessLocked(ProcessRecord app,
3012            String hostingType, String hostingNameStr) {
3013        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3014                null /* entryPoint */, null /* entryPointArgs */);
3015    }
3016
3017    private final void startProcessLocked(ProcessRecord app, String hostingType,
3018            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3019        if (app.pid > 0 && app.pid != MY_PID) {
3020            synchronized (mPidsSelfLocked) {
3021                mPidsSelfLocked.remove(app.pid);
3022                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3023            }
3024            app.setPid(0);
3025        }
3026
3027        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3028                "startProcessLocked removing on hold: " + app);
3029        mProcessesOnHold.remove(app);
3030
3031        updateCpuStats();
3032
3033        try {
3034            int uid = app.uid;
3035
3036            int[] gids = null;
3037            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3038            if (!app.isolated) {
3039                int[] permGids = null;
3040                try {
3041                    final PackageManager pm = mContext.getPackageManager();
3042                    permGids = pm.getPackageGids(app.info.packageName);
3043
3044                    if (Environment.isExternalStorageEmulated()) {
3045                        if (pm.checkPermission(
3046                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3047                                app.info.packageName) == PERMISSION_GRANTED) {
3048                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3049                        } else {
3050                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3051                        }
3052                    }
3053                } catch (PackageManager.NameNotFoundException e) {
3054                    Slog.w(TAG, "Unable to retrieve gids", e);
3055                }
3056
3057                /*
3058                 * Add shared application and profile GIDs so applications can share some
3059                 * resources like shared libraries and access user-wide resources
3060                 */
3061                if (permGids == null) {
3062                    gids = new int[2];
3063                } else {
3064                    gids = new int[permGids.length + 2];
3065                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3066                }
3067                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3068                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3069            }
3070            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3071                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3072                        && mTopComponent != null
3073                        && app.processName.equals(mTopComponent.getPackageName())) {
3074                    uid = 0;
3075                }
3076                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3077                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3078                    uid = 0;
3079                }
3080            }
3081            int debugFlags = 0;
3082            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3083                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3084                // Also turn on CheckJNI for debuggable apps. It's quite
3085                // awkward to turn on otherwise.
3086                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3087            }
3088            // Run the app in safe mode if its manifest requests so or the
3089            // system is booted in safe mode.
3090            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3091                mSafeMode == true) {
3092                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3093            }
3094            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3095                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3096            }
3097            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3098                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3099            }
3100            if ("1".equals(SystemProperties.get("debug.assert"))) {
3101                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3102            }
3103
3104            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3105            if (requiredAbi == null) {
3106                requiredAbi = Build.SUPPORTED_ABIS[0];
3107            }
3108
3109            // Start the process.  It will either succeed and return a result containing
3110            // the PID of the new process, or else throw a RuntimeException.
3111            boolean isActivityProcess = (entryPoint == null);
3112            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3113            Process.ProcessStartResult startResult = Process.start(entryPoint,
3114                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3115                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3116
3117            if (app.isolated) {
3118                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3119            }
3120            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3121
3122            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3123                    UserHandle.getUserId(uid), startResult.pid, uid,
3124                    app.processName, hostingType,
3125                    hostingNameStr != null ? hostingNameStr : "");
3126
3127            if (app.persistent) {
3128                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3129            }
3130
3131            StringBuilder buf = mStringBuilder;
3132            buf.setLength(0);
3133            buf.append("Start proc ");
3134            buf.append(app.processName);
3135            if (!isActivityProcess) {
3136                buf.append(" [");
3137                buf.append(entryPoint);
3138                buf.append("]");
3139            }
3140            buf.append(" for ");
3141            buf.append(hostingType);
3142            if (hostingNameStr != null) {
3143                buf.append(" ");
3144                buf.append(hostingNameStr);
3145            }
3146            buf.append(": pid=");
3147            buf.append(startResult.pid);
3148            buf.append(" uid=");
3149            buf.append(uid);
3150            buf.append(" gids={");
3151            if (gids != null) {
3152                for (int gi=0; gi<gids.length; gi++) {
3153                    if (gi != 0) buf.append(", ");
3154                    buf.append(gids[gi]);
3155
3156                }
3157            }
3158            buf.append("}");
3159            if (requiredAbi != null) {
3160                buf.append(" abi=");
3161                buf.append(requiredAbi);
3162            }
3163            Slog.i(TAG, buf.toString());
3164            app.setPid(startResult.pid);
3165            app.usingWrapper = startResult.usingWrapper;
3166            app.removed = false;
3167            app.killedByAm = false;
3168            synchronized (mPidsSelfLocked) {
3169                this.mPidsSelfLocked.put(startResult.pid, app);
3170                if (isActivityProcess) {
3171                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3172                    msg.obj = app;
3173                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3174                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3175                }
3176            }
3177        } catch (RuntimeException e) {
3178            // XXX do better error recovery.
3179            app.setPid(0);
3180            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3181            if (app.isolated) {
3182                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3183            }
3184            Slog.e(TAG, "Failure starting process " + app.processName, e);
3185        }
3186    }
3187
3188    void updateUsageStats(ActivityRecord component, boolean resumed) {
3189        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3190        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3191        if (resumed) {
3192            if (mUsageStatsService != null) {
3193                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3194                        System.currentTimeMillis(),
3195                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3196            }
3197            synchronized (stats) {
3198                stats.noteActivityResumedLocked(component.app.uid);
3199            }
3200        } else {
3201            if (mUsageStatsService != null) {
3202                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3203                        System.currentTimeMillis(),
3204                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3205            }
3206            synchronized (stats) {
3207                stats.noteActivityPausedLocked(component.app.uid);
3208            }
3209        }
3210    }
3211
3212    Intent getHomeIntent() {
3213        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3214        intent.setComponent(mTopComponent);
3215        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3216            intent.addCategory(Intent.CATEGORY_HOME);
3217        }
3218        return intent;
3219    }
3220
3221    boolean startHomeActivityLocked(int userId) {
3222        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3223                && mTopAction == null) {
3224            // We are running in factory test mode, but unable to find
3225            // the factory test app, so just sit around displaying the
3226            // error message and don't try to start anything.
3227            return false;
3228        }
3229        Intent intent = getHomeIntent();
3230        ActivityInfo aInfo =
3231            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3232        if (aInfo != null) {
3233            intent.setComponent(new ComponentName(
3234                    aInfo.applicationInfo.packageName, aInfo.name));
3235            // Don't do this if the home app is currently being
3236            // instrumented.
3237            aInfo = new ActivityInfo(aInfo);
3238            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3239            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3240                    aInfo.applicationInfo.uid, true);
3241            if (app == null || app.instrumentationClass == null) {
3242                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3243                mStackSupervisor.startHomeActivity(intent, aInfo);
3244            }
3245        }
3246
3247        return true;
3248    }
3249
3250    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3251        ActivityInfo ai = null;
3252        ComponentName comp = intent.getComponent();
3253        try {
3254            if (comp != null) {
3255                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3256            } else {
3257                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3258                        intent,
3259                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3260                            flags, userId);
3261
3262                if (info != null) {
3263                    ai = info.activityInfo;
3264                }
3265            }
3266        } catch (RemoteException e) {
3267            // ignore
3268        }
3269
3270        return ai;
3271    }
3272
3273    /**
3274     * Starts the "new version setup screen" if appropriate.
3275     */
3276    void startSetupActivityLocked() {
3277        // Only do this once per boot.
3278        if (mCheckedForSetup) {
3279            return;
3280        }
3281
3282        // We will show this screen if the current one is a different
3283        // version than the last one shown, and we are not running in
3284        // low-level factory test mode.
3285        final ContentResolver resolver = mContext.getContentResolver();
3286        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3287                Settings.Global.getInt(resolver,
3288                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3289            mCheckedForSetup = true;
3290
3291            // See if we should be showing the platform update setup UI.
3292            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3293            List<ResolveInfo> ris = mContext.getPackageManager()
3294                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3295
3296            // We don't allow third party apps to replace this.
3297            ResolveInfo ri = null;
3298            for (int i=0; ris != null && i<ris.size(); i++) {
3299                if ((ris.get(i).activityInfo.applicationInfo.flags
3300                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3301                    ri = ris.get(i);
3302                    break;
3303                }
3304            }
3305
3306            if (ri != null) {
3307                String vers = ri.activityInfo.metaData != null
3308                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3309                        : null;
3310                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3311                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3312                            Intent.METADATA_SETUP_VERSION);
3313                }
3314                String lastVers = Settings.Secure.getString(
3315                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3316                if (vers != null && !vers.equals(lastVers)) {
3317                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3318                    intent.setComponent(new ComponentName(
3319                            ri.activityInfo.packageName, ri.activityInfo.name));
3320                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3321                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3322                }
3323            }
3324        }
3325    }
3326
3327    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3328        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3329    }
3330
3331    void enforceNotIsolatedCaller(String caller) {
3332        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3333            throw new SecurityException("Isolated process not allowed to call " + caller);
3334        }
3335    }
3336
3337    @Override
3338    public int getFrontActivityScreenCompatMode() {
3339        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3340        synchronized (this) {
3341            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3342        }
3343    }
3344
3345    @Override
3346    public void setFrontActivityScreenCompatMode(int mode) {
3347        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3348                "setFrontActivityScreenCompatMode");
3349        synchronized (this) {
3350            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3351        }
3352    }
3353
3354    @Override
3355    public int getPackageScreenCompatMode(String packageName) {
3356        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3357        synchronized (this) {
3358            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3359        }
3360    }
3361
3362    @Override
3363    public void setPackageScreenCompatMode(String packageName, int mode) {
3364        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3365                "setPackageScreenCompatMode");
3366        synchronized (this) {
3367            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3368        }
3369    }
3370
3371    @Override
3372    public boolean getPackageAskScreenCompat(String packageName) {
3373        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3374        synchronized (this) {
3375            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3376        }
3377    }
3378
3379    @Override
3380    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3381        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3382                "setPackageAskScreenCompat");
3383        synchronized (this) {
3384            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3385        }
3386    }
3387
3388    private void dispatchProcessesChanged() {
3389        int N;
3390        synchronized (this) {
3391            N = mPendingProcessChanges.size();
3392            if (mActiveProcessChanges.length < N) {
3393                mActiveProcessChanges = new ProcessChangeItem[N];
3394            }
3395            mPendingProcessChanges.toArray(mActiveProcessChanges);
3396            mAvailProcessChanges.addAll(mPendingProcessChanges);
3397            mPendingProcessChanges.clear();
3398            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3399        }
3400
3401        int i = mProcessObservers.beginBroadcast();
3402        while (i > 0) {
3403            i--;
3404            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3405            if (observer != null) {
3406                try {
3407                    for (int j=0; j<N; j++) {
3408                        ProcessChangeItem item = mActiveProcessChanges[j];
3409                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3410                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3411                                    + item.pid + " uid=" + item.uid + ": "
3412                                    + item.foregroundActivities);
3413                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3414                                    item.foregroundActivities);
3415                        }
3416                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3417                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3418                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3419                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3420                        }
3421                    }
3422                } catch (RemoteException e) {
3423                }
3424            }
3425        }
3426        mProcessObservers.finishBroadcast();
3427    }
3428
3429    private void dispatchProcessDied(int pid, int uid) {
3430        int i = mProcessObservers.beginBroadcast();
3431        while (i > 0) {
3432            i--;
3433            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3434            if (observer != null) {
3435                try {
3436                    observer.onProcessDied(pid, uid);
3437                } catch (RemoteException e) {
3438                }
3439            }
3440        }
3441        mProcessObservers.finishBroadcast();
3442    }
3443
3444    @Override
3445    public final int startActivity(IApplicationThread caller, String callingPackage,
3446            Intent intent, String resolvedType, IBinder resultTo,
3447            String resultWho, int requestCode, int startFlags,
3448            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3449        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3450                resultWho, requestCode,
3451                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3452    }
3453
3454    @Override
3455    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3456            Intent intent, String resolvedType, IBinder resultTo,
3457            String resultWho, int requestCode, int startFlags,
3458            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3459        enforceNotIsolatedCaller("startActivity");
3460        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3461                false, ALLOW_FULL_ONLY, "startActivity", null);
3462        // TODO: Switch to user app stacks here.
3463        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3464                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3465                null, null, options, userId, null);
3466    }
3467
3468    @Override
3469    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3470            Intent intent, String resolvedType, IBinder resultTo,
3471            String resultWho, int requestCode, int startFlags,
3472            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3473
3474        // This is very dangerous -- it allows you to perform a start activity (including
3475        // permission grants) as any app that may launch one of your own activities.  So
3476        // we will only allow this to be done from activities that are part of the core framework,
3477        // and then only when they are running as the system.
3478        final ActivityRecord sourceRecord;
3479        final int targetUid;
3480        final String targetPackage;
3481        synchronized (this) {
3482            if (resultTo == null) {
3483                throw new SecurityException("Must be called from an activity");
3484            }
3485            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3486            if (sourceRecord == null) {
3487                throw new SecurityException("Called with bad activity token: " + resultTo);
3488            }
3489            if (!sourceRecord.info.packageName.equals("android")) {
3490                throw new SecurityException(
3491                        "Must be called from an activity that is declared in the android package");
3492            }
3493            if (sourceRecord.app == null) {
3494                throw new SecurityException("Called without a process attached to activity");
3495            }
3496            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3497                // This is still okay, as long as this activity is running under the
3498                // uid of the original calling activity.
3499                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3500                    throw new SecurityException(
3501                            "Calling activity in uid " + sourceRecord.app.uid
3502                                    + " must be system uid or original calling uid "
3503                                    + sourceRecord.launchedFromUid);
3504                }
3505            }
3506            targetUid = sourceRecord.launchedFromUid;
3507            targetPackage = sourceRecord.launchedFromPackage;
3508        }
3509
3510        // TODO: Switch to user app stacks here.
3511        try {
3512            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3513                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3514                    null, null, null, null, options, UserHandle.getUserId(sourceRecord.app.uid),
3515                    null);
3516            return ret;
3517        } catch (SecurityException e) {
3518            // XXX need to figure out how to propagate to original app.
3519            // A SecurityException here is generally actually a fault of the original
3520            // calling activity (such as a fairly granting permissions), so propagate it
3521            // back to them.
3522            /*
3523            StringBuilder msg = new StringBuilder();
3524            msg.append("While launching");
3525            msg.append(intent.toString());
3526            msg.append(": ");
3527            msg.append(e.getMessage());
3528            */
3529            throw e;
3530        }
3531    }
3532
3533    @Override
3534    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3535            Intent intent, String resolvedType, IBinder resultTo,
3536            String resultWho, int requestCode, int startFlags, String profileFile,
3537            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3538        enforceNotIsolatedCaller("startActivityAndWait");
3539        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3540                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3541        WaitResult res = new WaitResult();
3542        // TODO: Switch to user app stacks here.
3543        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3544                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3545                res, null, options, userId, null);
3546        return res;
3547    }
3548
3549    @Override
3550    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3551            Intent intent, String resolvedType, IBinder resultTo,
3552            String resultWho, int requestCode, int startFlags, Configuration config,
3553            Bundle options, int userId) {
3554        enforceNotIsolatedCaller("startActivityWithConfig");
3555        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3556                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3557        // TODO: Switch to user app stacks here.
3558        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3559                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3560                null, null, null, config, options, userId, null);
3561        return ret;
3562    }
3563
3564    @Override
3565    public int startActivityIntentSender(IApplicationThread caller,
3566            IntentSender intent, Intent fillInIntent, String resolvedType,
3567            IBinder resultTo, String resultWho, int requestCode,
3568            int flagsMask, int flagsValues, Bundle options) {
3569        enforceNotIsolatedCaller("startActivityIntentSender");
3570        // Refuse possible leaked file descriptors
3571        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3572            throw new IllegalArgumentException("File descriptors passed in Intent");
3573        }
3574
3575        IIntentSender sender = intent.getTarget();
3576        if (!(sender instanceof PendingIntentRecord)) {
3577            throw new IllegalArgumentException("Bad PendingIntent object");
3578        }
3579
3580        PendingIntentRecord pir = (PendingIntentRecord)sender;
3581
3582        synchronized (this) {
3583            // If this is coming from the currently resumed activity, it is
3584            // effectively saying that app switches are allowed at this point.
3585            final ActivityStack stack = getFocusedStack();
3586            if (stack.mResumedActivity != null &&
3587                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3588                mAppSwitchesAllowedTime = 0;
3589            }
3590        }
3591        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3592                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3593        return ret;
3594    }
3595
3596    @Override
3597    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3598            Intent intent, String resolvedType, IVoiceInteractionSession session,
3599            IVoiceInteractor interactor, int startFlags, String profileFile,
3600            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3601        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3602                != PackageManager.PERMISSION_GRANTED) {
3603            String msg = "Permission Denial: startVoiceActivity() from pid="
3604                    + Binder.getCallingPid()
3605                    + ", uid=" + Binder.getCallingUid()
3606                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3607            Slog.w(TAG, msg);
3608            throw new SecurityException(msg);
3609        }
3610        if (session == null || interactor == null) {
3611            throw new NullPointerException("null session or interactor");
3612        }
3613        userId = handleIncomingUser(callingPid, callingUid, userId,
3614                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3615        // TODO: Switch to user app stacks here.
3616        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3617                resolvedType, session, interactor, null, null, 0, startFlags,
3618                profileFile, profileFd, null, null, options, userId, null);
3619    }
3620
3621    @Override
3622    public boolean startNextMatchingActivity(IBinder callingActivity,
3623            Intent intent, Bundle options) {
3624        // Refuse possible leaked file descriptors
3625        if (intent != null && intent.hasFileDescriptors() == true) {
3626            throw new IllegalArgumentException("File descriptors passed in Intent");
3627        }
3628
3629        synchronized (this) {
3630            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3631            if (r == null) {
3632                ActivityOptions.abort(options);
3633                return false;
3634            }
3635            if (r.app == null || r.app.thread == null) {
3636                // The caller is not running...  d'oh!
3637                ActivityOptions.abort(options);
3638                return false;
3639            }
3640            intent = new Intent(intent);
3641            // The caller is not allowed to change the data.
3642            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3643            // And we are resetting to find the next component...
3644            intent.setComponent(null);
3645
3646            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3647
3648            ActivityInfo aInfo = null;
3649            try {
3650                List<ResolveInfo> resolves =
3651                    AppGlobals.getPackageManager().queryIntentActivities(
3652                            intent, r.resolvedType,
3653                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3654                            UserHandle.getCallingUserId());
3655
3656                // Look for the original activity in the list...
3657                final int N = resolves != null ? resolves.size() : 0;
3658                for (int i=0; i<N; i++) {
3659                    ResolveInfo rInfo = resolves.get(i);
3660                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3661                            && rInfo.activityInfo.name.equals(r.info.name)) {
3662                        // We found the current one...  the next matching is
3663                        // after it.
3664                        i++;
3665                        if (i<N) {
3666                            aInfo = resolves.get(i).activityInfo;
3667                        }
3668                        if (debug) {
3669                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3670                                    + "/" + r.info.name);
3671                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3672                                    + "/" + aInfo.name);
3673                        }
3674                        break;
3675                    }
3676                }
3677            } catch (RemoteException e) {
3678            }
3679
3680            if (aInfo == null) {
3681                // Nobody who is next!
3682                ActivityOptions.abort(options);
3683                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3684                return false;
3685            }
3686
3687            intent.setComponent(new ComponentName(
3688                    aInfo.applicationInfo.packageName, aInfo.name));
3689            intent.setFlags(intent.getFlags()&~(
3690                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3691                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3692                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3693                    Intent.FLAG_ACTIVITY_NEW_TASK));
3694
3695            // Okay now we need to start the new activity, replacing the
3696            // currently running activity.  This is a little tricky because
3697            // we want to start the new one as if the current one is finished,
3698            // but not finish the current one first so that there is no flicker.
3699            // And thus...
3700            final boolean wasFinishing = r.finishing;
3701            r.finishing = true;
3702
3703            // Propagate reply information over to the new activity.
3704            final ActivityRecord resultTo = r.resultTo;
3705            final String resultWho = r.resultWho;
3706            final int requestCode = r.requestCode;
3707            r.resultTo = null;
3708            if (resultTo != null) {
3709                resultTo.removeResultsLocked(r, resultWho, requestCode);
3710            }
3711
3712            final long origId = Binder.clearCallingIdentity();
3713            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3714                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3715                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3716                    options, false, null, null);
3717            Binder.restoreCallingIdentity(origId);
3718
3719            r.finishing = wasFinishing;
3720            if (res != ActivityManager.START_SUCCESS) {
3721                return false;
3722            }
3723            return true;
3724        }
3725    }
3726
3727    @Override
3728    public final int startActivityFromRecents(int taskId, Bundle options) {
3729        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3730            String msg = "Permission Denial: startActivityFromRecents called without " +
3731                    START_TASKS_FROM_RECENTS;
3732            Slog.w(TAG, msg);
3733            throw new SecurityException(msg);
3734        }
3735        final int callingUid;
3736        final String callingPackage;
3737        final Intent intent;
3738        final int userId;
3739        synchronized (this) {
3740            final TaskRecord task = recentTaskForIdLocked(taskId);
3741            if (task == null) {
3742                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3743            }
3744            callingUid = task.mCallingUid;
3745            callingPackage = task.mCallingPackage;
3746            intent = task.intent;
3747            userId = task.userId;
3748        }
3749        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3750                options, userId, null);
3751    }
3752
3753    final int startActivityInPackage(int uid, String callingPackage,
3754            Intent intent, String resolvedType, IBinder resultTo,
3755            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3756                    IActivityContainer container) {
3757
3758        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3759                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3760
3761        // TODO: Switch to user app stacks here.
3762        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3763                null, null, resultTo, resultWho, requestCode, startFlags,
3764                null, null, null, null, options, userId, container);
3765        return ret;
3766    }
3767
3768    @Override
3769    public final int startActivities(IApplicationThread caller, String callingPackage,
3770            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3771            int userId) {
3772        enforceNotIsolatedCaller("startActivities");
3773        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3774                false, ALLOW_FULL_ONLY, "startActivity", null);
3775        // TODO: Switch to user app stacks here.
3776        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3777                resolvedTypes, resultTo, options, userId);
3778        return ret;
3779    }
3780
3781    final int startActivitiesInPackage(int uid, String callingPackage,
3782            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3783            Bundle options, int userId) {
3784
3785        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3786                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3787        // TODO: Switch to user app stacks here.
3788        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3789                resultTo, options, userId);
3790        return ret;
3791    }
3792
3793    //explicitly remove thd old information in mRecentTasks when removing existing user.
3794    private void removeRecentTasksForUserLocked(int userId) {
3795        if(userId <= 0) {
3796            Slog.i(TAG, "Can't remove recent task on user " + userId);
3797            return;
3798        }
3799
3800        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3801            TaskRecord tr = mRecentTasks.get(i);
3802            if (tr.userId == userId) {
3803                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3804                        + " when finishing user" + userId);
3805                tr.disposeThumbnail();
3806                mRecentTasks.remove(i);
3807            }
3808        }
3809
3810        // Remove tasks from persistent storage.
3811        mTaskPersister.wakeup(null, true);
3812    }
3813
3814    final void addRecentTaskLocked(TaskRecord task) {
3815        final int N = mRecentTasks.size();
3816        // Quick case: check if the top-most recent task is the same.
3817        if (N > 0 && mRecentTasks.get(0) == task) {
3818            return;
3819        }
3820        // Another quick case: never add voice sessions.
3821        if (task.voiceSession != null) {
3822            return;
3823        }
3824
3825        trimRecentsForTask(task, true);
3826
3827        if (N >= MAX_RECENT_TASKS) {
3828            final TaskRecord tr = mRecentTasks.remove(N - 1);
3829            tr.disposeThumbnail();
3830            tr.closeRecentsChain();
3831        }
3832        mRecentTasks.add(0, task);
3833    }
3834
3835    /**
3836     * If needed, remove oldest existing entries in recents that are for the same kind
3837     * of task as the given one.
3838     */
3839    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
3840        int N = mRecentTasks.size();
3841        final Intent intent = task.intent;
3842        final boolean document = intent != null && intent.isDocument();
3843
3844        int maxRecents = task.maxRecents - 1;
3845        for (int i=0; i<N; i++) {
3846            final TaskRecord tr = mRecentTasks.get(i);
3847            if (task != tr) {
3848                if (task.userId != tr.userId) {
3849                    continue;
3850                }
3851                if (i > MAX_RECENT_BITMAPS) {
3852                    tr.freeLastThumbnail();
3853                }
3854                final Intent trIntent = tr.intent;
3855                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3856                    (intent == null || !intent.filterEquals(trIntent))) {
3857                    continue;
3858                }
3859                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3860                if (document && trIsDocument) {
3861                    // These are the same document activity (not necessarily the same doc).
3862                    if (maxRecents > 0) {
3863                        --maxRecents;
3864                        continue;
3865                    }
3866                    // Hit the maximum number of documents for this task. Fall through
3867                    // and remove this document from recents.
3868                } else if (document || trIsDocument) {
3869                    // Only one of these is a document. Not the droid we're looking for.
3870                    continue;
3871                }
3872            }
3873
3874            if (!doTrim) {
3875                // If the caller is not actually asking for a trim, just tell them we reached
3876                // a point where the trim would happen.
3877                return i;
3878            }
3879
3880            // Either task and tr are the same or, their affinities match or their intents match
3881            // and neither of them is a document, or they are documents using the same activity
3882            // and their maxRecents has been reached.
3883            tr.disposeThumbnail();
3884            mRecentTasks.remove(i);
3885            if (task != tr) {
3886                tr.closeRecentsChain();
3887            }
3888            i--;
3889            N--;
3890            if (task.intent == null) {
3891                // If the new recent task we are adding is not fully
3892                // specified, then replace it with the existing recent task.
3893                task = tr;
3894            }
3895            notifyTaskPersisterLocked(tr, false);
3896        }
3897
3898        return -1;
3899    }
3900
3901    @Override
3902    public void reportActivityFullyDrawn(IBinder token) {
3903        synchronized (this) {
3904            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3905            if (r == null) {
3906                return;
3907            }
3908            r.reportFullyDrawnLocked();
3909        }
3910    }
3911
3912    @Override
3913    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3914        synchronized (this) {
3915            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3916            if (r == null) {
3917                return;
3918            }
3919            final long origId = Binder.clearCallingIdentity();
3920            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3921            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3922                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3923            if (config != null) {
3924                r.frozenBeforeDestroy = true;
3925                if (!updateConfigurationLocked(config, r, false, false)) {
3926                    mStackSupervisor.resumeTopActivitiesLocked();
3927                }
3928            }
3929            Binder.restoreCallingIdentity(origId);
3930        }
3931    }
3932
3933    @Override
3934    public int getRequestedOrientation(IBinder token) {
3935        synchronized (this) {
3936            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3937            if (r == null) {
3938                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3939            }
3940            return mWindowManager.getAppOrientation(r.appToken);
3941        }
3942    }
3943
3944    /**
3945     * This is the internal entry point for handling Activity.finish().
3946     *
3947     * @param token The Binder token referencing the Activity we want to finish.
3948     * @param resultCode Result code, if any, from this Activity.
3949     * @param resultData Result data (Intent), if any, from this Activity.
3950     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3951     *            the root Activity in the task.
3952     *
3953     * @return Returns true if the activity successfully finished, or false if it is still running.
3954     */
3955    @Override
3956    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3957            boolean finishTask) {
3958        // Refuse possible leaked file descriptors
3959        if (resultData != null && resultData.hasFileDescriptors() == true) {
3960            throw new IllegalArgumentException("File descriptors passed in Intent");
3961        }
3962
3963        synchronized(this) {
3964            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3965            if (r == null) {
3966                return true;
3967            }
3968            // Keep track of the root activity of the task before we finish it
3969            TaskRecord tr = r.task;
3970            ActivityRecord rootR = tr.getRootActivity();
3971            // Do not allow task to finish in Lock Task mode.
3972            if (tr == mStackSupervisor.mLockTaskModeTask) {
3973                if (rootR == r) {
3974                    mStackSupervisor.showLockTaskToast();
3975                    return false;
3976                }
3977            }
3978            if (mController != null) {
3979                // Find the first activity that is not finishing.
3980                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3981                if (next != null) {
3982                    // ask watcher if this is allowed
3983                    boolean resumeOK = true;
3984                    try {
3985                        resumeOK = mController.activityResuming(next.packageName);
3986                    } catch (RemoteException e) {
3987                        mController = null;
3988                        Watchdog.getInstance().setActivityController(null);
3989                    }
3990
3991                    if (!resumeOK) {
3992                        return false;
3993                    }
3994                }
3995            }
3996            final long origId = Binder.clearCallingIdentity();
3997            try {
3998                boolean res;
3999                if (finishTask && r == rootR) {
4000                    // If requested, remove the task that is associated to this activity only if it
4001                    // was the root activity in the task.  The result code and data is ignored because
4002                    // we don't support returning them across task boundaries.
4003                    res = removeTaskByIdLocked(tr.taskId, 0);
4004                } else {
4005                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4006                            resultData, "app-request", true);
4007                }
4008                return res;
4009            } finally {
4010                Binder.restoreCallingIdentity(origId);
4011            }
4012        }
4013    }
4014
4015    @Override
4016    public final void finishHeavyWeightApp() {
4017        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4018                != PackageManager.PERMISSION_GRANTED) {
4019            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4020                    + Binder.getCallingPid()
4021                    + ", uid=" + Binder.getCallingUid()
4022                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4023            Slog.w(TAG, msg);
4024            throw new SecurityException(msg);
4025        }
4026
4027        synchronized(this) {
4028            if (mHeavyWeightProcess == null) {
4029                return;
4030            }
4031
4032            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4033                    mHeavyWeightProcess.activities);
4034            for (int i=0; i<activities.size(); i++) {
4035                ActivityRecord r = activities.get(i);
4036                if (!r.finishing) {
4037                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4038                            null, "finish-heavy", true);
4039                }
4040            }
4041
4042            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4043                    mHeavyWeightProcess.userId, 0));
4044            mHeavyWeightProcess = null;
4045        }
4046    }
4047
4048    @Override
4049    public void crashApplication(int uid, int initialPid, String packageName,
4050            String message) {
4051        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4052                != PackageManager.PERMISSION_GRANTED) {
4053            String msg = "Permission Denial: crashApplication() from pid="
4054                    + Binder.getCallingPid()
4055                    + ", uid=" + Binder.getCallingUid()
4056                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4057            Slog.w(TAG, msg);
4058            throw new SecurityException(msg);
4059        }
4060
4061        synchronized(this) {
4062            ProcessRecord proc = null;
4063
4064            // Figure out which process to kill.  We don't trust that initialPid
4065            // still has any relation to current pids, so must scan through the
4066            // list.
4067            synchronized (mPidsSelfLocked) {
4068                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4069                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4070                    if (p.uid != uid) {
4071                        continue;
4072                    }
4073                    if (p.pid == initialPid) {
4074                        proc = p;
4075                        break;
4076                    }
4077                    if (p.pkgList.containsKey(packageName)) {
4078                        proc = p;
4079                    }
4080                }
4081            }
4082
4083            if (proc == null) {
4084                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4085                        + " initialPid=" + initialPid
4086                        + " packageName=" + packageName);
4087                return;
4088            }
4089
4090            if (proc.thread != null) {
4091                if (proc.pid == Process.myPid()) {
4092                    Log.w(TAG, "crashApplication: trying to crash self!");
4093                    return;
4094                }
4095                long ident = Binder.clearCallingIdentity();
4096                try {
4097                    proc.thread.scheduleCrash(message);
4098                } catch (RemoteException e) {
4099                }
4100                Binder.restoreCallingIdentity(ident);
4101            }
4102        }
4103    }
4104
4105    @Override
4106    public final void finishSubActivity(IBinder token, String resultWho,
4107            int requestCode) {
4108        synchronized(this) {
4109            final long origId = Binder.clearCallingIdentity();
4110            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4111            if (r != null) {
4112                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4113            }
4114            Binder.restoreCallingIdentity(origId);
4115        }
4116    }
4117
4118    @Override
4119    public boolean finishActivityAffinity(IBinder token) {
4120        synchronized(this) {
4121            final long origId = Binder.clearCallingIdentity();
4122            try {
4123                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4124
4125                ActivityRecord rootR = r.task.getRootActivity();
4126                // Do not allow task to finish in Lock Task mode.
4127                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4128                    if (rootR == r) {
4129                        mStackSupervisor.showLockTaskToast();
4130                        return false;
4131                    }
4132                }
4133                boolean res = false;
4134                if (r != null) {
4135                    res = r.task.stack.finishActivityAffinityLocked(r);
4136                }
4137                return res;
4138            } finally {
4139                Binder.restoreCallingIdentity(origId);
4140            }
4141        }
4142    }
4143
4144    @Override
4145    public void finishVoiceTask(IVoiceInteractionSession session) {
4146        synchronized(this) {
4147            final long origId = Binder.clearCallingIdentity();
4148            try {
4149                mStackSupervisor.finishVoiceTask(session);
4150            } finally {
4151                Binder.restoreCallingIdentity(origId);
4152            }
4153        }
4154
4155    }
4156
4157    @Override
4158    public boolean willActivityBeVisible(IBinder token) {
4159        synchronized(this) {
4160            ActivityStack stack = ActivityRecord.getStackLocked(token);
4161            if (stack != null) {
4162                return stack.willActivityBeVisibleLocked(token);
4163            }
4164            return false;
4165        }
4166    }
4167
4168    @Override
4169    public void overridePendingTransition(IBinder token, String packageName,
4170            int enterAnim, int exitAnim) {
4171        synchronized(this) {
4172            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4173            if (self == null) {
4174                return;
4175            }
4176
4177            final long origId = Binder.clearCallingIdentity();
4178
4179            if (self.state == ActivityState.RESUMED
4180                    || self.state == ActivityState.PAUSING) {
4181                mWindowManager.overridePendingAppTransition(packageName,
4182                        enterAnim, exitAnim, null);
4183            }
4184
4185            Binder.restoreCallingIdentity(origId);
4186        }
4187    }
4188
4189    /**
4190     * Main function for removing an existing process from the activity manager
4191     * as a result of that process going away.  Clears out all connections
4192     * to the process.
4193     */
4194    private final void handleAppDiedLocked(ProcessRecord app,
4195            boolean restarting, boolean allowRestart) {
4196        int pid = app.pid;
4197        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4198        if (!restarting) {
4199            removeLruProcessLocked(app);
4200            if (pid > 0) {
4201                ProcessList.remove(pid);
4202            }
4203        }
4204
4205        if (mProfileProc == app) {
4206            clearProfilerLocked();
4207        }
4208
4209        // Remove this application's activities from active lists.
4210        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4211
4212        app.activities.clear();
4213
4214        if (app.instrumentationClass != null) {
4215            Slog.w(TAG, "Crash of app " + app.processName
4216                  + " running instrumentation " + app.instrumentationClass);
4217            Bundle info = new Bundle();
4218            info.putString("shortMsg", "Process crashed.");
4219            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4220        }
4221
4222        if (!restarting) {
4223            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4224                // If there was nothing to resume, and we are not already
4225                // restarting this process, but there is a visible activity that
4226                // is hosted by the process...  then make sure all visible
4227                // activities are running, taking care of restarting this
4228                // process.
4229                if (hasVisibleActivities) {
4230                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4231                }
4232            }
4233        }
4234    }
4235
4236    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4237        IBinder threadBinder = thread.asBinder();
4238        // Find the application record.
4239        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4240            ProcessRecord rec = mLruProcesses.get(i);
4241            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4242                return i;
4243            }
4244        }
4245        return -1;
4246    }
4247
4248    final ProcessRecord getRecordForAppLocked(
4249            IApplicationThread thread) {
4250        if (thread == null) {
4251            return null;
4252        }
4253
4254        int appIndex = getLRURecordIndexForAppLocked(thread);
4255        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4256    }
4257
4258    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4259        // If there are no longer any background processes running,
4260        // and the app that died was not running instrumentation,
4261        // then tell everyone we are now low on memory.
4262        boolean haveBg = false;
4263        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4264            ProcessRecord rec = mLruProcesses.get(i);
4265            if (rec.thread != null
4266                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4267                haveBg = true;
4268                break;
4269            }
4270        }
4271
4272        if (!haveBg) {
4273            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4274            if (doReport) {
4275                long now = SystemClock.uptimeMillis();
4276                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4277                    doReport = false;
4278                } else {
4279                    mLastMemUsageReportTime = now;
4280                }
4281            }
4282            final ArrayList<ProcessMemInfo> memInfos
4283                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4284            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4285            long now = SystemClock.uptimeMillis();
4286            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4287                ProcessRecord rec = mLruProcesses.get(i);
4288                if (rec == dyingProc || rec.thread == null) {
4289                    continue;
4290                }
4291                if (doReport) {
4292                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4293                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4294                }
4295                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4296                    // The low memory report is overriding any current
4297                    // state for a GC request.  Make sure to do
4298                    // heavy/important/visible/foreground processes first.
4299                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4300                        rec.lastRequestedGc = 0;
4301                    } else {
4302                        rec.lastRequestedGc = rec.lastLowMemory;
4303                    }
4304                    rec.reportLowMemory = true;
4305                    rec.lastLowMemory = now;
4306                    mProcessesToGc.remove(rec);
4307                    addProcessToGcListLocked(rec);
4308                }
4309            }
4310            if (doReport) {
4311                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4312                mHandler.sendMessage(msg);
4313            }
4314            scheduleAppGcsLocked();
4315        }
4316    }
4317
4318    final void appDiedLocked(ProcessRecord app) {
4319       appDiedLocked(app, app.pid, app.thread);
4320    }
4321
4322    final void appDiedLocked(ProcessRecord app, int pid,
4323            IApplicationThread thread) {
4324
4325        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4326        synchronized (stats) {
4327            stats.noteProcessDiedLocked(app.info.uid, pid);
4328        }
4329
4330        Process.killProcessGroup(app.info.uid, pid);
4331
4332        // Clean up already done if the process has been re-started.
4333        if (app.pid == pid && app.thread != null &&
4334                app.thread.asBinder() == thread.asBinder()) {
4335            boolean doLowMem = app.instrumentationClass == null;
4336            boolean doOomAdj = doLowMem;
4337            if (!app.killedByAm) {
4338                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4339                        + ") has died.");
4340                mAllowLowerMemLevel = true;
4341            } else {
4342                // Note that we always want to do oom adj to update our state with the
4343                // new number of procs.
4344                mAllowLowerMemLevel = false;
4345                doLowMem = false;
4346            }
4347            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4348            if (DEBUG_CLEANUP) Slog.v(
4349                TAG, "Dying app: " + app + ", pid: " + pid
4350                + ", thread: " + thread.asBinder());
4351            handleAppDiedLocked(app, false, true);
4352
4353            if (doOomAdj) {
4354                updateOomAdjLocked();
4355            }
4356            if (doLowMem) {
4357                doLowMemReportIfNeededLocked(app);
4358            }
4359        } else if (app.pid != pid) {
4360            // A new process has already been started.
4361            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4362                    + ") has died and restarted (pid " + app.pid + ").");
4363            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4364        } else if (DEBUG_PROCESSES) {
4365            Slog.d(TAG, "Received spurious death notification for thread "
4366                    + thread.asBinder());
4367        }
4368    }
4369
4370    /**
4371     * If a stack trace dump file is configured, dump process stack traces.
4372     * @param clearTraces causes the dump file to be erased prior to the new
4373     *    traces being written, if true; when false, the new traces will be
4374     *    appended to any existing file content.
4375     * @param firstPids of dalvik VM processes to dump stack traces for first
4376     * @param lastPids of dalvik VM processes to dump stack traces for last
4377     * @param nativeProcs optional list of native process names to dump stack crawls
4378     * @return file containing stack traces, or null if no dump file is configured
4379     */
4380    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4381            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4382        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4383        if (tracesPath == null || tracesPath.length() == 0) {
4384            return null;
4385        }
4386
4387        File tracesFile = new File(tracesPath);
4388        try {
4389            File tracesDir = tracesFile.getParentFile();
4390            if (!tracesDir.exists()) {
4391                tracesFile.mkdirs();
4392                if (!SELinux.restorecon(tracesDir)) {
4393                    return null;
4394                }
4395            }
4396            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4397
4398            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4399            tracesFile.createNewFile();
4400            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4401        } catch (IOException e) {
4402            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4403            return null;
4404        }
4405
4406        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4407        return tracesFile;
4408    }
4409
4410    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4411            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4412        // Use a FileObserver to detect when traces finish writing.
4413        // The order of traces is considered important to maintain for legibility.
4414        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4415            @Override
4416            public synchronized void onEvent(int event, String path) { notify(); }
4417        };
4418
4419        try {
4420            observer.startWatching();
4421
4422            // First collect all of the stacks of the most important pids.
4423            if (firstPids != null) {
4424                try {
4425                    int num = firstPids.size();
4426                    for (int i = 0; i < num; i++) {
4427                        synchronized (observer) {
4428                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4429                            observer.wait(200);  // Wait for write-close, give up after 200msec
4430                        }
4431                    }
4432                } catch (InterruptedException e) {
4433                    Log.wtf(TAG, e);
4434                }
4435            }
4436
4437            // Next collect the stacks of the native pids
4438            if (nativeProcs != null) {
4439                int[] pids = Process.getPidsForCommands(nativeProcs);
4440                if (pids != null) {
4441                    for (int pid : pids) {
4442                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4443                    }
4444                }
4445            }
4446
4447            // Lastly, measure CPU usage.
4448            if (processCpuTracker != null) {
4449                processCpuTracker.init();
4450                System.gc();
4451                processCpuTracker.update();
4452                try {
4453                    synchronized (processCpuTracker) {
4454                        processCpuTracker.wait(500); // measure over 1/2 second.
4455                    }
4456                } catch (InterruptedException e) {
4457                }
4458                processCpuTracker.update();
4459
4460                // We'll take the stack crawls of just the top apps using CPU.
4461                final int N = processCpuTracker.countWorkingStats();
4462                int numProcs = 0;
4463                for (int i=0; i<N && numProcs<5; i++) {
4464                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4465                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4466                        numProcs++;
4467                        try {
4468                            synchronized (observer) {
4469                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4470                                observer.wait(200);  // Wait for write-close, give up after 200msec
4471                            }
4472                        } catch (InterruptedException e) {
4473                            Log.wtf(TAG, e);
4474                        }
4475
4476                    }
4477                }
4478            }
4479        } finally {
4480            observer.stopWatching();
4481        }
4482    }
4483
4484    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4485        if (true || IS_USER_BUILD) {
4486            return;
4487        }
4488        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4489        if (tracesPath == null || tracesPath.length() == 0) {
4490            return;
4491        }
4492
4493        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4494        StrictMode.allowThreadDiskWrites();
4495        try {
4496            final File tracesFile = new File(tracesPath);
4497            final File tracesDir = tracesFile.getParentFile();
4498            final File tracesTmp = new File(tracesDir, "__tmp__");
4499            try {
4500                if (!tracesDir.exists()) {
4501                    tracesFile.mkdirs();
4502                    if (!SELinux.restorecon(tracesDir.getPath())) {
4503                        return;
4504                    }
4505                }
4506                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4507
4508                if (tracesFile.exists()) {
4509                    tracesTmp.delete();
4510                    tracesFile.renameTo(tracesTmp);
4511                }
4512                StringBuilder sb = new StringBuilder();
4513                Time tobj = new Time();
4514                tobj.set(System.currentTimeMillis());
4515                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4516                sb.append(": ");
4517                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4518                sb.append(" since ");
4519                sb.append(msg);
4520                FileOutputStream fos = new FileOutputStream(tracesFile);
4521                fos.write(sb.toString().getBytes());
4522                if (app == null) {
4523                    fos.write("\n*** No application process!".getBytes());
4524                }
4525                fos.close();
4526                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4527            } catch (IOException e) {
4528                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4529                return;
4530            }
4531
4532            if (app != null) {
4533                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4534                firstPids.add(app.pid);
4535                dumpStackTraces(tracesPath, firstPids, null, null, null);
4536            }
4537
4538            File lastTracesFile = null;
4539            File curTracesFile = null;
4540            for (int i=9; i>=0; i--) {
4541                String name = String.format(Locale.US, "slow%02d.txt", i);
4542                curTracesFile = new File(tracesDir, name);
4543                if (curTracesFile.exists()) {
4544                    if (lastTracesFile != null) {
4545                        curTracesFile.renameTo(lastTracesFile);
4546                    } else {
4547                        curTracesFile.delete();
4548                    }
4549                }
4550                lastTracesFile = curTracesFile;
4551            }
4552            tracesFile.renameTo(curTracesFile);
4553            if (tracesTmp.exists()) {
4554                tracesTmp.renameTo(tracesFile);
4555            }
4556        } finally {
4557            StrictMode.setThreadPolicy(oldPolicy);
4558        }
4559    }
4560
4561    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4562            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4563        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4564        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4565
4566        if (mController != null) {
4567            try {
4568                // 0 == continue, -1 = kill process immediately
4569                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4570                if (res < 0 && app.pid != MY_PID) {
4571                    Process.killProcess(app.pid);
4572                    Process.killProcessGroup(app.info.uid, app.pid);
4573                }
4574            } catch (RemoteException e) {
4575                mController = null;
4576                Watchdog.getInstance().setActivityController(null);
4577            }
4578        }
4579
4580        long anrTime = SystemClock.uptimeMillis();
4581        if (MONITOR_CPU_USAGE) {
4582            updateCpuStatsNow();
4583        }
4584
4585        synchronized (this) {
4586            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4587            if (mShuttingDown) {
4588                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4589                return;
4590            } else if (app.notResponding) {
4591                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4592                return;
4593            } else if (app.crashing) {
4594                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4595                return;
4596            }
4597
4598            // In case we come through here for the same app before completing
4599            // this one, mark as anring now so we will bail out.
4600            app.notResponding = true;
4601
4602            // Log the ANR to the event log.
4603            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4604                    app.processName, app.info.flags, annotation);
4605
4606            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4607            firstPids.add(app.pid);
4608
4609            int parentPid = app.pid;
4610            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4611            if (parentPid != app.pid) firstPids.add(parentPid);
4612
4613            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4614
4615            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4616                ProcessRecord r = mLruProcesses.get(i);
4617                if (r != null && r.thread != null) {
4618                    int pid = r.pid;
4619                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4620                        if (r.persistent) {
4621                            firstPids.add(pid);
4622                        } else {
4623                            lastPids.put(pid, Boolean.TRUE);
4624                        }
4625                    }
4626                }
4627            }
4628        }
4629
4630        // Log the ANR to the main log.
4631        StringBuilder info = new StringBuilder();
4632        info.setLength(0);
4633        info.append("ANR in ").append(app.processName);
4634        if (activity != null && activity.shortComponentName != null) {
4635            info.append(" (").append(activity.shortComponentName).append(")");
4636        }
4637        info.append("\n");
4638        info.append("PID: ").append(app.pid).append("\n");
4639        if (annotation != null) {
4640            info.append("Reason: ").append(annotation).append("\n");
4641        }
4642        if (parent != null && parent != activity) {
4643            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4644        }
4645
4646        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4647
4648        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4649                NATIVE_STACKS_OF_INTEREST);
4650
4651        String cpuInfo = null;
4652        if (MONITOR_CPU_USAGE) {
4653            updateCpuStatsNow();
4654            synchronized (mProcessCpuThread) {
4655                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4656            }
4657            info.append(processCpuTracker.printCurrentLoad());
4658            info.append(cpuInfo);
4659        }
4660
4661        info.append(processCpuTracker.printCurrentState(anrTime));
4662
4663        Slog.e(TAG, info.toString());
4664        if (tracesFile == null) {
4665            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4666            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4667        }
4668
4669        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4670                cpuInfo, tracesFile, null);
4671
4672        if (mController != null) {
4673            try {
4674                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4675                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4676                if (res != 0) {
4677                    if (res < 0 && app.pid != MY_PID) {
4678                        Process.killProcess(app.pid);
4679                        Process.killProcessGroup(app.info.uid, app.pid);
4680                    } else {
4681                        synchronized (this) {
4682                            mServices.scheduleServiceTimeoutLocked(app);
4683                        }
4684                    }
4685                    return;
4686                }
4687            } catch (RemoteException e) {
4688                mController = null;
4689                Watchdog.getInstance().setActivityController(null);
4690            }
4691        }
4692
4693        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4694        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4695                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4696
4697        synchronized (this) {
4698            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4699                killUnneededProcessLocked(app, "background ANR");
4700                return;
4701            }
4702
4703            // Set the app's notResponding state, and look up the errorReportReceiver
4704            makeAppNotRespondingLocked(app,
4705                    activity != null ? activity.shortComponentName : null,
4706                    annotation != null ? "ANR " + annotation : "ANR",
4707                    info.toString());
4708
4709            // Bring up the infamous App Not Responding dialog
4710            Message msg = Message.obtain();
4711            HashMap<String, Object> map = new HashMap<String, Object>();
4712            msg.what = SHOW_NOT_RESPONDING_MSG;
4713            msg.obj = map;
4714            msg.arg1 = aboveSystem ? 1 : 0;
4715            map.put("app", app);
4716            if (activity != null) {
4717                map.put("activity", activity);
4718            }
4719
4720            mHandler.sendMessage(msg);
4721        }
4722    }
4723
4724    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4725        if (!mLaunchWarningShown) {
4726            mLaunchWarningShown = true;
4727            mHandler.post(new Runnable() {
4728                @Override
4729                public void run() {
4730                    synchronized (ActivityManagerService.this) {
4731                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4732                        d.show();
4733                        mHandler.postDelayed(new Runnable() {
4734                            @Override
4735                            public void run() {
4736                                synchronized (ActivityManagerService.this) {
4737                                    d.dismiss();
4738                                    mLaunchWarningShown = false;
4739                                }
4740                            }
4741                        }, 4000);
4742                    }
4743                }
4744            });
4745        }
4746    }
4747
4748    @Override
4749    public boolean clearApplicationUserData(final String packageName,
4750            final IPackageDataObserver observer, int userId) {
4751        enforceNotIsolatedCaller("clearApplicationUserData");
4752        int uid = Binder.getCallingUid();
4753        int pid = Binder.getCallingPid();
4754        userId = handleIncomingUser(pid, uid,
4755                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4756        long callingId = Binder.clearCallingIdentity();
4757        try {
4758            IPackageManager pm = AppGlobals.getPackageManager();
4759            int pkgUid = -1;
4760            synchronized(this) {
4761                try {
4762                    pkgUid = pm.getPackageUid(packageName, userId);
4763                } catch (RemoteException e) {
4764                }
4765                if (pkgUid == -1) {
4766                    Slog.w(TAG, "Invalid packageName: " + packageName);
4767                    if (observer != null) {
4768                        try {
4769                            observer.onRemoveCompleted(packageName, false);
4770                        } catch (RemoteException e) {
4771                            Slog.i(TAG, "Observer no longer exists.");
4772                        }
4773                    }
4774                    return false;
4775                }
4776                if (uid == pkgUid || checkComponentPermission(
4777                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4778                        pid, uid, -1, true)
4779                        == PackageManager.PERMISSION_GRANTED) {
4780                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4781                } else {
4782                    throw new SecurityException("PID " + pid + " does not have permission "
4783                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4784                                    + " of package " + packageName);
4785                }
4786
4787                // Remove all tasks match the cleared application package and user
4788                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4789                    final TaskRecord tr = mRecentTasks.get(i);
4790                    final String taskPackageName =
4791                            tr.getBaseIntent().getComponent().getPackageName();
4792                    if (tr.userId != userId) continue;
4793                    if (!taskPackageName.equals(packageName)) continue;
4794                    removeTaskByIdLocked(tr.taskId, 0);
4795                }
4796            }
4797
4798            try {
4799                // Clear application user data
4800                pm.clearApplicationUserData(packageName, observer, userId);
4801
4802                synchronized(this) {
4803                    // Remove all permissions granted from/to this package
4804                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4805                }
4806
4807                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4808                        Uri.fromParts("package", packageName, null));
4809                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4810                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4811                        null, null, 0, null, null, null, false, false, userId);
4812            } catch (RemoteException e) {
4813            }
4814        } finally {
4815            Binder.restoreCallingIdentity(callingId);
4816        }
4817        return true;
4818    }
4819
4820    @Override
4821    public void killBackgroundProcesses(final String packageName, int userId) {
4822        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4823                != PackageManager.PERMISSION_GRANTED &&
4824                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4825                        != PackageManager.PERMISSION_GRANTED) {
4826            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4827                    + Binder.getCallingPid()
4828                    + ", uid=" + Binder.getCallingUid()
4829                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4830            Slog.w(TAG, msg);
4831            throw new SecurityException(msg);
4832        }
4833
4834        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4835                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4836        long callingId = Binder.clearCallingIdentity();
4837        try {
4838            IPackageManager pm = AppGlobals.getPackageManager();
4839            synchronized(this) {
4840                int appId = -1;
4841                try {
4842                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4843                } catch (RemoteException e) {
4844                }
4845                if (appId == -1) {
4846                    Slog.w(TAG, "Invalid packageName: " + packageName);
4847                    return;
4848                }
4849                killPackageProcessesLocked(packageName, appId, userId,
4850                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4851            }
4852        } finally {
4853            Binder.restoreCallingIdentity(callingId);
4854        }
4855    }
4856
4857    @Override
4858    public void killAllBackgroundProcesses() {
4859        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4860                != PackageManager.PERMISSION_GRANTED) {
4861            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4862                    + Binder.getCallingPid()
4863                    + ", uid=" + Binder.getCallingUid()
4864                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4865            Slog.w(TAG, msg);
4866            throw new SecurityException(msg);
4867        }
4868
4869        long callingId = Binder.clearCallingIdentity();
4870        try {
4871            synchronized(this) {
4872                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4873                final int NP = mProcessNames.getMap().size();
4874                for (int ip=0; ip<NP; ip++) {
4875                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4876                    final int NA = apps.size();
4877                    for (int ia=0; ia<NA; ia++) {
4878                        ProcessRecord app = apps.valueAt(ia);
4879                        if (app.persistent) {
4880                            // we don't kill persistent processes
4881                            continue;
4882                        }
4883                        if (app.removed) {
4884                            procs.add(app);
4885                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4886                            app.removed = true;
4887                            procs.add(app);
4888                        }
4889                    }
4890                }
4891
4892                int N = procs.size();
4893                for (int i=0; i<N; i++) {
4894                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4895                }
4896                mAllowLowerMemLevel = true;
4897                updateOomAdjLocked();
4898                doLowMemReportIfNeededLocked(null);
4899            }
4900        } finally {
4901            Binder.restoreCallingIdentity(callingId);
4902        }
4903    }
4904
4905    @Override
4906    public void forceStopPackage(final String packageName, int userId) {
4907        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4908                != PackageManager.PERMISSION_GRANTED) {
4909            String msg = "Permission Denial: forceStopPackage() from pid="
4910                    + Binder.getCallingPid()
4911                    + ", uid=" + Binder.getCallingUid()
4912                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4913            Slog.w(TAG, msg);
4914            throw new SecurityException(msg);
4915        }
4916        final int callingPid = Binder.getCallingPid();
4917        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4918                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4919        long callingId = Binder.clearCallingIdentity();
4920        try {
4921            IPackageManager pm = AppGlobals.getPackageManager();
4922            synchronized(this) {
4923                int[] users = userId == UserHandle.USER_ALL
4924                        ? getUsersLocked() : new int[] { userId };
4925                for (int user : users) {
4926                    int pkgUid = -1;
4927                    try {
4928                        pkgUid = pm.getPackageUid(packageName, user);
4929                    } catch (RemoteException e) {
4930                    }
4931                    if (pkgUid == -1) {
4932                        Slog.w(TAG, "Invalid packageName: " + packageName);
4933                        continue;
4934                    }
4935                    try {
4936                        pm.setPackageStoppedState(packageName, true, user);
4937                    } catch (RemoteException e) {
4938                    } catch (IllegalArgumentException e) {
4939                        Slog.w(TAG, "Failed trying to unstop package "
4940                                + packageName + ": " + e);
4941                    }
4942                    if (isUserRunningLocked(user, false)) {
4943                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4944                    }
4945                }
4946            }
4947        } finally {
4948            Binder.restoreCallingIdentity(callingId);
4949        }
4950    }
4951
4952    @Override
4953    public void addPackageDependency(String packageName) {
4954        synchronized (this) {
4955            int callingPid = Binder.getCallingPid();
4956            if (callingPid == Process.myPid()) {
4957                //  Yeah, um, no.
4958                Slog.w(TAG, "Can't addPackageDependency on system process");
4959                return;
4960            }
4961            ProcessRecord proc;
4962            synchronized (mPidsSelfLocked) {
4963                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4964            }
4965            if (proc != null) {
4966                if (proc.pkgDeps == null) {
4967                    proc.pkgDeps = new ArraySet<String>(1);
4968                }
4969                proc.pkgDeps.add(packageName);
4970            }
4971        }
4972    }
4973
4974    /*
4975     * The pkg name and app id have to be specified.
4976     */
4977    @Override
4978    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4979        if (pkg == null) {
4980            return;
4981        }
4982        // Make sure the uid is valid.
4983        if (appid < 0) {
4984            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4985            return;
4986        }
4987        int callerUid = Binder.getCallingUid();
4988        // Only the system server can kill an application
4989        if (callerUid == Process.SYSTEM_UID) {
4990            // Post an aysnc message to kill the application
4991            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4992            msg.arg1 = appid;
4993            msg.arg2 = 0;
4994            Bundle bundle = new Bundle();
4995            bundle.putString("pkg", pkg);
4996            bundle.putString("reason", reason);
4997            msg.obj = bundle;
4998            mHandler.sendMessage(msg);
4999        } else {
5000            throw new SecurityException(callerUid + " cannot kill pkg: " +
5001                    pkg);
5002        }
5003    }
5004
5005    @Override
5006    public void closeSystemDialogs(String reason) {
5007        enforceNotIsolatedCaller("closeSystemDialogs");
5008
5009        final int pid = Binder.getCallingPid();
5010        final int uid = Binder.getCallingUid();
5011        final long origId = Binder.clearCallingIdentity();
5012        try {
5013            synchronized (this) {
5014                // Only allow this from foreground processes, so that background
5015                // applications can't abuse it to prevent system UI from being shown.
5016                if (uid >= Process.FIRST_APPLICATION_UID) {
5017                    ProcessRecord proc;
5018                    synchronized (mPidsSelfLocked) {
5019                        proc = mPidsSelfLocked.get(pid);
5020                    }
5021                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5022                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5023                                + " from background process " + proc);
5024                        return;
5025                    }
5026                }
5027                closeSystemDialogsLocked(reason);
5028            }
5029        } finally {
5030            Binder.restoreCallingIdentity(origId);
5031        }
5032    }
5033
5034    void closeSystemDialogsLocked(String reason) {
5035        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5036        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5037                | Intent.FLAG_RECEIVER_FOREGROUND);
5038        if (reason != null) {
5039            intent.putExtra("reason", reason);
5040        }
5041        mWindowManager.closeSystemDialogs(reason);
5042
5043        mStackSupervisor.closeSystemDialogsLocked();
5044
5045        broadcastIntentLocked(null, null, intent, null,
5046                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5047                Process.SYSTEM_UID, UserHandle.USER_ALL);
5048    }
5049
5050    @Override
5051    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5052        enforceNotIsolatedCaller("getProcessMemoryInfo");
5053        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5054        for (int i=pids.length-1; i>=0; i--) {
5055            ProcessRecord proc;
5056            int oomAdj;
5057            synchronized (this) {
5058                synchronized (mPidsSelfLocked) {
5059                    proc = mPidsSelfLocked.get(pids[i]);
5060                    oomAdj = proc != null ? proc.setAdj : 0;
5061                }
5062            }
5063            infos[i] = new Debug.MemoryInfo();
5064            Debug.getMemoryInfo(pids[i], infos[i]);
5065            if (proc != null) {
5066                synchronized (this) {
5067                    if (proc.thread != null && proc.setAdj == oomAdj) {
5068                        // Record this for posterity if the process has been stable.
5069                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5070                                infos[i].getTotalUss(), false, proc.pkgList);
5071                    }
5072                }
5073            }
5074        }
5075        return infos;
5076    }
5077
5078    @Override
5079    public long[] getProcessPss(int[] pids) {
5080        enforceNotIsolatedCaller("getProcessPss");
5081        long[] pss = new long[pids.length];
5082        for (int i=pids.length-1; i>=0; i--) {
5083            ProcessRecord proc;
5084            int oomAdj;
5085            synchronized (this) {
5086                synchronized (mPidsSelfLocked) {
5087                    proc = mPidsSelfLocked.get(pids[i]);
5088                    oomAdj = proc != null ? proc.setAdj : 0;
5089                }
5090            }
5091            long[] tmpUss = new long[1];
5092            pss[i] = Debug.getPss(pids[i], tmpUss);
5093            if (proc != null) {
5094                synchronized (this) {
5095                    if (proc.thread != null && proc.setAdj == oomAdj) {
5096                        // Record this for posterity if the process has been stable.
5097                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5098                    }
5099                }
5100            }
5101        }
5102        return pss;
5103    }
5104
5105    @Override
5106    public void killApplicationProcess(String processName, int uid) {
5107        if (processName == null) {
5108            return;
5109        }
5110
5111        int callerUid = Binder.getCallingUid();
5112        // Only the system server can kill an application
5113        if (callerUid == Process.SYSTEM_UID) {
5114            synchronized (this) {
5115                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5116                if (app != null && app.thread != null) {
5117                    try {
5118                        app.thread.scheduleSuicide();
5119                    } catch (RemoteException e) {
5120                        // If the other end already died, then our work here is done.
5121                    }
5122                } else {
5123                    Slog.w(TAG, "Process/uid not found attempting kill of "
5124                            + processName + " / " + uid);
5125                }
5126            }
5127        } else {
5128            throw new SecurityException(callerUid + " cannot kill app process: " +
5129                    processName);
5130        }
5131    }
5132
5133    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5134        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5135                false, true, false, false, UserHandle.getUserId(uid), reason);
5136        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5137                Uri.fromParts("package", packageName, null));
5138        if (!mProcessesReady) {
5139            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5140                    | Intent.FLAG_RECEIVER_FOREGROUND);
5141        }
5142        intent.putExtra(Intent.EXTRA_UID, uid);
5143        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5144        broadcastIntentLocked(null, null, intent,
5145                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5146                false, false,
5147                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5148    }
5149
5150    private void forceStopUserLocked(int userId, String reason) {
5151        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5152        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5153        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5154                | Intent.FLAG_RECEIVER_FOREGROUND);
5155        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5156        broadcastIntentLocked(null, null, intent,
5157                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5158                false, false,
5159                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5160    }
5161
5162    private final boolean killPackageProcessesLocked(String packageName, int appId,
5163            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5164            boolean doit, boolean evenPersistent, String reason) {
5165        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5166
5167        // Remove all processes this package may have touched: all with the
5168        // same UID (except for the system or root user), and all whose name
5169        // matches the package name.
5170        final int NP = mProcessNames.getMap().size();
5171        for (int ip=0; ip<NP; ip++) {
5172            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5173            final int NA = apps.size();
5174            for (int ia=0; ia<NA; ia++) {
5175                ProcessRecord app = apps.valueAt(ia);
5176                if (app.persistent && !evenPersistent) {
5177                    // we don't kill persistent processes
5178                    continue;
5179                }
5180                if (app.removed) {
5181                    if (doit) {
5182                        procs.add(app);
5183                    }
5184                    continue;
5185                }
5186
5187                // Skip process if it doesn't meet our oom adj requirement.
5188                if (app.setAdj < minOomAdj) {
5189                    continue;
5190                }
5191
5192                // If no package is specified, we call all processes under the
5193                // give user id.
5194                if (packageName == null) {
5195                    if (app.userId != userId) {
5196                        continue;
5197                    }
5198                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5199                        continue;
5200                    }
5201                // Package has been specified, we want to hit all processes
5202                // that match it.  We need to qualify this by the processes
5203                // that are running under the specified app and user ID.
5204                } else {
5205                    final boolean isDep = app.pkgDeps != null
5206                            && app.pkgDeps.contains(packageName);
5207                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5208                        continue;
5209                    }
5210                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5211                        continue;
5212                    }
5213                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5214                        continue;
5215                    }
5216                }
5217
5218                // Process has passed all conditions, kill it!
5219                if (!doit) {
5220                    return true;
5221                }
5222                app.removed = true;
5223                procs.add(app);
5224            }
5225        }
5226
5227        int N = procs.size();
5228        for (int i=0; i<N; i++) {
5229            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5230        }
5231        updateOomAdjLocked();
5232        return N > 0;
5233    }
5234
5235    private final boolean forceStopPackageLocked(String name, int appId,
5236            boolean callerWillRestart, boolean purgeCache, boolean doit,
5237            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5238        int i;
5239        int N;
5240
5241        if (userId == UserHandle.USER_ALL && name == null) {
5242            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5243        }
5244
5245        if (appId < 0 && name != null) {
5246            try {
5247                appId = UserHandle.getAppId(
5248                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5249            } catch (RemoteException e) {
5250            }
5251        }
5252
5253        if (doit) {
5254            if (name != null) {
5255                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5256                        + " user=" + userId + ": " + reason);
5257            } else {
5258                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5259            }
5260
5261            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5262            for (int ip=pmap.size()-1; ip>=0; ip--) {
5263                SparseArray<Long> ba = pmap.valueAt(ip);
5264                for (i=ba.size()-1; i>=0; i--) {
5265                    boolean remove = false;
5266                    final int entUid = ba.keyAt(i);
5267                    if (name != null) {
5268                        if (userId == UserHandle.USER_ALL) {
5269                            if (UserHandle.getAppId(entUid) == appId) {
5270                                remove = true;
5271                            }
5272                        } else {
5273                            if (entUid == UserHandle.getUid(userId, appId)) {
5274                                remove = true;
5275                            }
5276                        }
5277                    } else if (UserHandle.getUserId(entUid) == userId) {
5278                        remove = true;
5279                    }
5280                    if (remove) {
5281                        ba.removeAt(i);
5282                    }
5283                }
5284                if (ba.size() == 0) {
5285                    pmap.removeAt(ip);
5286                }
5287            }
5288        }
5289
5290        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5291                -100, callerWillRestart, true, doit, evenPersistent,
5292                name == null ? ("stop user " + userId) : ("stop " + name));
5293
5294        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5295            if (!doit) {
5296                return true;
5297            }
5298            didSomething = true;
5299        }
5300
5301        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5302            if (!doit) {
5303                return true;
5304            }
5305            didSomething = true;
5306        }
5307
5308        if (name == null) {
5309            // Remove all sticky broadcasts from this user.
5310            mStickyBroadcasts.remove(userId);
5311        }
5312
5313        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5314        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5315                userId, providers)) {
5316            if (!doit) {
5317                return true;
5318            }
5319            didSomething = true;
5320        }
5321        N = providers.size();
5322        for (i=0; i<N; i++) {
5323            removeDyingProviderLocked(null, providers.get(i), true);
5324        }
5325
5326        // Remove transient permissions granted from/to this package/user
5327        removeUriPermissionsForPackageLocked(name, userId, false);
5328
5329        if (name == null || uninstalling) {
5330            // Remove pending intents.  For now we only do this when force
5331            // stopping users, because we have some problems when doing this
5332            // for packages -- app widgets are not currently cleaned up for
5333            // such packages, so they can be left with bad pending intents.
5334            if (mIntentSenderRecords.size() > 0) {
5335                Iterator<WeakReference<PendingIntentRecord>> it
5336                        = mIntentSenderRecords.values().iterator();
5337                while (it.hasNext()) {
5338                    WeakReference<PendingIntentRecord> wpir = it.next();
5339                    if (wpir == null) {
5340                        it.remove();
5341                        continue;
5342                    }
5343                    PendingIntentRecord pir = wpir.get();
5344                    if (pir == null) {
5345                        it.remove();
5346                        continue;
5347                    }
5348                    if (name == null) {
5349                        // Stopping user, remove all objects for the user.
5350                        if (pir.key.userId != userId) {
5351                            // Not the same user, skip it.
5352                            continue;
5353                        }
5354                    } else {
5355                        if (UserHandle.getAppId(pir.uid) != appId) {
5356                            // Different app id, skip it.
5357                            continue;
5358                        }
5359                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5360                            // Different user, skip it.
5361                            continue;
5362                        }
5363                        if (!pir.key.packageName.equals(name)) {
5364                            // Different package, skip it.
5365                            continue;
5366                        }
5367                    }
5368                    if (!doit) {
5369                        return true;
5370                    }
5371                    didSomething = true;
5372                    it.remove();
5373                    pir.canceled = true;
5374                    if (pir.key.activity != null) {
5375                        pir.key.activity.pendingResults.remove(pir.ref);
5376                    }
5377                }
5378            }
5379        }
5380
5381        if (doit) {
5382            if (purgeCache && name != null) {
5383                AttributeCache ac = AttributeCache.instance();
5384                if (ac != null) {
5385                    ac.removePackage(name);
5386                }
5387            }
5388            if (mBooted) {
5389                mStackSupervisor.resumeTopActivitiesLocked();
5390                mStackSupervisor.scheduleIdleLocked();
5391            }
5392        }
5393
5394        return didSomething;
5395    }
5396
5397    private final boolean removeProcessLocked(ProcessRecord app,
5398            boolean callerWillRestart, boolean allowRestart, String reason) {
5399        final String name = app.processName;
5400        final int uid = app.uid;
5401        if (DEBUG_PROCESSES) Slog.d(
5402            TAG, "Force removing proc " + app.toShortString() + " (" + name
5403            + "/" + uid + ")");
5404
5405        mProcessNames.remove(name, uid);
5406        mIsolatedProcesses.remove(app.uid);
5407        if (mHeavyWeightProcess == app) {
5408            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5409                    mHeavyWeightProcess.userId, 0));
5410            mHeavyWeightProcess = null;
5411        }
5412        boolean needRestart = false;
5413        if (app.pid > 0 && app.pid != MY_PID) {
5414            int pid = app.pid;
5415            synchronized (mPidsSelfLocked) {
5416                mPidsSelfLocked.remove(pid);
5417                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5418            }
5419            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5420            if (app.isolated) {
5421                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5422            }
5423            killUnneededProcessLocked(app, reason);
5424            Process.killProcessGroup(app.info.uid, app.pid);
5425            handleAppDiedLocked(app, true, allowRestart);
5426            removeLruProcessLocked(app);
5427
5428            if (app.persistent && !app.isolated) {
5429                if (!callerWillRestart) {
5430                    addAppLocked(app.info, false, null /* ABI override */);
5431                } else {
5432                    needRestart = true;
5433                }
5434            }
5435        } else {
5436            mRemovedProcesses.add(app);
5437        }
5438
5439        return needRestart;
5440    }
5441
5442    private final void processStartTimedOutLocked(ProcessRecord app) {
5443        final int pid = app.pid;
5444        boolean gone = false;
5445        synchronized (mPidsSelfLocked) {
5446            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5447            if (knownApp != null && knownApp.thread == null) {
5448                mPidsSelfLocked.remove(pid);
5449                gone = true;
5450            }
5451        }
5452
5453        if (gone) {
5454            Slog.w(TAG, "Process " + app + " failed to attach");
5455            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5456                    pid, app.uid, app.processName);
5457            mProcessNames.remove(app.processName, app.uid);
5458            mIsolatedProcesses.remove(app.uid);
5459            if (mHeavyWeightProcess == app) {
5460                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5461                        mHeavyWeightProcess.userId, 0));
5462                mHeavyWeightProcess = null;
5463            }
5464            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5465            if (app.isolated) {
5466                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5467            }
5468            // Take care of any launching providers waiting for this process.
5469            checkAppInLaunchingProvidersLocked(app, true);
5470            // Take care of any services that are waiting for the process.
5471            mServices.processStartTimedOutLocked(app);
5472            killUnneededProcessLocked(app, "start timeout");
5473            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5474                Slog.w(TAG, "Unattached app died before backup, skipping");
5475                try {
5476                    IBackupManager bm = IBackupManager.Stub.asInterface(
5477                            ServiceManager.getService(Context.BACKUP_SERVICE));
5478                    bm.agentDisconnected(app.info.packageName);
5479                } catch (RemoteException e) {
5480                    // Can't happen; the backup manager is local
5481                }
5482            }
5483            if (isPendingBroadcastProcessLocked(pid)) {
5484                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5485                skipPendingBroadcastLocked(pid);
5486            }
5487        } else {
5488            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5489        }
5490    }
5491
5492    private final boolean attachApplicationLocked(IApplicationThread thread,
5493            int pid) {
5494
5495        // Find the application record that is being attached...  either via
5496        // the pid if we are running in multiple processes, or just pull the
5497        // next app record if we are emulating process with anonymous threads.
5498        ProcessRecord app;
5499        if (pid != MY_PID && pid >= 0) {
5500            synchronized (mPidsSelfLocked) {
5501                app = mPidsSelfLocked.get(pid);
5502            }
5503        } else {
5504            app = null;
5505        }
5506
5507        if (app == null) {
5508            Slog.w(TAG, "No pending application record for pid " + pid
5509                    + " (IApplicationThread " + thread + "); dropping process");
5510            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5511            if (pid > 0 && pid != MY_PID) {
5512                Process.killProcessQuiet(pid);
5513                //TODO: Process.killProcessGroup(app.info.uid, pid);
5514            } else {
5515                try {
5516                    thread.scheduleExit();
5517                } catch (Exception e) {
5518                    // Ignore exceptions.
5519                }
5520            }
5521            return false;
5522        }
5523
5524        // If this application record is still attached to a previous
5525        // process, clean it up now.
5526        if (app.thread != null) {
5527            handleAppDiedLocked(app, true, true);
5528        }
5529
5530        // Tell the process all about itself.
5531
5532        if (localLOGV) Slog.v(
5533                TAG, "Binding process pid " + pid + " to record " + app);
5534
5535        final String processName = app.processName;
5536        try {
5537            AppDeathRecipient adr = new AppDeathRecipient(
5538                    app, pid, thread);
5539            thread.asBinder().linkToDeath(adr, 0);
5540            app.deathRecipient = adr;
5541        } catch (RemoteException e) {
5542            app.resetPackageList(mProcessStats);
5543            startProcessLocked(app, "link fail", processName);
5544            return false;
5545        }
5546
5547        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5548
5549        app.makeActive(thread, mProcessStats);
5550        app.curAdj = app.setAdj = -100;
5551        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5552        app.forcingToForeground = null;
5553        updateProcessForegroundLocked(app, false, false);
5554        app.hasShownUi = false;
5555        app.debugging = false;
5556        app.cached = false;
5557
5558        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5559
5560        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5561        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5562
5563        if (!normalMode) {
5564            Slog.i(TAG, "Launching preboot mode app: " + app);
5565        }
5566
5567        if (localLOGV) Slog.v(
5568            TAG, "New app record " + app
5569            + " thread=" + thread.asBinder() + " pid=" + pid);
5570        try {
5571            int testMode = IApplicationThread.DEBUG_OFF;
5572            if (mDebugApp != null && mDebugApp.equals(processName)) {
5573                testMode = mWaitForDebugger
5574                    ? IApplicationThread.DEBUG_WAIT
5575                    : IApplicationThread.DEBUG_ON;
5576                app.debugging = true;
5577                if (mDebugTransient) {
5578                    mDebugApp = mOrigDebugApp;
5579                    mWaitForDebugger = mOrigWaitForDebugger;
5580                }
5581            }
5582            String profileFile = app.instrumentationProfileFile;
5583            ParcelFileDescriptor profileFd = null;
5584            boolean profileAutoStop = false;
5585            if (mProfileApp != null && mProfileApp.equals(processName)) {
5586                mProfileProc = app;
5587                profileFile = mProfileFile;
5588                profileFd = mProfileFd;
5589                profileAutoStop = mAutoStopProfiler;
5590            }
5591            boolean enableOpenGlTrace = false;
5592            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5593                enableOpenGlTrace = true;
5594                mOpenGlTraceApp = null;
5595            }
5596
5597            // If the app is being launched for restore or full backup, set it up specially
5598            boolean isRestrictedBackupMode = false;
5599            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5600                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5601                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5602                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5603            }
5604
5605            ensurePackageDexOpt(app.instrumentationInfo != null
5606                    ? app.instrumentationInfo.packageName
5607                    : app.info.packageName);
5608            if (app.instrumentationClass != null) {
5609                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5610            }
5611            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5612                    + processName + " with config " + mConfiguration);
5613            ApplicationInfo appInfo = app.instrumentationInfo != null
5614                    ? app.instrumentationInfo : app.info;
5615            app.compat = compatibilityInfoForPackageLocked(appInfo);
5616            if (profileFd != null) {
5617                profileFd = profileFd.dup();
5618            }
5619            thread.bindApplication(processName, appInfo, providers,
5620                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5621                    app.instrumentationArguments, app.instrumentationWatcher,
5622                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5623                    isRestrictedBackupMode || !normalMode, app.persistent,
5624                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5625                    mCoreSettingsObserver.getCoreSettingsLocked());
5626            updateLruProcessLocked(app, false, null);
5627            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5628        } catch (Exception e) {
5629            // todo: Yikes!  What should we do?  For now we will try to
5630            // start another process, but that could easily get us in
5631            // an infinite loop of restarting processes...
5632            Slog.w(TAG, "Exception thrown during bind!", e);
5633
5634            app.resetPackageList(mProcessStats);
5635            app.unlinkDeathRecipient();
5636            startProcessLocked(app, "bind fail", processName);
5637            return false;
5638        }
5639
5640        // Remove this record from the list of starting applications.
5641        mPersistentStartingProcesses.remove(app);
5642        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5643                "Attach application locked removing on hold: " + app);
5644        mProcessesOnHold.remove(app);
5645
5646        boolean badApp = false;
5647        boolean didSomething = false;
5648
5649        // See if the top visible activity is waiting to run in this process...
5650        if (normalMode) {
5651            try {
5652                if (mStackSupervisor.attachApplicationLocked(app)) {
5653                    didSomething = true;
5654                }
5655            } catch (Exception e) {
5656                badApp = true;
5657            }
5658        }
5659
5660        // Find any services that should be running in this process...
5661        if (!badApp) {
5662            try {
5663                didSomething |= mServices.attachApplicationLocked(app, processName);
5664            } catch (Exception e) {
5665                badApp = true;
5666            }
5667        }
5668
5669        // Check if a next-broadcast receiver is in this process...
5670        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5671            try {
5672                didSomething |= sendPendingBroadcastsLocked(app);
5673            } catch (Exception e) {
5674                // If the app died trying to launch the receiver we declare it 'bad'
5675                badApp = true;
5676            }
5677        }
5678
5679        // Check whether the next backup agent is in this process...
5680        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5681            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5682            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5683            try {
5684                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5685                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5686                        mBackupTarget.backupMode);
5687            } catch (Exception e) {
5688                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5689                e.printStackTrace();
5690            }
5691        }
5692
5693        if (badApp) {
5694            // todo: Also need to kill application to deal with all
5695            // kinds of exceptions.
5696            handleAppDiedLocked(app, false, true);
5697            return false;
5698        }
5699
5700        if (!didSomething) {
5701            updateOomAdjLocked();
5702        }
5703
5704        return true;
5705    }
5706
5707    @Override
5708    public final void attachApplication(IApplicationThread thread) {
5709        synchronized (this) {
5710            int callingPid = Binder.getCallingPid();
5711            final long origId = Binder.clearCallingIdentity();
5712            attachApplicationLocked(thread, callingPid);
5713            Binder.restoreCallingIdentity(origId);
5714        }
5715    }
5716
5717    @Override
5718    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5719        final long origId = Binder.clearCallingIdentity();
5720        synchronized (this) {
5721            ActivityStack stack = ActivityRecord.getStackLocked(token);
5722            if (stack != null) {
5723                ActivityRecord r =
5724                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5725                if (stopProfiling) {
5726                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5727                        try {
5728                            mProfileFd.close();
5729                        } catch (IOException e) {
5730                        }
5731                        clearProfilerLocked();
5732                    }
5733                }
5734            }
5735        }
5736        Binder.restoreCallingIdentity(origId);
5737    }
5738
5739    void postEnableScreenAfterBootLocked() {
5740        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5741    }
5742
5743    void enableScreenAfterBoot() {
5744        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5745                SystemClock.uptimeMillis());
5746        mWindowManager.enableScreenAfterBoot();
5747
5748        synchronized (this) {
5749            updateEventDispatchingLocked();
5750        }
5751    }
5752
5753    @Override
5754    public void showBootMessage(final CharSequence msg, final boolean always) {
5755        enforceNotIsolatedCaller("showBootMessage");
5756        mWindowManager.showBootMessage(msg, always);
5757    }
5758
5759    @Override
5760    public void keyguardWaitingForActivityDrawn() {
5761        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5762        final long token = Binder.clearCallingIdentity();
5763        try {
5764            synchronized (this) {
5765                if (DEBUG_LOCKSCREEN) logLockScreen("");
5766                mWindowManager.keyguardWaitingForActivityDrawn();
5767            }
5768        } finally {
5769            Binder.restoreCallingIdentity(token);
5770        }
5771    }
5772
5773    final void finishBooting() {
5774        // Register receivers to handle package update events
5775        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5776
5777        // Let system services know.
5778        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5779
5780        synchronized (this) {
5781            // Ensure that any processes we had put on hold are now started
5782            // up.
5783            final int NP = mProcessesOnHold.size();
5784            if (NP > 0) {
5785                ArrayList<ProcessRecord> procs =
5786                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5787                for (int ip=0; ip<NP; ip++) {
5788                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5789                            + procs.get(ip));
5790                    startProcessLocked(procs.get(ip), "on-hold", null);
5791                }
5792            }
5793
5794            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5795                // Start looking for apps that are abusing wake locks.
5796                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5797                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5798                // Tell anyone interested that we are done booting!
5799                SystemProperties.set("sys.boot_completed", "1");
5800                SystemProperties.set("dev.bootcomplete", "1");
5801                for (int i=0; i<mStartedUsers.size(); i++) {
5802                    UserStartedState uss = mStartedUsers.valueAt(i);
5803                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5804                        uss.mState = UserStartedState.STATE_RUNNING;
5805                        final int userId = mStartedUsers.keyAt(i);
5806                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5807                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5808                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5809                        broadcastIntentLocked(null, null, intent, null,
5810                                new IIntentReceiver.Stub() {
5811                                    @Override
5812                                    public void performReceive(Intent intent, int resultCode,
5813                                            String data, Bundle extras, boolean ordered,
5814                                            boolean sticky, int sendingUser) {
5815                                        synchronized (ActivityManagerService.this) {
5816                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5817                                                    true, false);
5818                                        }
5819                                    }
5820                                },
5821                                0, null, null,
5822                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5823                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5824                                userId);
5825                    }
5826                }
5827                scheduleStartProfilesLocked();
5828            }
5829        }
5830    }
5831
5832    final void ensureBootCompleted() {
5833        boolean booting;
5834        boolean enableScreen;
5835        synchronized (this) {
5836            booting = mBooting;
5837            mBooting = false;
5838            enableScreen = !mBooted;
5839            mBooted = true;
5840        }
5841
5842        if (booting) {
5843            finishBooting();
5844        }
5845
5846        if (enableScreen) {
5847            enableScreenAfterBoot();
5848        }
5849    }
5850
5851    @Override
5852    public final void activityResumed(IBinder token) {
5853        final long origId = Binder.clearCallingIdentity();
5854        synchronized(this) {
5855            ActivityStack stack = ActivityRecord.getStackLocked(token);
5856            if (stack != null) {
5857                ActivityRecord.activityResumedLocked(token);
5858            }
5859        }
5860        Binder.restoreCallingIdentity(origId);
5861    }
5862
5863    @Override
5864    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5865        final long origId = Binder.clearCallingIdentity();
5866        synchronized(this) {
5867            ActivityStack stack = ActivityRecord.getStackLocked(token);
5868            if (stack != null) {
5869                stack.activityPausedLocked(token, false, persistentState);
5870            }
5871        }
5872        Binder.restoreCallingIdentity(origId);
5873    }
5874
5875    @Override
5876    public final void activityStopped(IBinder token, Bundle icicle,
5877            PersistableBundle persistentState, CharSequence description) {
5878        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5879
5880        // Refuse possible leaked file descriptors
5881        if (icicle != null && icicle.hasFileDescriptors()) {
5882            throw new IllegalArgumentException("File descriptors passed in Bundle");
5883        }
5884
5885        final long origId = Binder.clearCallingIdentity();
5886
5887        synchronized (this) {
5888            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5889            if (r != null) {
5890                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5891            }
5892        }
5893
5894        trimApplications();
5895
5896        Binder.restoreCallingIdentity(origId);
5897    }
5898
5899    @Override
5900    public final void activityDestroyed(IBinder token) {
5901        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5902        synchronized (this) {
5903            ActivityStack stack = ActivityRecord.getStackLocked(token);
5904            if (stack != null) {
5905                stack.activityDestroyedLocked(token);
5906            }
5907        }
5908    }
5909
5910    @Override
5911    public final void backgroundResourcesReleased(IBinder token) {
5912        final long origId = Binder.clearCallingIdentity();
5913        try {
5914            synchronized (this) {
5915                ActivityStack stack = ActivityRecord.getStackLocked(token);
5916                if (stack != null) {
5917                    stack.backgroundResourcesReleased(token);
5918                }
5919            }
5920        } finally {
5921            Binder.restoreCallingIdentity(origId);
5922        }
5923    }
5924
5925    @Override
5926    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5927        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5928    }
5929
5930    @Override
5931    public final void notifyEnterAnimationComplete(IBinder token) {
5932        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5933    }
5934
5935    @Override
5936    public String getCallingPackage(IBinder token) {
5937        synchronized (this) {
5938            ActivityRecord r = getCallingRecordLocked(token);
5939            return r != null ? r.info.packageName : null;
5940        }
5941    }
5942
5943    @Override
5944    public ComponentName getCallingActivity(IBinder token) {
5945        synchronized (this) {
5946            ActivityRecord r = getCallingRecordLocked(token);
5947            return r != null ? r.intent.getComponent() : null;
5948        }
5949    }
5950
5951    private ActivityRecord getCallingRecordLocked(IBinder token) {
5952        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5953        if (r == null) {
5954            return null;
5955        }
5956        return r.resultTo;
5957    }
5958
5959    @Override
5960    public ComponentName getActivityClassForToken(IBinder token) {
5961        synchronized(this) {
5962            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5963            if (r == null) {
5964                return null;
5965            }
5966            return r.intent.getComponent();
5967        }
5968    }
5969
5970    @Override
5971    public String getPackageForToken(IBinder token) {
5972        synchronized(this) {
5973            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5974            if (r == null) {
5975                return null;
5976            }
5977            return r.packageName;
5978        }
5979    }
5980
5981    @Override
5982    public IIntentSender getIntentSender(int type,
5983            String packageName, IBinder token, String resultWho,
5984            int requestCode, Intent[] intents, String[] resolvedTypes,
5985            int flags, Bundle options, int userId) {
5986        enforceNotIsolatedCaller("getIntentSender");
5987        // Refuse possible leaked file descriptors
5988        if (intents != null) {
5989            if (intents.length < 1) {
5990                throw new IllegalArgumentException("Intents array length must be >= 1");
5991            }
5992            for (int i=0; i<intents.length; i++) {
5993                Intent intent = intents[i];
5994                if (intent != null) {
5995                    if (intent.hasFileDescriptors()) {
5996                        throw new IllegalArgumentException("File descriptors passed in Intent");
5997                    }
5998                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5999                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6000                        throw new IllegalArgumentException(
6001                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6002                    }
6003                    intents[i] = new Intent(intent);
6004                }
6005            }
6006            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6007                throw new IllegalArgumentException(
6008                        "Intent array length does not match resolvedTypes length");
6009            }
6010        }
6011        if (options != null) {
6012            if (options.hasFileDescriptors()) {
6013                throw new IllegalArgumentException("File descriptors passed in options");
6014            }
6015        }
6016
6017        synchronized(this) {
6018            int callingUid = Binder.getCallingUid();
6019            int origUserId = userId;
6020            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6021                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6022                    ALLOW_NON_FULL, "getIntentSender", null);
6023            if (origUserId == UserHandle.USER_CURRENT) {
6024                // We don't want to evaluate this until the pending intent is
6025                // actually executed.  However, we do want to always do the
6026                // security checking for it above.
6027                userId = UserHandle.USER_CURRENT;
6028            }
6029            try {
6030                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6031                    int uid = AppGlobals.getPackageManager()
6032                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6033                    if (!UserHandle.isSameApp(callingUid, uid)) {
6034                        String msg = "Permission Denial: getIntentSender() from pid="
6035                            + Binder.getCallingPid()
6036                            + ", uid=" + Binder.getCallingUid()
6037                            + ", (need uid=" + uid + ")"
6038                            + " is not allowed to send as package " + packageName;
6039                        Slog.w(TAG, msg);
6040                        throw new SecurityException(msg);
6041                    }
6042                }
6043
6044                return getIntentSenderLocked(type, packageName, callingUid, userId,
6045                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6046
6047            } catch (RemoteException e) {
6048                throw new SecurityException(e);
6049            }
6050        }
6051    }
6052
6053    IIntentSender getIntentSenderLocked(int type, String packageName,
6054            int callingUid, int userId, IBinder token, String resultWho,
6055            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6056            Bundle options) {
6057        if (DEBUG_MU)
6058            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6059        ActivityRecord activity = null;
6060        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6061            activity = ActivityRecord.isInStackLocked(token);
6062            if (activity == null) {
6063                return null;
6064            }
6065            if (activity.finishing) {
6066                return null;
6067            }
6068        }
6069
6070        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6071        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6072        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6073        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6074                |PendingIntent.FLAG_UPDATE_CURRENT);
6075
6076        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6077                type, packageName, activity, resultWho,
6078                requestCode, intents, resolvedTypes, flags, options, userId);
6079        WeakReference<PendingIntentRecord> ref;
6080        ref = mIntentSenderRecords.get(key);
6081        PendingIntentRecord rec = ref != null ? ref.get() : null;
6082        if (rec != null) {
6083            if (!cancelCurrent) {
6084                if (updateCurrent) {
6085                    if (rec.key.requestIntent != null) {
6086                        rec.key.requestIntent.replaceExtras(intents != null ?
6087                                intents[intents.length - 1] : null);
6088                    }
6089                    if (intents != null) {
6090                        intents[intents.length-1] = rec.key.requestIntent;
6091                        rec.key.allIntents = intents;
6092                        rec.key.allResolvedTypes = resolvedTypes;
6093                    } else {
6094                        rec.key.allIntents = null;
6095                        rec.key.allResolvedTypes = null;
6096                    }
6097                }
6098                return rec;
6099            }
6100            rec.canceled = true;
6101            mIntentSenderRecords.remove(key);
6102        }
6103        if (noCreate) {
6104            return rec;
6105        }
6106        rec = new PendingIntentRecord(this, key, callingUid);
6107        mIntentSenderRecords.put(key, rec.ref);
6108        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6109            if (activity.pendingResults == null) {
6110                activity.pendingResults
6111                        = new HashSet<WeakReference<PendingIntentRecord>>();
6112            }
6113            activity.pendingResults.add(rec.ref);
6114        }
6115        return rec;
6116    }
6117
6118    @Override
6119    public void cancelIntentSender(IIntentSender sender) {
6120        if (!(sender instanceof PendingIntentRecord)) {
6121            return;
6122        }
6123        synchronized(this) {
6124            PendingIntentRecord rec = (PendingIntentRecord)sender;
6125            try {
6126                int uid = AppGlobals.getPackageManager()
6127                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6128                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6129                    String msg = "Permission Denial: cancelIntentSender() from pid="
6130                        + Binder.getCallingPid()
6131                        + ", uid=" + Binder.getCallingUid()
6132                        + " is not allowed to cancel packges "
6133                        + rec.key.packageName;
6134                    Slog.w(TAG, msg);
6135                    throw new SecurityException(msg);
6136                }
6137            } catch (RemoteException e) {
6138                throw new SecurityException(e);
6139            }
6140            cancelIntentSenderLocked(rec, true);
6141        }
6142    }
6143
6144    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6145        rec.canceled = true;
6146        mIntentSenderRecords.remove(rec.key);
6147        if (cleanActivity && rec.key.activity != null) {
6148            rec.key.activity.pendingResults.remove(rec.ref);
6149        }
6150    }
6151
6152    @Override
6153    public String getPackageForIntentSender(IIntentSender pendingResult) {
6154        if (!(pendingResult instanceof PendingIntentRecord)) {
6155            return null;
6156        }
6157        try {
6158            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6159            return res.key.packageName;
6160        } catch (ClassCastException e) {
6161        }
6162        return null;
6163    }
6164
6165    @Override
6166    public int getUidForIntentSender(IIntentSender sender) {
6167        if (sender instanceof PendingIntentRecord) {
6168            try {
6169                PendingIntentRecord res = (PendingIntentRecord)sender;
6170                return res.uid;
6171            } catch (ClassCastException e) {
6172            }
6173        }
6174        return -1;
6175    }
6176
6177    @Override
6178    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6179        if (!(pendingResult instanceof PendingIntentRecord)) {
6180            return false;
6181        }
6182        try {
6183            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6184            if (res.key.allIntents == null) {
6185                return false;
6186            }
6187            for (int i=0; i<res.key.allIntents.length; i++) {
6188                Intent intent = res.key.allIntents[i];
6189                if (intent.getPackage() != null && intent.getComponent() != null) {
6190                    return false;
6191                }
6192            }
6193            return true;
6194        } catch (ClassCastException e) {
6195        }
6196        return false;
6197    }
6198
6199    @Override
6200    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6201        if (!(pendingResult instanceof PendingIntentRecord)) {
6202            return false;
6203        }
6204        try {
6205            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6206            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6207                return true;
6208            }
6209            return false;
6210        } catch (ClassCastException e) {
6211        }
6212        return false;
6213    }
6214
6215    @Override
6216    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6217        if (!(pendingResult instanceof PendingIntentRecord)) {
6218            return null;
6219        }
6220        try {
6221            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6222            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6223        } catch (ClassCastException e) {
6224        }
6225        return null;
6226    }
6227
6228    @Override
6229    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6230        if (!(pendingResult instanceof PendingIntentRecord)) {
6231            return null;
6232        }
6233        try {
6234            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6235            Intent intent = res.key.requestIntent;
6236            if (intent != null) {
6237                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6238                        || res.lastTagPrefix.equals(prefix))) {
6239                    return res.lastTag;
6240                }
6241                res.lastTagPrefix = prefix;
6242                StringBuilder sb = new StringBuilder(128);
6243                if (prefix != null) {
6244                    sb.append(prefix);
6245                }
6246                if (intent.getAction() != null) {
6247                    sb.append(intent.getAction());
6248                } else if (intent.getComponent() != null) {
6249                    intent.getComponent().appendShortString(sb);
6250                } else {
6251                    sb.append("?");
6252                }
6253                return res.lastTag = sb.toString();
6254            }
6255        } catch (ClassCastException e) {
6256        }
6257        return null;
6258    }
6259
6260    @Override
6261    public void setProcessLimit(int max) {
6262        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6263                "setProcessLimit()");
6264        synchronized (this) {
6265            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6266            mProcessLimitOverride = max;
6267        }
6268        trimApplications();
6269    }
6270
6271    @Override
6272    public int getProcessLimit() {
6273        synchronized (this) {
6274            return mProcessLimitOverride;
6275        }
6276    }
6277
6278    void foregroundTokenDied(ForegroundToken token) {
6279        synchronized (ActivityManagerService.this) {
6280            synchronized (mPidsSelfLocked) {
6281                ForegroundToken cur
6282                    = mForegroundProcesses.get(token.pid);
6283                if (cur != token) {
6284                    return;
6285                }
6286                mForegroundProcesses.remove(token.pid);
6287                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6288                if (pr == null) {
6289                    return;
6290                }
6291                pr.forcingToForeground = null;
6292                updateProcessForegroundLocked(pr, false, false);
6293            }
6294            updateOomAdjLocked();
6295        }
6296    }
6297
6298    @Override
6299    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6300        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6301                "setProcessForeground()");
6302        synchronized(this) {
6303            boolean changed = false;
6304
6305            synchronized (mPidsSelfLocked) {
6306                ProcessRecord pr = mPidsSelfLocked.get(pid);
6307                if (pr == null && isForeground) {
6308                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6309                    return;
6310                }
6311                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6312                if (oldToken != null) {
6313                    oldToken.token.unlinkToDeath(oldToken, 0);
6314                    mForegroundProcesses.remove(pid);
6315                    if (pr != null) {
6316                        pr.forcingToForeground = null;
6317                    }
6318                    changed = true;
6319                }
6320                if (isForeground && token != null) {
6321                    ForegroundToken newToken = new ForegroundToken() {
6322                        @Override
6323                        public void binderDied() {
6324                            foregroundTokenDied(this);
6325                        }
6326                    };
6327                    newToken.pid = pid;
6328                    newToken.token = token;
6329                    try {
6330                        token.linkToDeath(newToken, 0);
6331                        mForegroundProcesses.put(pid, newToken);
6332                        pr.forcingToForeground = token;
6333                        changed = true;
6334                    } catch (RemoteException e) {
6335                        // If the process died while doing this, we will later
6336                        // do the cleanup with the process death link.
6337                    }
6338                }
6339            }
6340
6341            if (changed) {
6342                updateOomAdjLocked();
6343            }
6344        }
6345    }
6346
6347    // =========================================================
6348    // PERMISSIONS
6349    // =========================================================
6350
6351    static class PermissionController extends IPermissionController.Stub {
6352        ActivityManagerService mActivityManagerService;
6353        PermissionController(ActivityManagerService activityManagerService) {
6354            mActivityManagerService = activityManagerService;
6355        }
6356
6357        @Override
6358        public boolean checkPermission(String permission, int pid, int uid) {
6359            return mActivityManagerService.checkPermission(permission, pid,
6360                    uid) == PackageManager.PERMISSION_GRANTED;
6361        }
6362    }
6363
6364    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6365        @Override
6366        public int checkComponentPermission(String permission, int pid, int uid,
6367                int owningUid, boolean exported) {
6368            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6369                    owningUid, exported);
6370        }
6371
6372        @Override
6373        public Object getAMSLock() {
6374            return ActivityManagerService.this;
6375        }
6376    }
6377
6378    /**
6379     * This can be called with or without the global lock held.
6380     */
6381    int checkComponentPermission(String permission, int pid, int uid,
6382            int owningUid, boolean exported) {
6383        // We might be performing an operation on behalf of an indirect binder
6384        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6385        // client identity accordingly before proceeding.
6386        Identity tlsIdentity = sCallerIdentity.get();
6387        if (tlsIdentity != null) {
6388            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6389                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6390            uid = tlsIdentity.uid;
6391            pid = tlsIdentity.pid;
6392        }
6393
6394        if (pid == MY_PID) {
6395            return PackageManager.PERMISSION_GRANTED;
6396        }
6397
6398        return ActivityManager.checkComponentPermission(permission, uid,
6399                owningUid, exported);
6400    }
6401
6402    /**
6403     * As the only public entry point for permissions checking, this method
6404     * can enforce the semantic that requesting a check on a null global
6405     * permission is automatically denied.  (Internally a null permission
6406     * string is used when calling {@link #checkComponentPermission} in cases
6407     * when only uid-based security is needed.)
6408     *
6409     * This can be called with or without the global lock held.
6410     */
6411    @Override
6412    public int checkPermission(String permission, int pid, int uid) {
6413        if (permission == null) {
6414            return PackageManager.PERMISSION_DENIED;
6415        }
6416        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6417    }
6418
6419    /**
6420     * Binder IPC calls go through the public entry point.
6421     * This can be called with or without the global lock held.
6422     */
6423    int checkCallingPermission(String permission) {
6424        return checkPermission(permission,
6425                Binder.getCallingPid(),
6426                UserHandle.getAppId(Binder.getCallingUid()));
6427    }
6428
6429    /**
6430     * This can be called with or without the global lock held.
6431     */
6432    void enforceCallingPermission(String permission, String func) {
6433        if (checkCallingPermission(permission)
6434                == PackageManager.PERMISSION_GRANTED) {
6435            return;
6436        }
6437
6438        String msg = "Permission Denial: " + func + " from pid="
6439                + Binder.getCallingPid()
6440                + ", uid=" + Binder.getCallingUid()
6441                + " requires " + permission;
6442        Slog.w(TAG, msg);
6443        throw new SecurityException(msg);
6444    }
6445
6446    /**
6447     * Determine if UID is holding permissions required to access {@link Uri} in
6448     * the given {@link ProviderInfo}. Final permission checking is always done
6449     * in {@link ContentProvider}.
6450     */
6451    private final boolean checkHoldingPermissionsLocked(
6452            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6453        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6454                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6455        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6456            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6457                    != PERMISSION_GRANTED) {
6458                return false;
6459            }
6460        }
6461        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6462    }
6463
6464    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6465            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6466        if (pi.applicationInfo.uid == uid) {
6467            return true;
6468        } else if (!pi.exported) {
6469            return false;
6470        }
6471
6472        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6473        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6474        try {
6475            // check if target holds top-level <provider> permissions
6476            if (!readMet && pi.readPermission != null && considerUidPermissions
6477                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6478                readMet = true;
6479            }
6480            if (!writeMet && pi.writePermission != null && considerUidPermissions
6481                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6482                writeMet = true;
6483            }
6484
6485            // track if unprotected read/write is allowed; any denied
6486            // <path-permission> below removes this ability
6487            boolean allowDefaultRead = pi.readPermission == null;
6488            boolean allowDefaultWrite = pi.writePermission == null;
6489
6490            // check if target holds any <path-permission> that match uri
6491            final PathPermission[] pps = pi.pathPermissions;
6492            if (pps != null) {
6493                final String path = grantUri.uri.getPath();
6494                int i = pps.length;
6495                while (i > 0 && (!readMet || !writeMet)) {
6496                    i--;
6497                    PathPermission pp = pps[i];
6498                    if (pp.match(path)) {
6499                        if (!readMet) {
6500                            final String pprperm = pp.getReadPermission();
6501                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6502                                    + pprperm + " for " + pp.getPath()
6503                                    + ": match=" + pp.match(path)
6504                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6505                            if (pprperm != null) {
6506                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6507                                        == PERMISSION_GRANTED) {
6508                                    readMet = true;
6509                                } else {
6510                                    allowDefaultRead = false;
6511                                }
6512                            }
6513                        }
6514                        if (!writeMet) {
6515                            final String ppwperm = pp.getWritePermission();
6516                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6517                                    + ppwperm + " for " + pp.getPath()
6518                                    + ": match=" + pp.match(path)
6519                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6520                            if (ppwperm != null) {
6521                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6522                                        == PERMISSION_GRANTED) {
6523                                    writeMet = true;
6524                                } else {
6525                                    allowDefaultWrite = false;
6526                                }
6527                            }
6528                        }
6529                    }
6530                }
6531            }
6532
6533            // grant unprotected <provider> read/write, if not blocked by
6534            // <path-permission> above
6535            if (allowDefaultRead) readMet = true;
6536            if (allowDefaultWrite) writeMet = true;
6537
6538        } catch (RemoteException e) {
6539            return false;
6540        }
6541
6542        return readMet && writeMet;
6543    }
6544
6545    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6546        ProviderInfo pi = null;
6547        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6548        if (cpr != null) {
6549            pi = cpr.info;
6550        } else {
6551            try {
6552                pi = AppGlobals.getPackageManager().resolveContentProvider(
6553                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6554            } catch (RemoteException ex) {
6555            }
6556        }
6557        return pi;
6558    }
6559
6560    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6561        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6562        if (targetUris != null) {
6563            return targetUris.get(grantUri);
6564        }
6565        return null;
6566    }
6567
6568    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6569            String targetPkg, int targetUid, GrantUri grantUri) {
6570        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6571        if (targetUris == null) {
6572            targetUris = Maps.newArrayMap();
6573            mGrantedUriPermissions.put(targetUid, targetUris);
6574        }
6575
6576        UriPermission perm = targetUris.get(grantUri);
6577        if (perm == null) {
6578            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6579            targetUris.put(grantUri, perm);
6580        }
6581
6582        return perm;
6583    }
6584
6585    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6586            final int modeFlags) {
6587        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6588        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6589                : UriPermission.STRENGTH_OWNED;
6590
6591        // Root gets to do everything.
6592        if (uid == 0) {
6593            return true;
6594        }
6595
6596        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6597        if (perms == null) return false;
6598
6599        // First look for exact match
6600        final UriPermission exactPerm = perms.get(grantUri);
6601        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6602            return true;
6603        }
6604
6605        // No exact match, look for prefixes
6606        final int N = perms.size();
6607        for (int i = 0; i < N; i++) {
6608            final UriPermission perm = perms.valueAt(i);
6609            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6610                    && perm.getStrength(modeFlags) >= minStrength) {
6611                return true;
6612            }
6613        }
6614
6615        return false;
6616    }
6617
6618    /**
6619     * @param uri This uri must NOT contain an embedded userId.
6620     * @param userId The userId in which the uri is to be resolved.
6621     */
6622    @Override
6623    public int checkUriPermission(Uri uri, int pid, int uid,
6624            final int modeFlags, int userId) {
6625        enforceNotIsolatedCaller("checkUriPermission");
6626
6627        // Another redirected-binder-call permissions check as in
6628        // {@link checkComponentPermission}.
6629        Identity tlsIdentity = sCallerIdentity.get();
6630        if (tlsIdentity != null) {
6631            uid = tlsIdentity.uid;
6632            pid = tlsIdentity.pid;
6633        }
6634
6635        // Our own process gets to do everything.
6636        if (pid == MY_PID) {
6637            return PackageManager.PERMISSION_GRANTED;
6638        }
6639        synchronized (this) {
6640            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6641                    ? PackageManager.PERMISSION_GRANTED
6642                    : PackageManager.PERMISSION_DENIED;
6643        }
6644    }
6645
6646    /**
6647     * Check if the targetPkg can be granted permission to access uri by
6648     * the callingUid using the given modeFlags.  Throws a security exception
6649     * if callingUid is not allowed to do this.  Returns the uid of the target
6650     * if the URI permission grant should be performed; returns -1 if it is not
6651     * needed (for example targetPkg already has permission to access the URI).
6652     * If you already know the uid of the target, you can supply it in
6653     * lastTargetUid else set that to -1.
6654     */
6655    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6656            final int modeFlags, int lastTargetUid) {
6657        if (!Intent.isAccessUriMode(modeFlags)) {
6658            return -1;
6659        }
6660
6661        if (targetPkg != null) {
6662            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6663                    "Checking grant " + targetPkg + " permission to " + grantUri);
6664        }
6665
6666        final IPackageManager pm = AppGlobals.getPackageManager();
6667
6668        // If this is not a content: uri, we can't do anything with it.
6669        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6670            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6671                    "Can't grant URI permission for non-content URI: " + grantUri);
6672            return -1;
6673        }
6674
6675        final String authority = grantUri.uri.getAuthority();
6676        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6677        if (pi == null) {
6678            Slog.w(TAG, "No content provider found for permission check: " +
6679                    grantUri.uri.toSafeString());
6680            return -1;
6681        }
6682
6683        int targetUid = lastTargetUid;
6684        if (targetUid < 0 && targetPkg != null) {
6685            try {
6686                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6687                if (targetUid < 0) {
6688                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6689                            "Can't grant URI permission no uid for: " + targetPkg);
6690                    return -1;
6691                }
6692            } catch (RemoteException ex) {
6693                return -1;
6694            }
6695        }
6696
6697        if (targetUid >= 0) {
6698            // First...  does the target actually need this permission?
6699            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6700                // No need to grant the target this permission.
6701                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6702                        "Target " + targetPkg + " already has full permission to " + grantUri);
6703                return -1;
6704            }
6705        } else {
6706            // First...  there is no target package, so can anyone access it?
6707            boolean allowed = pi.exported;
6708            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6709                if (pi.readPermission != null) {
6710                    allowed = false;
6711                }
6712            }
6713            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6714                if (pi.writePermission != null) {
6715                    allowed = false;
6716                }
6717            }
6718            if (allowed) {
6719                return -1;
6720            }
6721        }
6722
6723        /* There is a special cross user grant if:
6724         * - The target is on another user.
6725         * - Apps on the current user can access the uri without any uid permissions.
6726         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6727         * grant uri permissions.
6728         */
6729        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6730                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6731                modeFlags, false /*without considering the uid permissions*/);
6732
6733        // Second...  is the provider allowing granting of URI permissions?
6734        if (!specialCrossUserGrant) {
6735            if (!pi.grantUriPermissions) {
6736                throw new SecurityException("Provider " + pi.packageName
6737                        + "/" + pi.name
6738                        + " does not allow granting of Uri permissions (uri "
6739                        + grantUri + ")");
6740            }
6741            if (pi.uriPermissionPatterns != null) {
6742                final int N = pi.uriPermissionPatterns.length;
6743                boolean allowed = false;
6744                for (int i=0; i<N; i++) {
6745                    if (pi.uriPermissionPatterns[i] != null
6746                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6747                        allowed = true;
6748                        break;
6749                    }
6750                }
6751                if (!allowed) {
6752                    throw new SecurityException("Provider " + pi.packageName
6753                            + "/" + pi.name
6754                            + " does not allow granting of permission to path of Uri "
6755                            + grantUri);
6756                }
6757            }
6758        }
6759
6760        // Third...  does the caller itself have permission to access
6761        // this uri?
6762        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6763            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6764                // Require they hold a strong enough Uri permission
6765                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6766                    throw new SecurityException("Uid " + callingUid
6767                            + " does not have permission to uri " + grantUri);
6768                }
6769            }
6770        }
6771        return targetUid;
6772    }
6773
6774    /**
6775     * @param uri This uri must NOT contain an embedded userId.
6776     * @param userId The userId in which the uri is to be resolved.
6777     */
6778    @Override
6779    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6780            final int modeFlags, int userId) {
6781        enforceNotIsolatedCaller("checkGrantUriPermission");
6782        synchronized(this) {
6783            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6784                    new GrantUri(userId, uri, false), modeFlags, -1);
6785        }
6786    }
6787
6788    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6789            final int modeFlags, UriPermissionOwner owner) {
6790        if (!Intent.isAccessUriMode(modeFlags)) {
6791            return;
6792        }
6793
6794        // So here we are: the caller has the assumed permission
6795        // to the uri, and the target doesn't.  Let's now give this to
6796        // the target.
6797
6798        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6799                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6800
6801        final String authority = grantUri.uri.getAuthority();
6802        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6803        if (pi == null) {
6804            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6805            return;
6806        }
6807
6808        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6809            grantUri.prefix = true;
6810        }
6811        final UriPermission perm = findOrCreateUriPermissionLocked(
6812                pi.packageName, targetPkg, targetUid, grantUri);
6813        perm.grantModes(modeFlags, owner);
6814    }
6815
6816    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6817            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6818        if (targetPkg == null) {
6819            throw new NullPointerException("targetPkg");
6820        }
6821        int targetUid;
6822        final IPackageManager pm = AppGlobals.getPackageManager();
6823        try {
6824            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6825        } catch (RemoteException ex) {
6826            return;
6827        }
6828
6829        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6830                targetUid);
6831        if (targetUid < 0) {
6832            return;
6833        }
6834
6835        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6836                owner);
6837    }
6838
6839    static class NeededUriGrants extends ArrayList<GrantUri> {
6840        final String targetPkg;
6841        final int targetUid;
6842        final int flags;
6843
6844        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6845            this.targetPkg = targetPkg;
6846            this.targetUid = targetUid;
6847            this.flags = flags;
6848        }
6849    }
6850
6851    /**
6852     * Like checkGrantUriPermissionLocked, but takes an Intent.
6853     */
6854    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6855            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6856        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6857                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6858                + " clip=" + (intent != null ? intent.getClipData() : null)
6859                + " from " + intent + "; flags=0x"
6860                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6861
6862        if (targetPkg == null) {
6863            throw new NullPointerException("targetPkg");
6864        }
6865
6866        if (intent == null) {
6867            return null;
6868        }
6869        Uri data = intent.getData();
6870        ClipData clip = intent.getClipData();
6871        if (data == null && clip == null) {
6872            return null;
6873        }
6874        // Default userId for uris in the intent (if they don't specify it themselves)
6875        int contentUserHint = intent.getContentUserHint();
6876        if (contentUserHint == UserHandle.USER_CURRENT) {
6877            contentUserHint = UserHandle.getUserId(callingUid);
6878        }
6879        final IPackageManager pm = AppGlobals.getPackageManager();
6880        int targetUid;
6881        if (needed != null) {
6882            targetUid = needed.targetUid;
6883        } else {
6884            try {
6885                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6886            } catch (RemoteException ex) {
6887                return null;
6888            }
6889            if (targetUid < 0) {
6890                if (DEBUG_URI_PERMISSION) {
6891                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6892                            + " on user " + targetUserId);
6893                }
6894                return null;
6895            }
6896        }
6897        if (data != null) {
6898            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6899            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6900                    targetUid);
6901            if (targetUid > 0) {
6902                if (needed == null) {
6903                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6904                }
6905                needed.add(grantUri);
6906            }
6907        }
6908        if (clip != null) {
6909            for (int i=0; i<clip.getItemCount(); i++) {
6910                Uri uri = clip.getItemAt(i).getUri();
6911                if (uri != null) {
6912                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6913                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6914                            targetUid);
6915                    if (targetUid > 0) {
6916                        if (needed == null) {
6917                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6918                        }
6919                        needed.add(grantUri);
6920                    }
6921                } else {
6922                    Intent clipIntent = clip.getItemAt(i).getIntent();
6923                    if (clipIntent != null) {
6924                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6925                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6926                        if (newNeeded != null) {
6927                            needed = newNeeded;
6928                        }
6929                    }
6930                }
6931            }
6932        }
6933
6934        return needed;
6935    }
6936
6937    /**
6938     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6939     */
6940    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6941            UriPermissionOwner owner) {
6942        if (needed != null) {
6943            for (int i=0; i<needed.size(); i++) {
6944                GrantUri grantUri = needed.get(i);
6945                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6946                        grantUri, needed.flags, owner);
6947            }
6948        }
6949    }
6950
6951    void grantUriPermissionFromIntentLocked(int callingUid,
6952            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6953        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6954                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6955        if (needed == null) {
6956            return;
6957        }
6958
6959        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6960    }
6961
6962    /**
6963     * @param uri This uri must NOT contain an embedded userId.
6964     * @param userId The userId in which the uri is to be resolved.
6965     */
6966    @Override
6967    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6968            final int modeFlags, int userId) {
6969        enforceNotIsolatedCaller("grantUriPermission");
6970        GrantUri grantUri = new GrantUri(userId, uri, false);
6971        synchronized(this) {
6972            final ProcessRecord r = getRecordForAppLocked(caller);
6973            if (r == null) {
6974                throw new SecurityException("Unable to find app for caller "
6975                        + caller
6976                        + " when granting permission to uri " + grantUri);
6977            }
6978            if (targetPkg == null) {
6979                throw new IllegalArgumentException("null target");
6980            }
6981            if (grantUri == null) {
6982                throw new IllegalArgumentException("null uri");
6983            }
6984
6985            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6986                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6987                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6988                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6989
6990            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6991                    UserHandle.getUserId(r.uid));
6992        }
6993    }
6994
6995    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6996        if (perm.modeFlags == 0) {
6997            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6998                    perm.targetUid);
6999            if (perms != null) {
7000                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7001                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7002
7003                perms.remove(perm.uri);
7004                if (perms.isEmpty()) {
7005                    mGrantedUriPermissions.remove(perm.targetUid);
7006                }
7007            }
7008        }
7009    }
7010
7011    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7012        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7013
7014        final IPackageManager pm = AppGlobals.getPackageManager();
7015        final String authority = grantUri.uri.getAuthority();
7016        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7017        if (pi == null) {
7018            Slog.w(TAG, "No content provider found for permission revoke: "
7019                    + grantUri.toSafeString());
7020            return;
7021        }
7022
7023        // Does the caller have this permission on the URI?
7024        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7025            // Right now, if you are not the original owner of the permission,
7026            // you are not allowed to revoke it.
7027            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7028                throw new SecurityException("Uid " + callingUid
7029                        + " does not have permission to uri " + grantUri);
7030            //}
7031        }
7032
7033        boolean persistChanged = false;
7034
7035        // Go through all of the permissions and remove any that match.
7036        int N = mGrantedUriPermissions.size();
7037        for (int i = 0; i < N; i++) {
7038            final int targetUid = mGrantedUriPermissions.keyAt(i);
7039            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7040
7041            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7042                final UriPermission perm = it.next();
7043                if (perm.uri.sourceUserId == grantUri.sourceUserId
7044                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7045                    if (DEBUG_URI_PERMISSION)
7046                        Slog.v(TAG,
7047                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7048                    persistChanged |= perm.revokeModes(
7049                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7050                    if (perm.modeFlags == 0) {
7051                        it.remove();
7052                    }
7053                }
7054            }
7055
7056            if (perms.isEmpty()) {
7057                mGrantedUriPermissions.remove(targetUid);
7058                N--;
7059                i--;
7060            }
7061        }
7062
7063        if (persistChanged) {
7064            schedulePersistUriGrants();
7065        }
7066    }
7067
7068    /**
7069     * @param uri This uri must NOT contain an embedded userId.
7070     * @param userId The userId in which the uri is to be resolved.
7071     */
7072    @Override
7073    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7074            int userId) {
7075        enforceNotIsolatedCaller("revokeUriPermission");
7076        synchronized(this) {
7077            final ProcessRecord r = getRecordForAppLocked(caller);
7078            if (r == null) {
7079                throw new SecurityException("Unable to find app for caller "
7080                        + caller
7081                        + " when revoking permission to uri " + uri);
7082            }
7083            if (uri == null) {
7084                Slog.w(TAG, "revokeUriPermission: null uri");
7085                return;
7086            }
7087
7088            if (!Intent.isAccessUriMode(modeFlags)) {
7089                return;
7090            }
7091
7092            final IPackageManager pm = AppGlobals.getPackageManager();
7093            final String authority = uri.getAuthority();
7094            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7095            if (pi == null) {
7096                Slog.w(TAG, "No content provider found for permission revoke: "
7097                        + uri.toSafeString());
7098                return;
7099            }
7100
7101            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7102        }
7103    }
7104
7105    /**
7106     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7107     * given package.
7108     *
7109     * @param packageName Package name to match, or {@code null} to apply to all
7110     *            packages.
7111     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7112     *            to all users.
7113     * @param persistable If persistable grants should be removed.
7114     */
7115    private void removeUriPermissionsForPackageLocked(
7116            String packageName, int userHandle, boolean persistable) {
7117        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7118            throw new IllegalArgumentException("Must narrow by either package or user");
7119        }
7120
7121        boolean persistChanged = false;
7122
7123        int N = mGrantedUriPermissions.size();
7124        for (int i = 0; i < N; i++) {
7125            final int targetUid = mGrantedUriPermissions.keyAt(i);
7126            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7127
7128            // Only inspect grants matching user
7129            if (userHandle == UserHandle.USER_ALL
7130                    || userHandle == UserHandle.getUserId(targetUid)) {
7131                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7132                    final UriPermission perm = it.next();
7133
7134                    // Only inspect grants matching package
7135                    if (packageName == null || perm.sourcePkg.equals(packageName)
7136                            || perm.targetPkg.equals(packageName)) {
7137                        persistChanged |= perm.revokeModes(
7138                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7139
7140                        // Only remove when no modes remain; any persisted grants
7141                        // will keep this alive.
7142                        if (perm.modeFlags == 0) {
7143                            it.remove();
7144                        }
7145                    }
7146                }
7147
7148                if (perms.isEmpty()) {
7149                    mGrantedUriPermissions.remove(targetUid);
7150                    N--;
7151                    i--;
7152                }
7153            }
7154        }
7155
7156        if (persistChanged) {
7157            schedulePersistUriGrants();
7158        }
7159    }
7160
7161    @Override
7162    public IBinder newUriPermissionOwner(String name) {
7163        enforceNotIsolatedCaller("newUriPermissionOwner");
7164        synchronized(this) {
7165            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7166            return owner.getExternalTokenLocked();
7167        }
7168    }
7169
7170    /**
7171     * @param uri This uri must NOT contain an embedded userId.
7172     * @param sourceUserId The userId in which the uri is to be resolved.
7173     * @param targetUserId The userId of the app that receives the grant.
7174     */
7175    @Override
7176    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7177            final int modeFlags, int sourceUserId, int targetUserId) {
7178        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7179                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7180        synchronized(this) {
7181            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7182            if (owner == null) {
7183                throw new IllegalArgumentException("Unknown owner: " + token);
7184            }
7185            if (fromUid != Binder.getCallingUid()) {
7186                if (Binder.getCallingUid() != Process.myUid()) {
7187                    // Only system code can grant URI permissions on behalf
7188                    // of other users.
7189                    throw new SecurityException("nice try");
7190                }
7191            }
7192            if (targetPkg == null) {
7193                throw new IllegalArgumentException("null target");
7194            }
7195            if (uri == null) {
7196                throw new IllegalArgumentException("null uri");
7197            }
7198
7199            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7200                    modeFlags, owner, targetUserId);
7201        }
7202    }
7203
7204    /**
7205     * @param uri This uri must NOT contain an embedded userId.
7206     * @param userId The userId in which the uri is to be resolved.
7207     */
7208    @Override
7209    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7210        synchronized(this) {
7211            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7212            if (owner == null) {
7213                throw new IllegalArgumentException("Unknown owner: " + token);
7214            }
7215
7216            if (uri == null) {
7217                owner.removeUriPermissionsLocked(mode);
7218            } else {
7219                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7220            }
7221        }
7222    }
7223
7224    private void schedulePersistUriGrants() {
7225        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7226            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7227                    10 * DateUtils.SECOND_IN_MILLIS);
7228        }
7229    }
7230
7231    private void writeGrantedUriPermissions() {
7232        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7233
7234        // Snapshot permissions so we can persist without lock
7235        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7236        synchronized (this) {
7237            final int size = mGrantedUriPermissions.size();
7238            for (int i = 0; i < size; i++) {
7239                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7240                for (UriPermission perm : perms.values()) {
7241                    if (perm.persistedModeFlags != 0) {
7242                        persist.add(perm.snapshot());
7243                    }
7244                }
7245            }
7246        }
7247
7248        FileOutputStream fos = null;
7249        try {
7250            fos = mGrantFile.startWrite();
7251
7252            XmlSerializer out = new FastXmlSerializer();
7253            out.setOutput(fos, "utf-8");
7254            out.startDocument(null, true);
7255            out.startTag(null, TAG_URI_GRANTS);
7256            for (UriPermission.Snapshot perm : persist) {
7257                out.startTag(null, TAG_URI_GRANT);
7258                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7259                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7260                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7261                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7262                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7263                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7264                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7265                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7266                out.endTag(null, TAG_URI_GRANT);
7267            }
7268            out.endTag(null, TAG_URI_GRANTS);
7269            out.endDocument();
7270
7271            mGrantFile.finishWrite(fos);
7272        } catch (IOException e) {
7273            if (fos != null) {
7274                mGrantFile.failWrite(fos);
7275            }
7276        }
7277    }
7278
7279    private void readGrantedUriPermissionsLocked() {
7280        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7281
7282        final long now = System.currentTimeMillis();
7283
7284        FileInputStream fis = null;
7285        try {
7286            fis = mGrantFile.openRead();
7287            final XmlPullParser in = Xml.newPullParser();
7288            in.setInput(fis, null);
7289
7290            int type;
7291            while ((type = in.next()) != END_DOCUMENT) {
7292                final String tag = in.getName();
7293                if (type == START_TAG) {
7294                    if (TAG_URI_GRANT.equals(tag)) {
7295                        final int sourceUserId;
7296                        final int targetUserId;
7297                        final int userHandle = readIntAttribute(in,
7298                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7299                        if (userHandle != UserHandle.USER_NULL) {
7300                            // For backwards compatibility.
7301                            sourceUserId = userHandle;
7302                            targetUserId = userHandle;
7303                        } else {
7304                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7305                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7306                        }
7307                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7308                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7309                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7310                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7311                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7312                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7313
7314                        // Sanity check that provider still belongs to source package
7315                        final ProviderInfo pi = getProviderInfoLocked(
7316                                uri.getAuthority(), sourceUserId);
7317                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7318                            int targetUid = -1;
7319                            try {
7320                                targetUid = AppGlobals.getPackageManager()
7321                                        .getPackageUid(targetPkg, targetUserId);
7322                            } catch (RemoteException e) {
7323                            }
7324                            if (targetUid != -1) {
7325                                final UriPermission perm = findOrCreateUriPermissionLocked(
7326                                        sourcePkg, targetPkg, targetUid,
7327                                        new GrantUri(sourceUserId, uri, prefix));
7328                                perm.initPersistedModes(modeFlags, createdTime);
7329                            }
7330                        } else {
7331                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7332                                    + " but instead found " + pi);
7333                        }
7334                    }
7335                }
7336            }
7337        } catch (FileNotFoundException e) {
7338            // Missing grants is okay
7339        } catch (IOException e) {
7340            Log.wtf(TAG, "Failed reading Uri grants", e);
7341        } catch (XmlPullParserException e) {
7342            Log.wtf(TAG, "Failed reading Uri grants", e);
7343        } finally {
7344            IoUtils.closeQuietly(fis);
7345        }
7346    }
7347
7348    /**
7349     * @param uri This uri must NOT contain an embedded userId.
7350     * @param userId The userId in which the uri is to be resolved.
7351     */
7352    @Override
7353    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7354        enforceNotIsolatedCaller("takePersistableUriPermission");
7355
7356        Preconditions.checkFlagsArgument(modeFlags,
7357                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7358
7359        synchronized (this) {
7360            final int callingUid = Binder.getCallingUid();
7361            boolean persistChanged = false;
7362            GrantUri grantUri = new GrantUri(userId, uri, false);
7363
7364            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7365                    new GrantUri(userId, uri, false));
7366            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7367                    new GrantUri(userId, uri, true));
7368
7369            final boolean exactValid = (exactPerm != null)
7370                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7371            final boolean prefixValid = (prefixPerm != null)
7372                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7373
7374            if (!(exactValid || prefixValid)) {
7375                throw new SecurityException("No persistable permission grants found for UID "
7376                        + callingUid + " and Uri " + grantUri.toSafeString());
7377            }
7378
7379            if (exactValid) {
7380                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7381            }
7382            if (prefixValid) {
7383                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7384            }
7385
7386            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7387
7388            if (persistChanged) {
7389                schedulePersistUriGrants();
7390            }
7391        }
7392    }
7393
7394    /**
7395     * @param uri This uri must NOT contain an embedded userId.
7396     * @param userId The userId in which the uri is to be resolved.
7397     */
7398    @Override
7399    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7400        enforceNotIsolatedCaller("releasePersistableUriPermission");
7401
7402        Preconditions.checkFlagsArgument(modeFlags,
7403                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7404
7405        synchronized (this) {
7406            final int callingUid = Binder.getCallingUid();
7407            boolean persistChanged = false;
7408
7409            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7410                    new GrantUri(userId, uri, false));
7411            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7412                    new GrantUri(userId, uri, true));
7413            if (exactPerm == null && prefixPerm == null) {
7414                throw new SecurityException("No permission grants found for UID " + callingUid
7415                        + " and Uri " + uri.toSafeString());
7416            }
7417
7418            if (exactPerm != null) {
7419                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7420                removeUriPermissionIfNeededLocked(exactPerm);
7421            }
7422            if (prefixPerm != null) {
7423                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7424                removeUriPermissionIfNeededLocked(prefixPerm);
7425            }
7426
7427            if (persistChanged) {
7428                schedulePersistUriGrants();
7429            }
7430        }
7431    }
7432
7433    /**
7434     * Prune any older {@link UriPermission} for the given UID until outstanding
7435     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7436     *
7437     * @return if any mutations occured that require persisting.
7438     */
7439    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7440        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7441        if (perms == null) return false;
7442        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7443
7444        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7445        for (UriPermission perm : perms.values()) {
7446            if (perm.persistedModeFlags != 0) {
7447                persisted.add(perm);
7448            }
7449        }
7450
7451        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7452        if (trimCount <= 0) return false;
7453
7454        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7455        for (int i = 0; i < trimCount; i++) {
7456            final UriPermission perm = persisted.get(i);
7457
7458            if (DEBUG_URI_PERMISSION) {
7459                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7460            }
7461
7462            perm.releasePersistableModes(~0);
7463            removeUriPermissionIfNeededLocked(perm);
7464        }
7465
7466        return true;
7467    }
7468
7469    @Override
7470    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7471            String packageName, boolean incoming) {
7472        enforceNotIsolatedCaller("getPersistedUriPermissions");
7473        Preconditions.checkNotNull(packageName, "packageName");
7474
7475        final int callingUid = Binder.getCallingUid();
7476        final IPackageManager pm = AppGlobals.getPackageManager();
7477        try {
7478            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7479            if (packageUid != callingUid) {
7480                throw new SecurityException(
7481                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7482            }
7483        } catch (RemoteException e) {
7484            throw new SecurityException("Failed to verify package name ownership");
7485        }
7486
7487        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7488        synchronized (this) {
7489            if (incoming) {
7490                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7491                        callingUid);
7492                if (perms == null) {
7493                    Slog.w(TAG, "No permission grants found for " + packageName);
7494                } else {
7495                    for (UriPermission perm : perms.values()) {
7496                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7497                            result.add(perm.buildPersistedPublicApiObject());
7498                        }
7499                    }
7500                }
7501            } else {
7502                final int size = mGrantedUriPermissions.size();
7503                for (int i = 0; i < size; i++) {
7504                    final ArrayMap<GrantUri, UriPermission> perms =
7505                            mGrantedUriPermissions.valueAt(i);
7506                    for (UriPermission perm : perms.values()) {
7507                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7508                            result.add(perm.buildPersistedPublicApiObject());
7509                        }
7510                    }
7511                }
7512            }
7513        }
7514        return new ParceledListSlice<android.content.UriPermission>(result);
7515    }
7516
7517    @Override
7518    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7519        synchronized (this) {
7520            ProcessRecord app =
7521                who != null ? getRecordForAppLocked(who) : null;
7522            if (app == null) return;
7523
7524            Message msg = Message.obtain();
7525            msg.what = WAIT_FOR_DEBUGGER_MSG;
7526            msg.obj = app;
7527            msg.arg1 = waiting ? 1 : 0;
7528            mHandler.sendMessage(msg);
7529        }
7530    }
7531
7532    @Override
7533    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7534        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7535        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7536        outInfo.availMem = Process.getFreeMemory();
7537        outInfo.totalMem = Process.getTotalMemory();
7538        outInfo.threshold = homeAppMem;
7539        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7540        outInfo.hiddenAppThreshold = cachedAppMem;
7541        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7542                ProcessList.SERVICE_ADJ);
7543        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7544                ProcessList.VISIBLE_APP_ADJ);
7545        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7546                ProcessList.FOREGROUND_APP_ADJ);
7547    }
7548
7549    // =========================================================
7550    // TASK MANAGEMENT
7551    // =========================================================
7552
7553    @Override
7554    public List<IAppTask> getAppTasks(String callingPackage) {
7555        int callingUid = Binder.getCallingUid();
7556        long ident = Binder.clearCallingIdentity();
7557
7558        synchronized(this) {
7559            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7560            try {
7561                if (localLOGV) Slog.v(TAG, "getAppTasks");
7562
7563                final int N = mRecentTasks.size();
7564                for (int i = 0; i < N; i++) {
7565                    TaskRecord tr = mRecentTasks.get(i);
7566                    // Skip tasks that do not match the caller.  We don't need to verify
7567                    // callingPackage, because we are also limiting to callingUid and know
7568                    // that will limit to the correct security sandbox.
7569                    if (tr.effectiveUid != callingUid) {
7570                        continue;
7571                    }
7572                    Intent intent = tr.getBaseIntent();
7573                    if (intent == null ||
7574                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7575                        continue;
7576                    }
7577                    ActivityManager.RecentTaskInfo taskInfo =
7578                            createRecentTaskInfoFromTaskRecord(tr);
7579                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7580                    list.add(taskImpl);
7581                }
7582            } finally {
7583                Binder.restoreCallingIdentity(ident);
7584            }
7585            return list;
7586        }
7587    }
7588
7589    @Override
7590    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7591        final int callingUid = Binder.getCallingUid();
7592        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7593
7594        synchronized(this) {
7595            if (localLOGV) Slog.v(
7596                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7597
7598            final boolean allowed = checkCallingPermission(
7599                    android.Manifest.permission.GET_TASKS)
7600                    == PackageManager.PERMISSION_GRANTED;
7601            if (!allowed) {
7602                Slog.w(TAG, "getTasks: caller " + callingUid
7603                        + " does not hold GET_TASKS; limiting output");
7604            }
7605
7606            // TODO: Improve with MRU list from all ActivityStacks.
7607            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7608        }
7609
7610        return list;
7611    }
7612
7613    TaskRecord getMostRecentTask() {
7614        return mRecentTasks.get(0);
7615    }
7616
7617    /**
7618     * Creates a new RecentTaskInfo from a TaskRecord.
7619     */
7620    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7621        // Update the task description to reflect any changes in the task stack
7622        tr.updateTaskDescription();
7623
7624        // Compose the recent task info
7625        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7626        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7627        rti.persistentId = tr.taskId;
7628        rti.baseIntent = new Intent(tr.getBaseIntent());
7629        rti.origActivity = tr.origActivity;
7630        rti.description = tr.lastDescription;
7631        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7632        rti.userId = tr.userId;
7633        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7634        rti.firstActiveTime = tr.firstActiveTime;
7635        rti.lastActiveTime = tr.lastActiveTime;
7636        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7637        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7638        return rti;
7639    }
7640
7641    @Override
7642    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7643        final int callingUid = Binder.getCallingUid();
7644        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7645                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7646
7647        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7648        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7649        synchronized (this) {
7650            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7651                    == PackageManager.PERMISSION_GRANTED;
7652            if (!allowed) {
7653                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7654                        + " does not hold GET_TASKS; limiting output");
7655            }
7656            final boolean detailed = checkCallingPermission(
7657                    android.Manifest.permission.GET_DETAILED_TASKS)
7658                    == PackageManager.PERMISSION_GRANTED;
7659
7660            IPackageManager pm = AppGlobals.getPackageManager();
7661
7662            final int N = mRecentTasks.size();
7663            ArrayList<ActivityManager.RecentTaskInfo> res
7664                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7665                            maxNum < N ? maxNum : N);
7666
7667            final Set<Integer> includedUsers;
7668            if (includeProfiles) {
7669                includedUsers = getProfileIdsLocked(userId);
7670            } else {
7671                includedUsers = new HashSet<Integer>();
7672            }
7673            includedUsers.add(Integer.valueOf(userId));
7674
7675            // Regroup affiliated tasks together.
7676            for (int i = 0; i < N; ) {
7677                TaskRecord task = mRecentTasks.remove(i);
7678                if (mTmpRecents.contains(task)) {
7679                    continue;
7680                }
7681                int affiliatedTaskId = task.mAffiliatedTaskId;
7682                while (true) {
7683                    TaskRecord next = task.mNextAffiliate;
7684                    if (next == null) {
7685                        break;
7686                    }
7687                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7688                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7689                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7690                        task.setNextAffiliate(null);
7691                        if (next.mPrevAffiliate == task) {
7692                            next.setPrevAffiliate(null);
7693                        }
7694                        break;
7695                    }
7696                    if (next.mPrevAffiliate != task) {
7697                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7698                                next.mPrevAffiliate + " task=" + task);
7699                        next.setPrevAffiliate(null);
7700                        break;
7701                    }
7702                    if (!mRecentTasks.contains(next)) {
7703                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7704                        task.setNextAffiliate(null);
7705                        if (next.mPrevAffiliate == task) {
7706                            next.setPrevAffiliate(null);
7707                        }
7708                        break;
7709                    }
7710                    task = next;
7711                }
7712                // task is now the end of the list
7713                do {
7714                    mRecentTasks.remove(task);
7715                    mRecentTasks.add(i++, task);
7716                    mTmpRecents.add(task);
7717                } while ((task = task.mPrevAffiliate) != null);
7718            }
7719            mTmpRecents.clear();
7720            // mRecentTasks is now in sorted, affiliated order.
7721
7722            for (int i=0; i<N && maxNum > 0; i++) {
7723                TaskRecord tr = mRecentTasks.get(i);
7724                // Only add calling user or related users recent tasks
7725                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7726                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7727                    continue;
7728                }
7729
7730                // Return the entry if desired by the caller.  We always return
7731                // the first entry, because callers always expect this to be the
7732                // foreground app.  We may filter others if the caller has
7733                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7734                // we should exclude the entry.
7735
7736                if (i == 0
7737                        || withExcluded
7738                        || (tr.intent == null)
7739                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7740                                == 0)) {
7741                    if (!allowed) {
7742                        // If the caller doesn't have the GET_TASKS permission, then only
7743                        // allow them to see a small subset of tasks -- their own and home.
7744                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7745                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7746                            continue;
7747                        }
7748                    }
7749                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7750                        // Don't include auto remove tasks that are finished or finishing.
7751                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7752                                + tr);
7753                        continue;
7754                    }
7755
7756                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7757                    if (!detailed) {
7758                        rti.baseIntent.replaceExtras((Bundle)null);
7759                    }
7760
7761                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7762                        // Check whether this activity is currently available.
7763                        try {
7764                            if (rti.origActivity != null) {
7765                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7766                                        == null) {
7767                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail orig act: "
7768                                            + tr);
7769                                    continue;
7770                                }
7771                            } else if (rti.baseIntent != null) {
7772                                if (pm.queryIntentActivities(rti.baseIntent,
7773                                        null, 0, userId) == null) {
7774                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail intent: "
7775                                            + tr);
7776                                    continue;
7777                                }
7778                            }
7779                        } catch (RemoteException e) {
7780                            // Will never happen.
7781                        }
7782                    }
7783
7784                    res.add(rti);
7785                    maxNum--;
7786                }
7787            }
7788            return res;
7789        }
7790    }
7791
7792    private TaskRecord recentTaskForIdLocked(int id) {
7793        final int N = mRecentTasks.size();
7794            for (int i=0; i<N; i++) {
7795                TaskRecord tr = mRecentTasks.get(i);
7796                if (tr.taskId == id) {
7797                    return tr;
7798                }
7799            }
7800            return null;
7801    }
7802
7803    @Override
7804    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7805        synchronized (this) {
7806            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7807                    "getTaskThumbnail()");
7808            TaskRecord tr = recentTaskForIdLocked(id);
7809            if (tr != null) {
7810                return tr.getTaskThumbnailLocked();
7811            }
7812        }
7813        return null;
7814    }
7815
7816    @Override
7817    public int addAppTask(IBinder activityToken, Intent intent,
7818            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7819        final int callingUid = Binder.getCallingUid();
7820        final long callingIdent = Binder.clearCallingIdentity();
7821
7822        try {
7823            synchronized (this) {
7824                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7825                if (r == null) {
7826                    throw new IllegalArgumentException("Activity does not exist; token="
7827                            + activityToken);
7828                }
7829                ComponentName comp = intent.getComponent();
7830                if (comp == null) {
7831                    throw new IllegalArgumentException("Intent " + intent
7832                            + " must specify explicit component");
7833                }
7834                if (thumbnail.getWidth() != mThumbnailWidth
7835                        || thumbnail.getHeight() != mThumbnailHeight) {
7836                    throw new IllegalArgumentException("Bad thumbnail size: got "
7837                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7838                            + mThumbnailWidth + "x" + mThumbnailHeight);
7839                }
7840                if (intent.getSelector() != null) {
7841                    intent.setSelector(null);
7842                }
7843                if (intent.getSourceBounds() != null) {
7844                    intent.setSourceBounds(null);
7845                }
7846                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7847                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7848                        // The caller has added this as an auto-remove task...  that makes no
7849                        // sense, so turn off auto-remove.
7850                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7851                    }
7852                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7853                    // Must be a new task.
7854                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7855                }
7856                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7857                    mLastAddedTaskActivity = null;
7858                }
7859                ActivityInfo ainfo = mLastAddedTaskActivity;
7860                if (ainfo == null) {
7861                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7862                            comp, 0, UserHandle.getUserId(callingUid));
7863                    if (ainfo.applicationInfo.uid != callingUid) {
7864                        throw new SecurityException(
7865                                "Can't add task for another application: target uid="
7866                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7867                    }
7868                }
7869
7870                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7871                        intent, description);
7872
7873                int trimIdx = trimRecentsForTask(task, false);
7874                if (trimIdx >= 0) {
7875                    // If this would have caused a trim, then we'll abort because that
7876                    // means it would be added at the end of the list but then just removed.
7877                    return -1;
7878                }
7879
7880                final int N = mRecentTasks.size();
7881                if (N >= (MAX_RECENT_TASKS-1)) {
7882                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7883                    tr.disposeThumbnail();
7884                    tr.closeRecentsChain();
7885                }
7886
7887                mRecentTasks.add(task);
7888                r.task.stack.addTask(task, false, false);
7889
7890                task.setLastThumbnail(thumbnail);
7891                task.freeLastThumbnail();
7892
7893                return task.taskId;
7894            }
7895        } finally {
7896            Binder.restoreCallingIdentity(callingIdent);
7897        }
7898    }
7899
7900    @Override
7901    public Point getAppTaskThumbnailSize() {
7902        synchronized (this) {
7903            return new Point(mThumbnailWidth,  mThumbnailHeight);
7904        }
7905    }
7906
7907    @Override
7908    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7909        synchronized (this) {
7910            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7911            if (r != null) {
7912                r.taskDescription = td;
7913                r.task.updateTaskDescription();
7914            }
7915        }
7916    }
7917
7918    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7919        if (!pr.killedByAm) {
7920            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7921            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7922                    pr.processName, pr.setAdj, reason);
7923            pr.killedByAm = true;
7924            Process.killProcessQuiet(pr.pid);
7925            Process.killProcessGroup(pr.info.uid, pr.pid);
7926        }
7927    }
7928
7929    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7930        tr.disposeThumbnail();
7931        mRecentTasks.remove(tr);
7932        tr.closeRecentsChain();
7933        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7934        Intent baseIntent = new Intent(
7935                tr.intent != null ? tr.intent : tr.affinityIntent);
7936        ComponentName component = baseIntent.getComponent();
7937        if (component == null) {
7938            Slog.w(TAG, "Now component for base intent of task: " + tr);
7939            return;
7940        }
7941
7942        // Find any running services associated with this app.
7943        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7944
7945        if (killProcesses) {
7946            // Find any running processes associated with this app.
7947            final String pkg = component.getPackageName();
7948            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7949            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7950            for (int i=0; i<pmap.size(); i++) {
7951                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7952                for (int j=0; j<uids.size(); j++) {
7953                    ProcessRecord proc = uids.valueAt(j);
7954                    if (proc.userId != tr.userId) {
7955                        continue;
7956                    }
7957                    if (!proc.pkgList.containsKey(pkg)) {
7958                        continue;
7959                    }
7960                    procs.add(proc);
7961                }
7962            }
7963
7964            // Kill the running processes.
7965            for (int i=0; i<procs.size(); i++) {
7966                ProcessRecord pr = procs.get(i);
7967                if (pr == mHomeProcess) {
7968                    // Don't kill the home process along with tasks from the same package.
7969                    continue;
7970                }
7971                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7972                    killUnneededProcessLocked(pr, "remove task");
7973                } else {
7974                    pr.waitingToKill = "remove task";
7975                }
7976            }
7977        }
7978    }
7979
7980    /**
7981     * Removes the task with the specified task id.
7982     *
7983     * @param taskId Identifier of the task to be removed.
7984     * @param flags Additional operational flags.  May be 0 or
7985     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7986     * @return Returns true if the given task was found and removed.
7987     */
7988    private boolean removeTaskByIdLocked(int taskId, int flags) {
7989        TaskRecord tr = recentTaskForIdLocked(taskId);
7990        if (tr != null) {
7991            tr.removeTaskActivitiesLocked();
7992            cleanUpRemovedTaskLocked(tr, flags);
7993            if (tr.isPersistable) {
7994                notifyTaskPersisterLocked(null, true);
7995            }
7996            return true;
7997        }
7998        return false;
7999    }
8000
8001    @Override
8002    public boolean removeTask(int taskId, int flags) {
8003        synchronized (this) {
8004            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8005                    "removeTask()");
8006            long ident = Binder.clearCallingIdentity();
8007            try {
8008                return removeTaskByIdLocked(taskId, flags);
8009            } finally {
8010                Binder.restoreCallingIdentity(ident);
8011            }
8012        }
8013    }
8014
8015    /**
8016     * TODO: Add mController hook
8017     */
8018    @Override
8019    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8020        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8021                "moveTaskToFront()");
8022
8023        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8024        synchronized(this) {
8025            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8026                    Binder.getCallingUid(), "Task to front")) {
8027                ActivityOptions.abort(options);
8028                return;
8029            }
8030            final long origId = Binder.clearCallingIdentity();
8031            try {
8032                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8033                if (task == null) {
8034                    return;
8035                }
8036                if (mStackSupervisor.isLockTaskModeViolation(task)) {
8037                    mStackSupervisor.showLockTaskToast();
8038                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8039                    return;
8040                }
8041                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8042                if (prev != null && prev.isRecentsActivity()) {
8043                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8044                }
8045                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8046            } finally {
8047                Binder.restoreCallingIdentity(origId);
8048            }
8049            ActivityOptions.abort(options);
8050        }
8051    }
8052
8053    @Override
8054    public void moveTaskToBack(int taskId) {
8055        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8056                "moveTaskToBack()");
8057
8058        synchronized(this) {
8059            TaskRecord tr = recentTaskForIdLocked(taskId);
8060            if (tr != null) {
8061                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8062                ActivityStack stack = tr.stack;
8063                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8064                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8065                            Binder.getCallingUid(), "Task to back")) {
8066                        return;
8067                    }
8068                }
8069                final long origId = Binder.clearCallingIdentity();
8070                try {
8071                    stack.moveTaskToBackLocked(taskId, null);
8072                } finally {
8073                    Binder.restoreCallingIdentity(origId);
8074                }
8075            }
8076        }
8077    }
8078
8079    /**
8080     * Moves an activity, and all of the other activities within the same task, to the bottom
8081     * of the history stack.  The activity's order within the task is unchanged.
8082     *
8083     * @param token A reference to the activity we wish to move
8084     * @param nonRoot If false then this only works if the activity is the root
8085     *                of a task; if true it will work for any activity in a task.
8086     * @return Returns true if the move completed, false if not.
8087     */
8088    @Override
8089    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8090        enforceNotIsolatedCaller("moveActivityTaskToBack");
8091        synchronized(this) {
8092            final long origId = Binder.clearCallingIdentity();
8093            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8094            if (taskId >= 0) {
8095                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8096            }
8097            Binder.restoreCallingIdentity(origId);
8098        }
8099        return false;
8100    }
8101
8102    @Override
8103    public void moveTaskBackwards(int task) {
8104        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8105                "moveTaskBackwards()");
8106
8107        synchronized(this) {
8108            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8109                    Binder.getCallingUid(), "Task backwards")) {
8110                return;
8111            }
8112            final long origId = Binder.clearCallingIdentity();
8113            moveTaskBackwardsLocked(task);
8114            Binder.restoreCallingIdentity(origId);
8115        }
8116    }
8117
8118    private final void moveTaskBackwardsLocked(int task) {
8119        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8120    }
8121
8122    @Override
8123    public IBinder getHomeActivityToken() throws RemoteException {
8124        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8125                "getHomeActivityToken()");
8126        synchronized (this) {
8127            return mStackSupervisor.getHomeActivityToken();
8128        }
8129    }
8130
8131    @Override
8132    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8133            IActivityContainerCallback callback) throws RemoteException {
8134        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8135                "createActivityContainer()");
8136        synchronized (this) {
8137            if (parentActivityToken == null) {
8138                throw new IllegalArgumentException("parent token must not be null");
8139            }
8140            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8141            if (r == null) {
8142                return null;
8143            }
8144            if (callback == null) {
8145                throw new IllegalArgumentException("callback must not be null");
8146            }
8147            return mStackSupervisor.createActivityContainer(r, callback);
8148        }
8149    }
8150
8151    @Override
8152    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8153        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8154                "deleteActivityContainer()");
8155        synchronized (this) {
8156            mStackSupervisor.deleteActivityContainer(container);
8157        }
8158    }
8159
8160    @Override
8161    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8162            throws RemoteException {
8163        synchronized (this) {
8164            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8165            if (stack != null) {
8166                return stack.mActivityContainer;
8167            }
8168            return null;
8169        }
8170    }
8171
8172    @Override
8173    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8174        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8175                "moveTaskToStack()");
8176        if (stackId == HOME_STACK_ID) {
8177            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8178                    new RuntimeException("here").fillInStackTrace());
8179        }
8180        synchronized (this) {
8181            long ident = Binder.clearCallingIdentity();
8182            try {
8183                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8184                        + stackId + " toTop=" + toTop);
8185                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8186            } finally {
8187                Binder.restoreCallingIdentity(ident);
8188            }
8189        }
8190    }
8191
8192    @Override
8193    public void resizeStack(int stackBoxId, Rect bounds) {
8194        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8195                "resizeStackBox()");
8196        long ident = Binder.clearCallingIdentity();
8197        try {
8198            mWindowManager.resizeStack(stackBoxId, bounds);
8199        } finally {
8200            Binder.restoreCallingIdentity(ident);
8201        }
8202    }
8203
8204    @Override
8205    public List<StackInfo> getAllStackInfos() {
8206        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8207                "getAllStackInfos()");
8208        long ident = Binder.clearCallingIdentity();
8209        try {
8210            synchronized (this) {
8211                return mStackSupervisor.getAllStackInfosLocked();
8212            }
8213        } finally {
8214            Binder.restoreCallingIdentity(ident);
8215        }
8216    }
8217
8218    @Override
8219    public StackInfo getStackInfo(int stackId) {
8220        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8221                "getStackInfo()");
8222        long ident = Binder.clearCallingIdentity();
8223        try {
8224            synchronized (this) {
8225                return mStackSupervisor.getStackInfoLocked(stackId);
8226            }
8227        } finally {
8228            Binder.restoreCallingIdentity(ident);
8229        }
8230    }
8231
8232    @Override
8233    public boolean isInHomeStack(int taskId) {
8234        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8235                "getStackInfo()");
8236        long ident = Binder.clearCallingIdentity();
8237        try {
8238            synchronized (this) {
8239                TaskRecord tr = recentTaskForIdLocked(taskId);
8240                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8241            }
8242        } finally {
8243            Binder.restoreCallingIdentity(ident);
8244        }
8245    }
8246
8247    @Override
8248    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8249        synchronized(this) {
8250            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8251        }
8252    }
8253
8254    private boolean isLockTaskAuthorized(String pkg) {
8255        final DevicePolicyManager dpm = (DevicePolicyManager)
8256                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8257        try {
8258            int uid = mContext.getPackageManager().getPackageUid(pkg,
8259                    Binder.getCallingUserHandle().getIdentifier());
8260            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8261        } catch (NameNotFoundException e) {
8262            return false;
8263        }
8264    }
8265
8266    void startLockTaskMode(TaskRecord task) {
8267        final String pkg;
8268        synchronized (this) {
8269            pkg = task.intent.getComponent().getPackageName();
8270        }
8271        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8272        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8273            final TaskRecord taskRecord = task;
8274            mHandler.post(new Runnable() {
8275                @Override
8276                public void run() {
8277                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8278                }
8279            });
8280            return;
8281        }
8282        long ident = Binder.clearCallingIdentity();
8283        try {
8284            synchronized (this) {
8285                // Since we lost lock on task, make sure it is still there.
8286                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8287                if (task != null) {
8288                    if (!isSystemInitiated
8289                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8290                        throw new IllegalArgumentException("Invalid task, not in foreground");
8291                    }
8292                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8293                }
8294            }
8295        } finally {
8296            Binder.restoreCallingIdentity(ident);
8297        }
8298    }
8299
8300    @Override
8301    public void startLockTaskMode(int taskId) {
8302        final TaskRecord task;
8303        long ident = Binder.clearCallingIdentity();
8304        try {
8305            synchronized (this) {
8306                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8307            }
8308        } finally {
8309            Binder.restoreCallingIdentity(ident);
8310        }
8311        if (task != null) {
8312            startLockTaskMode(task);
8313        }
8314    }
8315
8316    @Override
8317    public void startLockTaskMode(IBinder token) {
8318        final TaskRecord task;
8319        long ident = Binder.clearCallingIdentity();
8320        try {
8321            synchronized (this) {
8322                final ActivityRecord r = ActivityRecord.forToken(token);
8323                if (r == null) {
8324                    return;
8325                }
8326                task = r.task;
8327            }
8328        } finally {
8329            Binder.restoreCallingIdentity(ident);
8330        }
8331        if (task != null) {
8332            startLockTaskMode(task);
8333        }
8334    }
8335
8336    @Override
8337    public void startLockTaskModeOnCurrent() throws RemoteException {
8338        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8339        ActivityRecord r = null;
8340        synchronized (this) {
8341            r = mStackSupervisor.topRunningActivityLocked();
8342        }
8343        startLockTaskMode(r.task);
8344    }
8345
8346    @Override
8347    public void stopLockTaskMode() {
8348        // Verify that the user matches the package of the intent for the TaskRecord
8349        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8350        // and stopLockTaskMode.
8351        final int callingUid = Binder.getCallingUid();
8352        if (callingUid != Process.SYSTEM_UID) {
8353            try {
8354                String pkg =
8355                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8356                int uid = mContext.getPackageManager().getPackageUid(pkg,
8357                        Binder.getCallingUserHandle().getIdentifier());
8358                if (uid != callingUid) {
8359                    throw new SecurityException("Invalid uid, expected " + uid);
8360                }
8361            } catch (NameNotFoundException e) {
8362                Log.d(TAG, "stopLockTaskMode " + e);
8363                return;
8364            }
8365        }
8366        long ident = Binder.clearCallingIdentity();
8367        try {
8368            Log.d(TAG, "stopLockTaskMode");
8369            // Stop lock task
8370            synchronized (this) {
8371                mStackSupervisor.setLockTaskModeLocked(null, false);
8372            }
8373        } finally {
8374            Binder.restoreCallingIdentity(ident);
8375        }
8376    }
8377
8378    @Override
8379    public void stopLockTaskModeOnCurrent() throws RemoteException {
8380        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8381        long ident = Binder.clearCallingIdentity();
8382        try {
8383            stopLockTaskMode();
8384        } finally {
8385            Binder.restoreCallingIdentity(ident);
8386        }
8387    }
8388
8389    @Override
8390    public boolean isInLockTaskMode() {
8391        synchronized (this) {
8392            return mStackSupervisor.isInLockTaskMode();
8393        }
8394    }
8395
8396    // =========================================================
8397    // CONTENT PROVIDERS
8398    // =========================================================
8399
8400    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8401        List<ProviderInfo> providers = null;
8402        try {
8403            providers = AppGlobals.getPackageManager().
8404                queryContentProviders(app.processName, app.uid,
8405                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8406        } catch (RemoteException ex) {
8407        }
8408        if (DEBUG_MU)
8409            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8410        int userId = app.userId;
8411        if (providers != null) {
8412            int N = providers.size();
8413            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8414            for (int i=0; i<N; i++) {
8415                ProviderInfo cpi =
8416                    (ProviderInfo)providers.get(i);
8417                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8418                        cpi.name, cpi.flags);
8419                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8420                    // This is a singleton provider, but a user besides the
8421                    // default user is asking to initialize a process it runs
8422                    // in...  well, no, it doesn't actually run in this process,
8423                    // it runs in the process of the default user.  Get rid of it.
8424                    providers.remove(i);
8425                    N--;
8426                    i--;
8427                    continue;
8428                }
8429
8430                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8431                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8432                if (cpr == null) {
8433                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8434                    mProviderMap.putProviderByClass(comp, cpr);
8435                }
8436                if (DEBUG_MU)
8437                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8438                app.pubProviders.put(cpi.name, cpr);
8439                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8440                    // Don't add this if it is a platform component that is marked
8441                    // to run in multiple processes, because this is actually
8442                    // part of the framework so doesn't make sense to track as a
8443                    // separate apk in the process.
8444                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8445                            mProcessStats);
8446                }
8447                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8448            }
8449        }
8450        return providers;
8451    }
8452
8453    /**
8454     * Check if {@link ProcessRecord} has a possible chance at accessing the
8455     * given {@link ProviderInfo}. Final permission checking is always done
8456     * in {@link ContentProvider}.
8457     */
8458    private final String checkContentProviderPermissionLocked(
8459            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8460        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8461        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8462        boolean checkedGrants = false;
8463        if (checkUser) {
8464            // Looking for cross-user grants before enforcing the typical cross-users permissions
8465            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8466            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8467                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8468                    return null;
8469                }
8470                checkedGrants = true;
8471            }
8472            userId = handleIncomingUser(callingPid, callingUid, userId,
8473                    false, ALLOW_NON_FULL,
8474                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8475            if (userId != tmpTargetUserId) {
8476                // When we actually went to determine the final targer user ID, this ended
8477                // up different than our initial check for the authority.  This is because
8478                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8479                // SELF.  So we need to re-check the grants again.
8480                checkedGrants = false;
8481            }
8482        }
8483        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8484                cpi.applicationInfo.uid, cpi.exported)
8485                == PackageManager.PERMISSION_GRANTED) {
8486            return null;
8487        }
8488        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8489                cpi.applicationInfo.uid, cpi.exported)
8490                == PackageManager.PERMISSION_GRANTED) {
8491            return null;
8492        }
8493
8494        PathPermission[] pps = cpi.pathPermissions;
8495        if (pps != null) {
8496            int i = pps.length;
8497            while (i > 0) {
8498                i--;
8499                PathPermission pp = pps[i];
8500                String pprperm = pp.getReadPermission();
8501                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8502                        cpi.applicationInfo.uid, cpi.exported)
8503                        == PackageManager.PERMISSION_GRANTED) {
8504                    return null;
8505                }
8506                String ppwperm = pp.getWritePermission();
8507                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8508                        cpi.applicationInfo.uid, cpi.exported)
8509                        == PackageManager.PERMISSION_GRANTED) {
8510                    return null;
8511                }
8512            }
8513        }
8514        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8515            return null;
8516        }
8517
8518        String msg;
8519        if (!cpi.exported) {
8520            msg = "Permission Denial: opening provider " + cpi.name
8521                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8522                    + ", uid=" + callingUid + ") that is not exported from uid "
8523                    + cpi.applicationInfo.uid;
8524        } else {
8525            msg = "Permission Denial: opening provider " + cpi.name
8526                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8527                    + ", uid=" + callingUid + ") requires "
8528                    + cpi.readPermission + " or " + cpi.writePermission;
8529        }
8530        Slog.w(TAG, msg);
8531        return msg;
8532    }
8533
8534    /**
8535     * Returns if the ContentProvider has granted a uri to callingUid
8536     */
8537    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8538        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8539        if (perms != null) {
8540            for (int i=perms.size()-1; i>=0; i--) {
8541                GrantUri grantUri = perms.keyAt(i);
8542                if (grantUri.sourceUserId == userId || !checkUser) {
8543                    if (matchesProvider(grantUri.uri, cpi)) {
8544                        return true;
8545                    }
8546                }
8547            }
8548        }
8549        return false;
8550    }
8551
8552    /**
8553     * Returns true if the uri authority is one of the authorities specified in the provider.
8554     */
8555    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8556        String uriAuth = uri.getAuthority();
8557        String cpiAuth = cpi.authority;
8558        if (cpiAuth.indexOf(';') == -1) {
8559            return cpiAuth.equals(uriAuth);
8560        }
8561        String[] cpiAuths = cpiAuth.split(";");
8562        int length = cpiAuths.length;
8563        for (int i = 0; i < length; i++) {
8564            if (cpiAuths[i].equals(uriAuth)) return true;
8565        }
8566        return false;
8567    }
8568
8569    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8570            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8571        if (r != null) {
8572            for (int i=0; i<r.conProviders.size(); i++) {
8573                ContentProviderConnection conn = r.conProviders.get(i);
8574                if (conn.provider == cpr) {
8575                    if (DEBUG_PROVIDER) Slog.v(TAG,
8576                            "Adding provider requested by "
8577                            + r.processName + " from process "
8578                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8579                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8580                    if (stable) {
8581                        conn.stableCount++;
8582                        conn.numStableIncs++;
8583                    } else {
8584                        conn.unstableCount++;
8585                        conn.numUnstableIncs++;
8586                    }
8587                    return conn;
8588                }
8589            }
8590            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8591            if (stable) {
8592                conn.stableCount = 1;
8593                conn.numStableIncs = 1;
8594            } else {
8595                conn.unstableCount = 1;
8596                conn.numUnstableIncs = 1;
8597            }
8598            cpr.connections.add(conn);
8599            r.conProviders.add(conn);
8600            return conn;
8601        }
8602        cpr.addExternalProcessHandleLocked(externalProcessToken);
8603        return null;
8604    }
8605
8606    boolean decProviderCountLocked(ContentProviderConnection conn,
8607            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8608        if (conn != null) {
8609            cpr = conn.provider;
8610            if (DEBUG_PROVIDER) Slog.v(TAG,
8611                    "Removing provider requested by "
8612                    + conn.client.processName + " from process "
8613                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8614                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8615            if (stable) {
8616                conn.stableCount--;
8617            } else {
8618                conn.unstableCount--;
8619            }
8620            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8621                cpr.connections.remove(conn);
8622                conn.client.conProviders.remove(conn);
8623                return true;
8624            }
8625            return false;
8626        }
8627        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8628        return false;
8629    }
8630
8631    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8632            String name, IBinder token, boolean stable, int userId) {
8633        ContentProviderRecord cpr;
8634        ContentProviderConnection conn = null;
8635        ProviderInfo cpi = null;
8636
8637        synchronized(this) {
8638            ProcessRecord r = null;
8639            if (caller != null) {
8640                r = getRecordForAppLocked(caller);
8641                if (r == null) {
8642                    throw new SecurityException(
8643                            "Unable to find app for caller " + caller
8644                          + " (pid=" + Binder.getCallingPid()
8645                          + ") when getting content provider " + name);
8646                }
8647            }
8648
8649            boolean checkCrossUser = true;
8650
8651            // First check if this content provider has been published...
8652            cpr = mProviderMap.getProviderByName(name, userId);
8653            // If that didn't work, check if it exists for user 0 and then
8654            // verify that it's a singleton provider before using it.
8655            if (cpr == null && userId != UserHandle.USER_OWNER) {
8656                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8657                if (cpr != null) {
8658                    cpi = cpr.info;
8659                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8660                            cpi.name, cpi.flags)
8661                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8662                        userId = UserHandle.USER_OWNER;
8663                        checkCrossUser = false;
8664                    } else {
8665                        cpr = null;
8666                        cpi = null;
8667                    }
8668                }
8669            }
8670
8671            boolean providerRunning = cpr != null;
8672            if (providerRunning) {
8673                cpi = cpr.info;
8674                String msg;
8675                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8676                        != null) {
8677                    throw new SecurityException(msg);
8678                }
8679
8680                if (r != null && cpr.canRunHere(r)) {
8681                    // This provider has been published or is in the process
8682                    // of being published...  but it is also allowed to run
8683                    // in the caller's process, so don't make a connection
8684                    // and just let the caller instantiate its own instance.
8685                    ContentProviderHolder holder = cpr.newHolder(null);
8686                    // don't give caller the provider object, it needs
8687                    // to make its own.
8688                    holder.provider = null;
8689                    return holder;
8690                }
8691
8692                final long origId = Binder.clearCallingIdentity();
8693
8694                // In this case the provider instance already exists, so we can
8695                // return it right away.
8696                conn = incProviderCountLocked(r, cpr, token, stable);
8697                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8698                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8699                        // If this is a perceptible app accessing the provider,
8700                        // make sure to count it as being accessed and thus
8701                        // back up on the LRU list.  This is good because
8702                        // content providers are often expensive to start.
8703                        updateLruProcessLocked(cpr.proc, false, null);
8704                    }
8705                }
8706
8707                if (cpr.proc != null) {
8708                    if (false) {
8709                        if (cpr.name.flattenToShortString().equals(
8710                                "com.android.providers.calendar/.CalendarProvider2")) {
8711                            Slog.v(TAG, "****************** KILLING "
8712                                + cpr.name.flattenToShortString());
8713                            Process.killProcess(cpr.proc.pid);
8714                        }
8715                    }
8716                    boolean success = updateOomAdjLocked(cpr.proc);
8717                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8718                    // NOTE: there is still a race here where a signal could be
8719                    // pending on the process even though we managed to update its
8720                    // adj level.  Not sure what to do about this, but at least
8721                    // the race is now smaller.
8722                    if (!success) {
8723                        // Uh oh...  it looks like the provider's process
8724                        // has been killed on us.  We need to wait for a new
8725                        // process to be started, and make sure its death
8726                        // doesn't kill our process.
8727                        Slog.i(TAG,
8728                                "Existing provider " + cpr.name.flattenToShortString()
8729                                + " is crashing; detaching " + r);
8730                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8731                        appDiedLocked(cpr.proc);
8732                        if (!lastRef) {
8733                            // This wasn't the last ref our process had on
8734                            // the provider...  we have now been killed, bail.
8735                            return null;
8736                        }
8737                        providerRunning = false;
8738                        conn = null;
8739                    }
8740                }
8741
8742                Binder.restoreCallingIdentity(origId);
8743            }
8744
8745            boolean singleton;
8746            if (!providerRunning) {
8747                try {
8748                    cpi = AppGlobals.getPackageManager().
8749                        resolveContentProvider(name,
8750                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8751                } catch (RemoteException ex) {
8752                }
8753                if (cpi == null) {
8754                    return null;
8755                }
8756                // If the provider is a singleton AND
8757                // (it's a call within the same user || the provider is a
8758                // privileged app)
8759                // Then allow connecting to the singleton provider
8760                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8761                        cpi.name, cpi.flags)
8762                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8763                if (singleton) {
8764                    userId = UserHandle.USER_OWNER;
8765                }
8766                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8767
8768                String msg;
8769                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8770                        != null) {
8771                    throw new SecurityException(msg);
8772                }
8773
8774                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8775                        && !cpi.processName.equals("system")) {
8776                    // If this content provider does not run in the system
8777                    // process, and the system is not yet ready to run other
8778                    // processes, then fail fast instead of hanging.
8779                    throw new IllegalArgumentException(
8780                            "Attempt to launch content provider before system ready");
8781                }
8782
8783                // Make sure that the user who owns this provider is started.  If not,
8784                // we don't want to allow it to run.
8785                if (mStartedUsers.get(userId) == null) {
8786                    Slog.w(TAG, "Unable to launch app "
8787                            + cpi.applicationInfo.packageName + "/"
8788                            + cpi.applicationInfo.uid + " for provider "
8789                            + name + ": user " + userId + " is stopped");
8790                    return null;
8791                }
8792
8793                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8794                cpr = mProviderMap.getProviderByClass(comp, userId);
8795                final boolean firstClass = cpr == null;
8796                if (firstClass) {
8797                    try {
8798                        ApplicationInfo ai =
8799                            AppGlobals.getPackageManager().
8800                                getApplicationInfo(
8801                                        cpi.applicationInfo.packageName,
8802                                        STOCK_PM_FLAGS, userId);
8803                        if (ai == null) {
8804                            Slog.w(TAG, "No package info for content provider "
8805                                    + cpi.name);
8806                            return null;
8807                        }
8808                        ai = getAppInfoForUser(ai, userId);
8809                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8810                    } catch (RemoteException ex) {
8811                        // pm is in same process, this will never happen.
8812                    }
8813                }
8814
8815                if (r != null && cpr.canRunHere(r)) {
8816                    // If this is a multiprocess provider, then just return its
8817                    // info and allow the caller to instantiate it.  Only do
8818                    // this if the provider is the same user as the caller's
8819                    // process, or can run as root (so can be in any process).
8820                    return cpr.newHolder(null);
8821                }
8822
8823                if (DEBUG_PROVIDER) {
8824                    RuntimeException e = new RuntimeException("here");
8825                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8826                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8827                }
8828
8829                // This is single process, and our app is now connecting to it.
8830                // See if we are already in the process of launching this
8831                // provider.
8832                final int N = mLaunchingProviders.size();
8833                int i;
8834                for (i=0; i<N; i++) {
8835                    if (mLaunchingProviders.get(i) == cpr) {
8836                        break;
8837                    }
8838                }
8839
8840                // If the provider is not already being launched, then get it
8841                // started.
8842                if (i >= N) {
8843                    final long origId = Binder.clearCallingIdentity();
8844
8845                    try {
8846                        // Content provider is now in use, its package can't be stopped.
8847                        try {
8848                            AppGlobals.getPackageManager().setPackageStoppedState(
8849                                    cpr.appInfo.packageName, false, userId);
8850                        } catch (RemoteException e) {
8851                        } catch (IllegalArgumentException e) {
8852                            Slog.w(TAG, "Failed trying to unstop package "
8853                                    + cpr.appInfo.packageName + ": " + e);
8854                        }
8855
8856                        // Use existing process if already started
8857                        ProcessRecord proc = getProcessRecordLocked(
8858                                cpi.processName, cpr.appInfo.uid, false);
8859                        if (proc != null && proc.thread != null) {
8860                            if (DEBUG_PROVIDER) {
8861                                Slog.d(TAG, "Installing in existing process " + proc);
8862                            }
8863                            proc.pubProviders.put(cpi.name, cpr);
8864                            try {
8865                                proc.thread.scheduleInstallProvider(cpi);
8866                            } catch (RemoteException e) {
8867                            }
8868                        } else {
8869                            proc = startProcessLocked(cpi.processName,
8870                                    cpr.appInfo, false, 0, "content provider",
8871                                    new ComponentName(cpi.applicationInfo.packageName,
8872                                            cpi.name), false, false, false);
8873                            if (proc == null) {
8874                                Slog.w(TAG, "Unable to launch app "
8875                                        + cpi.applicationInfo.packageName + "/"
8876                                        + cpi.applicationInfo.uid + " for provider "
8877                                        + name + ": process is bad");
8878                                return null;
8879                            }
8880                        }
8881                        cpr.launchingApp = proc;
8882                        mLaunchingProviders.add(cpr);
8883                    } finally {
8884                        Binder.restoreCallingIdentity(origId);
8885                    }
8886                }
8887
8888                // Make sure the provider is published (the same provider class
8889                // may be published under multiple names).
8890                if (firstClass) {
8891                    mProviderMap.putProviderByClass(comp, cpr);
8892                }
8893
8894                mProviderMap.putProviderByName(name, cpr);
8895                conn = incProviderCountLocked(r, cpr, token, stable);
8896                if (conn != null) {
8897                    conn.waiting = true;
8898                }
8899            }
8900        }
8901
8902        // Wait for the provider to be published...
8903        synchronized (cpr) {
8904            while (cpr.provider == null) {
8905                if (cpr.launchingApp == null) {
8906                    Slog.w(TAG, "Unable to launch app "
8907                            + cpi.applicationInfo.packageName + "/"
8908                            + cpi.applicationInfo.uid + " for provider "
8909                            + name + ": launching app became null");
8910                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8911                            UserHandle.getUserId(cpi.applicationInfo.uid),
8912                            cpi.applicationInfo.packageName,
8913                            cpi.applicationInfo.uid, name);
8914                    return null;
8915                }
8916                try {
8917                    if (DEBUG_MU) {
8918                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8919                                + cpr.launchingApp);
8920                    }
8921                    if (conn != null) {
8922                        conn.waiting = true;
8923                    }
8924                    cpr.wait();
8925                } catch (InterruptedException ex) {
8926                } finally {
8927                    if (conn != null) {
8928                        conn.waiting = false;
8929                    }
8930                }
8931            }
8932        }
8933        return cpr != null ? cpr.newHolder(conn) : null;
8934    }
8935
8936    @Override
8937    public final ContentProviderHolder getContentProvider(
8938            IApplicationThread caller, String name, int userId, boolean stable) {
8939        enforceNotIsolatedCaller("getContentProvider");
8940        if (caller == null) {
8941            String msg = "null IApplicationThread when getting content provider "
8942                    + name;
8943            Slog.w(TAG, msg);
8944            throw new SecurityException(msg);
8945        }
8946        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8947        // with cross-user grant.
8948        return getContentProviderImpl(caller, name, null, stable, userId);
8949    }
8950
8951    public ContentProviderHolder getContentProviderExternal(
8952            String name, int userId, IBinder token) {
8953        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8954            "Do not have permission in call getContentProviderExternal()");
8955        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8956                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8957        return getContentProviderExternalUnchecked(name, token, userId);
8958    }
8959
8960    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8961            IBinder token, int userId) {
8962        return getContentProviderImpl(null, name, token, true, userId);
8963    }
8964
8965    /**
8966     * Drop a content provider from a ProcessRecord's bookkeeping
8967     */
8968    public void removeContentProvider(IBinder connection, boolean stable) {
8969        enforceNotIsolatedCaller("removeContentProvider");
8970        long ident = Binder.clearCallingIdentity();
8971        try {
8972            synchronized (this) {
8973                ContentProviderConnection conn;
8974                try {
8975                    conn = (ContentProviderConnection)connection;
8976                } catch (ClassCastException e) {
8977                    String msg ="removeContentProvider: " + connection
8978                            + " not a ContentProviderConnection";
8979                    Slog.w(TAG, msg);
8980                    throw new IllegalArgumentException(msg);
8981                }
8982                if (conn == null) {
8983                    throw new NullPointerException("connection is null");
8984                }
8985                if (decProviderCountLocked(conn, null, null, stable)) {
8986                    updateOomAdjLocked();
8987                }
8988            }
8989        } finally {
8990            Binder.restoreCallingIdentity(ident);
8991        }
8992    }
8993
8994    public void removeContentProviderExternal(String name, IBinder token) {
8995        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8996            "Do not have permission in call removeContentProviderExternal()");
8997        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8998    }
8999
9000    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9001        synchronized (this) {
9002            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9003            if(cpr == null) {
9004                //remove from mProvidersByClass
9005                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9006                return;
9007            }
9008
9009            //update content provider record entry info
9010            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9011            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9012            if (localCpr.hasExternalProcessHandles()) {
9013                if (localCpr.removeExternalProcessHandleLocked(token)) {
9014                    updateOomAdjLocked();
9015                } else {
9016                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9017                            + " with no external reference for token: "
9018                            + token + ".");
9019                }
9020            } else {
9021                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9022                        + " with no external references.");
9023            }
9024        }
9025    }
9026
9027    public final void publishContentProviders(IApplicationThread caller,
9028            List<ContentProviderHolder> providers) {
9029        if (providers == null) {
9030            return;
9031        }
9032
9033        enforceNotIsolatedCaller("publishContentProviders");
9034        synchronized (this) {
9035            final ProcessRecord r = getRecordForAppLocked(caller);
9036            if (DEBUG_MU)
9037                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9038            if (r == null) {
9039                throw new SecurityException(
9040                        "Unable to find app for caller " + caller
9041                      + " (pid=" + Binder.getCallingPid()
9042                      + ") when publishing content providers");
9043            }
9044
9045            final long origId = Binder.clearCallingIdentity();
9046
9047            final int N = providers.size();
9048            for (int i=0; i<N; i++) {
9049                ContentProviderHolder src = providers.get(i);
9050                if (src == null || src.info == null || src.provider == null) {
9051                    continue;
9052                }
9053                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9054                if (DEBUG_MU)
9055                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9056                if (dst != null) {
9057                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9058                    mProviderMap.putProviderByClass(comp, dst);
9059                    String names[] = dst.info.authority.split(";");
9060                    for (int j = 0; j < names.length; j++) {
9061                        mProviderMap.putProviderByName(names[j], dst);
9062                    }
9063
9064                    int NL = mLaunchingProviders.size();
9065                    int j;
9066                    for (j=0; j<NL; j++) {
9067                        if (mLaunchingProviders.get(j) == dst) {
9068                            mLaunchingProviders.remove(j);
9069                            j--;
9070                            NL--;
9071                        }
9072                    }
9073                    synchronized (dst) {
9074                        dst.provider = src.provider;
9075                        dst.proc = r;
9076                        dst.notifyAll();
9077                    }
9078                    updateOomAdjLocked(r);
9079                }
9080            }
9081
9082            Binder.restoreCallingIdentity(origId);
9083        }
9084    }
9085
9086    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9087        ContentProviderConnection conn;
9088        try {
9089            conn = (ContentProviderConnection)connection;
9090        } catch (ClassCastException e) {
9091            String msg ="refContentProvider: " + connection
9092                    + " not a ContentProviderConnection";
9093            Slog.w(TAG, msg);
9094            throw new IllegalArgumentException(msg);
9095        }
9096        if (conn == null) {
9097            throw new NullPointerException("connection is null");
9098        }
9099
9100        synchronized (this) {
9101            if (stable > 0) {
9102                conn.numStableIncs += stable;
9103            }
9104            stable = conn.stableCount + stable;
9105            if (stable < 0) {
9106                throw new IllegalStateException("stableCount < 0: " + stable);
9107            }
9108
9109            if (unstable > 0) {
9110                conn.numUnstableIncs += unstable;
9111            }
9112            unstable = conn.unstableCount + unstable;
9113            if (unstable < 0) {
9114                throw new IllegalStateException("unstableCount < 0: " + unstable);
9115            }
9116
9117            if ((stable+unstable) <= 0) {
9118                throw new IllegalStateException("ref counts can't go to zero here: stable="
9119                        + stable + " unstable=" + unstable);
9120            }
9121            conn.stableCount = stable;
9122            conn.unstableCount = unstable;
9123            return !conn.dead;
9124        }
9125    }
9126
9127    public void unstableProviderDied(IBinder connection) {
9128        ContentProviderConnection conn;
9129        try {
9130            conn = (ContentProviderConnection)connection;
9131        } catch (ClassCastException e) {
9132            String msg ="refContentProvider: " + connection
9133                    + " not a ContentProviderConnection";
9134            Slog.w(TAG, msg);
9135            throw new IllegalArgumentException(msg);
9136        }
9137        if (conn == null) {
9138            throw new NullPointerException("connection is null");
9139        }
9140
9141        // Safely retrieve the content provider associated with the connection.
9142        IContentProvider provider;
9143        synchronized (this) {
9144            provider = conn.provider.provider;
9145        }
9146
9147        if (provider == null) {
9148            // Um, yeah, we're way ahead of you.
9149            return;
9150        }
9151
9152        // Make sure the caller is being honest with us.
9153        if (provider.asBinder().pingBinder()) {
9154            // Er, no, still looks good to us.
9155            synchronized (this) {
9156                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9157                        + " says " + conn + " died, but we don't agree");
9158                return;
9159            }
9160        }
9161
9162        // Well look at that!  It's dead!
9163        synchronized (this) {
9164            if (conn.provider.provider != provider) {
9165                // But something changed...  good enough.
9166                return;
9167            }
9168
9169            ProcessRecord proc = conn.provider.proc;
9170            if (proc == null || proc.thread == null) {
9171                // Seems like the process is already cleaned up.
9172                return;
9173            }
9174
9175            // As far as we're concerned, this is just like receiving a
9176            // death notification...  just a bit prematurely.
9177            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9178                    + ") early provider death");
9179            final long ident = Binder.clearCallingIdentity();
9180            try {
9181                appDiedLocked(proc);
9182            } finally {
9183                Binder.restoreCallingIdentity(ident);
9184            }
9185        }
9186    }
9187
9188    @Override
9189    public void appNotRespondingViaProvider(IBinder connection) {
9190        enforceCallingPermission(
9191                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9192
9193        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9194        if (conn == null) {
9195            Slog.w(TAG, "ContentProviderConnection is null");
9196            return;
9197        }
9198
9199        final ProcessRecord host = conn.provider.proc;
9200        if (host == null) {
9201            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9202            return;
9203        }
9204
9205        final long token = Binder.clearCallingIdentity();
9206        try {
9207            appNotResponding(host, null, null, false, "ContentProvider not responding");
9208        } finally {
9209            Binder.restoreCallingIdentity(token);
9210        }
9211    }
9212
9213    public final void installSystemProviders() {
9214        List<ProviderInfo> providers;
9215        synchronized (this) {
9216            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9217            providers = generateApplicationProvidersLocked(app);
9218            if (providers != null) {
9219                for (int i=providers.size()-1; i>=0; i--) {
9220                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9221                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9222                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9223                                + ": not system .apk");
9224                        providers.remove(i);
9225                    }
9226                }
9227            }
9228        }
9229        if (providers != null) {
9230            mSystemThread.installSystemProviders(providers);
9231        }
9232
9233        mCoreSettingsObserver = new CoreSettingsObserver(this);
9234
9235        //mUsageStatsService.monitorPackages();
9236    }
9237
9238    /**
9239     * Allows apps to retrieve the MIME type of a URI.
9240     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9241     * users, then it does not need permission to access the ContentProvider.
9242     * Either, it needs cross-user uri grants.
9243     *
9244     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9245     *
9246     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9247     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9248     */
9249    public String getProviderMimeType(Uri uri, int userId) {
9250        enforceNotIsolatedCaller("getProviderMimeType");
9251        final String name = uri.getAuthority();
9252        int callingUid = Binder.getCallingUid();
9253        int callingPid = Binder.getCallingPid();
9254        long ident = 0;
9255        boolean clearedIdentity = false;
9256        userId = unsafeConvertIncomingUser(userId);
9257        if (UserHandle.getUserId(callingUid) != userId) {
9258            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9259                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9260                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9261                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9262                clearedIdentity = true;
9263                ident = Binder.clearCallingIdentity();
9264            }
9265        }
9266        ContentProviderHolder holder = null;
9267        try {
9268            holder = getContentProviderExternalUnchecked(name, null, userId);
9269            if (holder != null) {
9270                return holder.provider.getType(uri);
9271            }
9272        } catch (RemoteException e) {
9273            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9274            return null;
9275        } finally {
9276            // We need to clear the identity to call removeContentProviderExternalUnchecked
9277            if (!clearedIdentity) {
9278                ident = Binder.clearCallingIdentity();
9279            }
9280            try {
9281                if (holder != null) {
9282                    removeContentProviderExternalUnchecked(name, null, userId);
9283                }
9284            } finally {
9285                Binder.restoreCallingIdentity(ident);
9286            }
9287        }
9288
9289        return null;
9290    }
9291
9292    // =========================================================
9293    // GLOBAL MANAGEMENT
9294    // =========================================================
9295
9296    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9297            boolean isolated, int isolatedUid) {
9298        String proc = customProcess != null ? customProcess : info.processName;
9299        BatteryStatsImpl.Uid.Proc ps = null;
9300        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9301        int uid = info.uid;
9302        if (isolated) {
9303            if (isolatedUid == 0) {
9304                int userId = UserHandle.getUserId(uid);
9305                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9306                while (true) {
9307                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9308                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9309                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9310                    }
9311                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9312                    mNextIsolatedProcessUid++;
9313                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9314                        // No process for this uid, use it.
9315                        break;
9316                    }
9317                    stepsLeft--;
9318                    if (stepsLeft <= 0) {
9319                        return null;
9320                    }
9321                }
9322            } else {
9323                // Special case for startIsolatedProcess (internal only), where
9324                // the uid of the isolated process is specified by the caller.
9325                uid = isolatedUid;
9326            }
9327        }
9328        return new ProcessRecord(stats, info, proc, uid);
9329    }
9330
9331    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9332            String abiOverride) {
9333        ProcessRecord app;
9334        if (!isolated) {
9335            app = getProcessRecordLocked(info.processName, info.uid, true);
9336        } else {
9337            app = null;
9338        }
9339
9340        if (app == null) {
9341            app = newProcessRecordLocked(info, null, isolated, 0);
9342            mProcessNames.put(info.processName, app.uid, app);
9343            if (isolated) {
9344                mIsolatedProcesses.put(app.uid, app);
9345            }
9346            updateLruProcessLocked(app, false, null);
9347            updateOomAdjLocked();
9348        }
9349
9350        // This package really, really can not be stopped.
9351        try {
9352            AppGlobals.getPackageManager().setPackageStoppedState(
9353                    info.packageName, false, UserHandle.getUserId(app.uid));
9354        } catch (RemoteException e) {
9355        } catch (IllegalArgumentException e) {
9356            Slog.w(TAG, "Failed trying to unstop package "
9357                    + info.packageName + ": " + e);
9358        }
9359
9360        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9361                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9362            app.persistent = true;
9363            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9364        }
9365        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9366            mPersistentStartingProcesses.add(app);
9367            startProcessLocked(app, "added application", app.processName, abiOverride,
9368                    null /* entryPoint */, null /* entryPointArgs */);
9369        }
9370
9371        return app;
9372    }
9373
9374    public void unhandledBack() {
9375        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9376                "unhandledBack()");
9377
9378        synchronized(this) {
9379            final long origId = Binder.clearCallingIdentity();
9380            try {
9381                getFocusedStack().unhandledBackLocked();
9382            } finally {
9383                Binder.restoreCallingIdentity(origId);
9384            }
9385        }
9386    }
9387
9388    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9389        enforceNotIsolatedCaller("openContentUri");
9390        final int userId = UserHandle.getCallingUserId();
9391        String name = uri.getAuthority();
9392        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9393        ParcelFileDescriptor pfd = null;
9394        if (cph != null) {
9395            // We record the binder invoker's uid in thread-local storage before
9396            // going to the content provider to open the file.  Later, in the code
9397            // that handles all permissions checks, we look for this uid and use
9398            // that rather than the Activity Manager's own uid.  The effect is that
9399            // we do the check against the caller's permissions even though it looks
9400            // to the content provider like the Activity Manager itself is making
9401            // the request.
9402            sCallerIdentity.set(new Identity(
9403                    Binder.getCallingPid(), Binder.getCallingUid()));
9404            try {
9405                pfd = cph.provider.openFile(null, uri, "r", null);
9406            } catch (FileNotFoundException e) {
9407                // do nothing; pfd will be returned null
9408            } finally {
9409                // Ensure that whatever happens, we clean up the identity state
9410                sCallerIdentity.remove();
9411            }
9412
9413            // We've got the fd now, so we're done with the provider.
9414            removeContentProviderExternalUnchecked(name, null, userId);
9415        } else {
9416            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9417        }
9418        return pfd;
9419    }
9420
9421    // Actually is sleeping or shutting down or whatever else in the future
9422    // is an inactive state.
9423    public boolean isSleepingOrShuttingDown() {
9424        return mSleeping || mShuttingDown;
9425    }
9426
9427    public boolean isSleeping() {
9428        return mSleeping;
9429    }
9430
9431    void goingToSleep() {
9432        synchronized(this) {
9433            mWentToSleep = true;
9434            updateEventDispatchingLocked();
9435            goToSleepIfNeededLocked();
9436        }
9437    }
9438
9439    void finishRunningVoiceLocked() {
9440        if (mRunningVoice) {
9441            mRunningVoice = false;
9442            goToSleepIfNeededLocked();
9443        }
9444    }
9445
9446    void goToSleepIfNeededLocked() {
9447        if (mWentToSleep && !mRunningVoice) {
9448            if (!mSleeping) {
9449                mSleeping = true;
9450                mStackSupervisor.goingToSleepLocked();
9451
9452                // Initialize the wake times of all processes.
9453                checkExcessivePowerUsageLocked(false);
9454                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9455                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9456                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9457            }
9458        }
9459    }
9460
9461    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9462        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9463            // Never persist the home stack.
9464            return;
9465        }
9466        mTaskPersister.wakeup(task, flush);
9467    }
9468
9469    @Override
9470    public boolean shutdown(int timeout) {
9471        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9472                != PackageManager.PERMISSION_GRANTED) {
9473            throw new SecurityException("Requires permission "
9474                    + android.Manifest.permission.SHUTDOWN);
9475        }
9476
9477        boolean timedout = false;
9478
9479        synchronized(this) {
9480            mShuttingDown = true;
9481            updateEventDispatchingLocked();
9482            timedout = mStackSupervisor.shutdownLocked(timeout);
9483        }
9484
9485        mAppOpsService.shutdown();
9486        if (mUsageStatsService != null) {
9487            mUsageStatsService.prepareShutdown();
9488        }
9489        mBatteryStatsService.shutdown();
9490        synchronized (this) {
9491            mProcessStats.shutdownLocked();
9492        }
9493        notifyTaskPersisterLocked(null, true);
9494
9495        return timedout;
9496    }
9497
9498    public final void activitySlept(IBinder token) {
9499        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9500
9501        final long origId = Binder.clearCallingIdentity();
9502
9503        synchronized (this) {
9504            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9505            if (r != null) {
9506                mStackSupervisor.activitySleptLocked(r);
9507            }
9508        }
9509
9510        Binder.restoreCallingIdentity(origId);
9511    }
9512
9513    void logLockScreen(String msg) {
9514        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9515                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9516                mWentToSleep + " mSleeping=" + mSleeping);
9517    }
9518
9519    private void comeOutOfSleepIfNeededLocked() {
9520        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9521            if (mSleeping) {
9522                mSleeping = false;
9523                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9524            }
9525        }
9526    }
9527
9528    void wakingUp() {
9529        synchronized(this) {
9530            mWentToSleep = false;
9531            updateEventDispatchingLocked();
9532            comeOutOfSleepIfNeededLocked();
9533        }
9534    }
9535
9536    void startRunningVoiceLocked() {
9537        if (!mRunningVoice) {
9538            mRunningVoice = true;
9539            comeOutOfSleepIfNeededLocked();
9540        }
9541    }
9542
9543    private void updateEventDispatchingLocked() {
9544        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9545    }
9546
9547    public void setLockScreenShown(boolean shown) {
9548        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9549                != PackageManager.PERMISSION_GRANTED) {
9550            throw new SecurityException("Requires permission "
9551                    + android.Manifest.permission.DEVICE_POWER);
9552        }
9553
9554        synchronized(this) {
9555            long ident = Binder.clearCallingIdentity();
9556            try {
9557                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9558                mLockScreenShown = shown;
9559                comeOutOfSleepIfNeededLocked();
9560            } finally {
9561                Binder.restoreCallingIdentity(ident);
9562            }
9563        }
9564    }
9565
9566    @Override
9567    public void stopAppSwitches() {
9568        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9569                != PackageManager.PERMISSION_GRANTED) {
9570            throw new SecurityException("Requires permission "
9571                    + android.Manifest.permission.STOP_APP_SWITCHES);
9572        }
9573
9574        synchronized(this) {
9575            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9576                    + APP_SWITCH_DELAY_TIME;
9577            mDidAppSwitch = false;
9578            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9579            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9580            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9581        }
9582    }
9583
9584    public void resumeAppSwitches() {
9585        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9586                != PackageManager.PERMISSION_GRANTED) {
9587            throw new SecurityException("Requires permission "
9588                    + android.Manifest.permission.STOP_APP_SWITCHES);
9589        }
9590
9591        synchronized(this) {
9592            // Note that we don't execute any pending app switches... we will
9593            // let those wait until either the timeout, or the next start
9594            // activity request.
9595            mAppSwitchesAllowedTime = 0;
9596        }
9597    }
9598
9599    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9600            String name) {
9601        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9602            return true;
9603        }
9604
9605        final int perm = checkComponentPermission(
9606                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9607                callingUid, -1, true);
9608        if (perm == PackageManager.PERMISSION_GRANTED) {
9609            return true;
9610        }
9611
9612        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9613        return false;
9614    }
9615
9616    public void setDebugApp(String packageName, boolean waitForDebugger,
9617            boolean persistent) {
9618        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9619                "setDebugApp()");
9620
9621        long ident = Binder.clearCallingIdentity();
9622        try {
9623            // Note that this is not really thread safe if there are multiple
9624            // callers into it at the same time, but that's not a situation we
9625            // care about.
9626            if (persistent) {
9627                final ContentResolver resolver = mContext.getContentResolver();
9628                Settings.Global.putString(
9629                    resolver, Settings.Global.DEBUG_APP,
9630                    packageName);
9631                Settings.Global.putInt(
9632                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9633                    waitForDebugger ? 1 : 0);
9634            }
9635
9636            synchronized (this) {
9637                if (!persistent) {
9638                    mOrigDebugApp = mDebugApp;
9639                    mOrigWaitForDebugger = mWaitForDebugger;
9640                }
9641                mDebugApp = packageName;
9642                mWaitForDebugger = waitForDebugger;
9643                mDebugTransient = !persistent;
9644                if (packageName != null) {
9645                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9646                            false, UserHandle.USER_ALL, "set debug app");
9647                }
9648            }
9649        } finally {
9650            Binder.restoreCallingIdentity(ident);
9651        }
9652    }
9653
9654    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9655        synchronized (this) {
9656            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9657            if (!isDebuggable) {
9658                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9659                    throw new SecurityException("Process not debuggable: " + app.packageName);
9660                }
9661            }
9662
9663            mOpenGlTraceApp = processName;
9664        }
9665    }
9666
9667    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9668            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9669        synchronized (this) {
9670            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9671            if (!isDebuggable) {
9672                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9673                    throw new SecurityException("Process not debuggable: " + app.packageName);
9674                }
9675            }
9676            mProfileApp = processName;
9677            mProfileFile = profileFile;
9678            if (mProfileFd != null) {
9679                try {
9680                    mProfileFd.close();
9681                } catch (IOException e) {
9682                }
9683                mProfileFd = null;
9684            }
9685            mProfileFd = profileFd;
9686            mProfileType = 0;
9687            mAutoStopProfiler = autoStopProfiler;
9688        }
9689    }
9690
9691    @Override
9692    public void setAlwaysFinish(boolean enabled) {
9693        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9694                "setAlwaysFinish()");
9695
9696        Settings.Global.putInt(
9697                mContext.getContentResolver(),
9698                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9699
9700        synchronized (this) {
9701            mAlwaysFinishActivities = enabled;
9702        }
9703    }
9704
9705    @Override
9706    public void setActivityController(IActivityController controller) {
9707        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9708                "setActivityController()");
9709        synchronized (this) {
9710            mController = controller;
9711            Watchdog.getInstance().setActivityController(controller);
9712        }
9713    }
9714
9715    @Override
9716    public void setUserIsMonkey(boolean userIsMonkey) {
9717        synchronized (this) {
9718            synchronized (mPidsSelfLocked) {
9719                final int callingPid = Binder.getCallingPid();
9720                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9721                if (precessRecord == null) {
9722                    throw new SecurityException("Unknown process: " + callingPid);
9723                }
9724                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9725                    throw new SecurityException("Only an instrumentation process "
9726                            + "with a UiAutomation can call setUserIsMonkey");
9727                }
9728            }
9729            mUserIsMonkey = userIsMonkey;
9730        }
9731    }
9732
9733    @Override
9734    public boolean isUserAMonkey() {
9735        synchronized (this) {
9736            // If there is a controller also implies the user is a monkey.
9737            return (mUserIsMonkey || mController != null);
9738        }
9739    }
9740
9741    public void requestBugReport() {
9742        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9743        SystemProperties.set("ctl.start", "bugreport");
9744    }
9745
9746    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9747        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9748    }
9749
9750    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9751        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9752            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9753        }
9754        return KEY_DISPATCHING_TIMEOUT;
9755    }
9756
9757    @Override
9758    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9759        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9760                != PackageManager.PERMISSION_GRANTED) {
9761            throw new SecurityException("Requires permission "
9762                    + android.Manifest.permission.FILTER_EVENTS);
9763        }
9764        ProcessRecord proc;
9765        long timeout;
9766        synchronized (this) {
9767            synchronized (mPidsSelfLocked) {
9768                proc = mPidsSelfLocked.get(pid);
9769            }
9770            timeout = getInputDispatchingTimeoutLocked(proc);
9771        }
9772
9773        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9774            return -1;
9775        }
9776
9777        return timeout;
9778    }
9779
9780    /**
9781     * Handle input dispatching timeouts.
9782     * Returns whether input dispatching should be aborted or not.
9783     */
9784    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9785            final ActivityRecord activity, final ActivityRecord parent,
9786            final boolean aboveSystem, String reason) {
9787        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9788                != PackageManager.PERMISSION_GRANTED) {
9789            throw new SecurityException("Requires permission "
9790                    + android.Manifest.permission.FILTER_EVENTS);
9791        }
9792
9793        final String annotation;
9794        if (reason == null) {
9795            annotation = "Input dispatching timed out";
9796        } else {
9797            annotation = "Input dispatching timed out (" + reason + ")";
9798        }
9799
9800        if (proc != null) {
9801            synchronized (this) {
9802                if (proc.debugging) {
9803                    return false;
9804                }
9805
9806                if (mDidDexOpt) {
9807                    // Give more time since we were dexopting.
9808                    mDidDexOpt = false;
9809                    return false;
9810                }
9811
9812                if (proc.instrumentationClass != null) {
9813                    Bundle info = new Bundle();
9814                    info.putString("shortMsg", "keyDispatchingTimedOut");
9815                    info.putString("longMsg", annotation);
9816                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9817                    return true;
9818                }
9819            }
9820            mHandler.post(new Runnable() {
9821                @Override
9822                public void run() {
9823                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9824                }
9825            });
9826        }
9827
9828        return true;
9829    }
9830
9831    public Bundle getAssistContextExtras(int requestType) {
9832        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9833                "getAssistContextExtras()");
9834        PendingAssistExtras pae;
9835        Bundle extras = new Bundle();
9836        synchronized (this) {
9837            ActivityRecord activity = getFocusedStack().mResumedActivity;
9838            if (activity == null) {
9839                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9840                return null;
9841            }
9842            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9843            if (activity.app == null || activity.app.thread == null) {
9844                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9845                return extras;
9846            }
9847            if (activity.app.pid == Binder.getCallingPid()) {
9848                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9849                return extras;
9850            }
9851            pae = new PendingAssistExtras(activity);
9852            try {
9853                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9854                        requestType);
9855                mPendingAssistExtras.add(pae);
9856                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9857            } catch (RemoteException e) {
9858                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9859                return extras;
9860            }
9861        }
9862        synchronized (pae) {
9863            while (!pae.haveResult) {
9864                try {
9865                    pae.wait();
9866                } catch (InterruptedException e) {
9867                }
9868            }
9869            if (pae.result != null) {
9870                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9871            }
9872        }
9873        synchronized (this) {
9874            mPendingAssistExtras.remove(pae);
9875            mHandler.removeCallbacks(pae);
9876        }
9877        return extras;
9878    }
9879
9880    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9881        PendingAssistExtras pae = (PendingAssistExtras)token;
9882        synchronized (pae) {
9883            pae.result = extras;
9884            pae.haveResult = true;
9885            pae.notifyAll();
9886        }
9887    }
9888
9889    public void registerProcessObserver(IProcessObserver observer) {
9890        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9891                "registerProcessObserver()");
9892        synchronized (this) {
9893            mProcessObservers.register(observer);
9894        }
9895    }
9896
9897    @Override
9898    public void unregisterProcessObserver(IProcessObserver observer) {
9899        synchronized (this) {
9900            mProcessObservers.unregister(observer);
9901        }
9902    }
9903
9904    @Override
9905    public boolean convertFromTranslucent(IBinder token) {
9906        final long origId = Binder.clearCallingIdentity();
9907        try {
9908            synchronized (this) {
9909                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9910                if (r == null) {
9911                    return false;
9912                }
9913                if (r.changeWindowTranslucency(true)) {
9914                    mWindowManager.setAppFullscreen(token, true);
9915                    r.task.stack.releaseBackgroundResources();
9916                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9917                    return true;
9918                }
9919                return false;
9920            }
9921        } finally {
9922            Binder.restoreCallingIdentity(origId);
9923        }
9924    }
9925
9926    @Override
9927    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9928        final long origId = Binder.clearCallingIdentity();
9929        try {
9930            synchronized (this) {
9931                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9932                if (r == null) {
9933                    return false;
9934                }
9935                int index = r.task.mActivities.lastIndexOf(r);
9936                if (index > 0) {
9937                    ActivityRecord under = r.task.mActivities.get(index - 1);
9938                    under.returningOptions = options;
9939                }
9940                if (r.changeWindowTranslucency(false)) {
9941                    r.task.stack.convertToTranslucent(r);
9942                    mWindowManager.setAppFullscreen(token, false);
9943                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9944                    return true;
9945                } else {
9946                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9947                    return false;
9948                }
9949            }
9950        } finally {
9951            Binder.restoreCallingIdentity(origId);
9952        }
9953    }
9954
9955    @Override
9956    public boolean requestVisibleBehind(IBinder token, boolean visible) {
9957        final long origId = Binder.clearCallingIdentity();
9958        try {
9959            synchronized (this) {
9960                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9961                if (r != null) {
9962                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
9963                }
9964            }
9965            return false;
9966        } finally {
9967            Binder.restoreCallingIdentity(origId);
9968        }
9969    }
9970
9971    @Override
9972    public boolean isBackgroundVisibleBehind(IBinder token) {
9973        final long origId = Binder.clearCallingIdentity();
9974        try {
9975            synchronized (this) {
9976                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9977                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
9978                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
9979                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
9980                return visible;
9981            }
9982        } finally {
9983            Binder.restoreCallingIdentity(origId);
9984        }
9985    }
9986
9987    @Override
9988    public ActivityOptions getActivityOptions(IBinder token) {
9989        final long origId = Binder.clearCallingIdentity();
9990        try {
9991            synchronized (this) {
9992                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9993                if (r != null) {
9994                    final ActivityOptions activityOptions = r.pendingOptions;
9995                    r.pendingOptions = null;
9996                    return activityOptions;
9997                }
9998                return null;
9999            }
10000        } finally {
10001            Binder.restoreCallingIdentity(origId);
10002        }
10003    }
10004
10005    @Override
10006    public void setImmersive(IBinder token, boolean immersive) {
10007        synchronized(this) {
10008            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10009            if (r == null) {
10010                throw new IllegalArgumentException();
10011            }
10012            r.immersive = immersive;
10013
10014            // update associated state if we're frontmost
10015            if (r == mFocusedActivity) {
10016                if (DEBUG_IMMERSIVE) {
10017                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10018                }
10019                applyUpdateLockStateLocked(r);
10020            }
10021        }
10022    }
10023
10024    @Override
10025    public boolean isImmersive(IBinder token) {
10026        synchronized (this) {
10027            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10028            if (r == null) {
10029                throw new IllegalArgumentException();
10030            }
10031            return r.immersive;
10032        }
10033    }
10034
10035    public boolean isTopActivityImmersive() {
10036        enforceNotIsolatedCaller("startActivity");
10037        synchronized (this) {
10038            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10039            return (r != null) ? r.immersive : false;
10040        }
10041    }
10042
10043    @Override
10044    public boolean isTopOfTask(IBinder token) {
10045        synchronized (this) {
10046            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10047            if (r == null) {
10048                throw new IllegalArgumentException();
10049            }
10050            return r.task.getTopActivity() == r;
10051        }
10052    }
10053
10054    public final void enterSafeMode() {
10055        synchronized(this) {
10056            // It only makes sense to do this before the system is ready
10057            // and started launching other packages.
10058            if (!mSystemReady) {
10059                try {
10060                    AppGlobals.getPackageManager().enterSafeMode();
10061                } catch (RemoteException e) {
10062                }
10063            }
10064
10065            mSafeMode = true;
10066        }
10067    }
10068
10069    public final void showSafeModeOverlay() {
10070        View v = LayoutInflater.from(mContext).inflate(
10071                com.android.internal.R.layout.safe_mode, null);
10072        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10073        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10074        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10075        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10076        lp.gravity = Gravity.BOTTOM | Gravity.START;
10077        lp.format = v.getBackground().getOpacity();
10078        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10079                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10080        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10081        ((WindowManager)mContext.getSystemService(
10082                Context.WINDOW_SERVICE)).addView(v, lp);
10083    }
10084
10085    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10086        if (!(sender instanceof PendingIntentRecord)) {
10087            return;
10088        }
10089        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10090        synchronized (stats) {
10091            if (mBatteryStatsService.isOnBattery()) {
10092                mBatteryStatsService.enforceCallingPermission();
10093                PendingIntentRecord rec = (PendingIntentRecord)sender;
10094                int MY_UID = Binder.getCallingUid();
10095                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10096                BatteryStatsImpl.Uid.Pkg pkg =
10097                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10098                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10099                pkg.incWakeupsLocked();
10100            }
10101        }
10102    }
10103
10104    public boolean killPids(int[] pids, String pReason, boolean secure) {
10105        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10106            throw new SecurityException("killPids only available to the system");
10107        }
10108        String reason = (pReason == null) ? "Unknown" : pReason;
10109        // XXX Note: don't acquire main activity lock here, because the window
10110        // manager calls in with its locks held.
10111
10112        boolean killed = false;
10113        synchronized (mPidsSelfLocked) {
10114            int[] types = new int[pids.length];
10115            int worstType = 0;
10116            for (int i=0; i<pids.length; i++) {
10117                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10118                if (proc != null) {
10119                    int type = proc.setAdj;
10120                    types[i] = type;
10121                    if (type > worstType) {
10122                        worstType = type;
10123                    }
10124                }
10125            }
10126
10127            // If the worst oom_adj is somewhere in the cached proc LRU range,
10128            // then constrain it so we will kill all cached procs.
10129            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10130                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10131                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10132            }
10133
10134            // If this is not a secure call, don't let it kill processes that
10135            // are important.
10136            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10137                worstType = ProcessList.SERVICE_ADJ;
10138            }
10139
10140            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10141            for (int i=0; i<pids.length; i++) {
10142                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10143                if (proc == null) {
10144                    continue;
10145                }
10146                int adj = proc.setAdj;
10147                if (adj >= worstType && !proc.killedByAm) {
10148                    killUnneededProcessLocked(proc, reason);
10149                    killed = true;
10150                }
10151            }
10152        }
10153        return killed;
10154    }
10155
10156    @Override
10157    public void killUid(int uid, String reason) {
10158        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10159            throw new SecurityException("killUid only available to the system");
10160        }
10161        synchronized (this) {
10162            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10163                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10164                    reason != null ? reason : "kill uid");
10165        }
10166    }
10167
10168    @Override
10169    public boolean killProcessesBelowForeground(String reason) {
10170        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10171            throw new SecurityException("killProcessesBelowForeground() only available to system");
10172        }
10173
10174        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10175    }
10176
10177    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10178        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10179            throw new SecurityException("killProcessesBelowAdj() only available to system");
10180        }
10181
10182        boolean killed = false;
10183        synchronized (mPidsSelfLocked) {
10184            final int size = mPidsSelfLocked.size();
10185            for (int i = 0; i < size; i++) {
10186                final int pid = mPidsSelfLocked.keyAt(i);
10187                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10188                if (proc == null) continue;
10189
10190                final int adj = proc.setAdj;
10191                if (adj > belowAdj && !proc.killedByAm) {
10192                    killUnneededProcessLocked(proc, reason);
10193                    killed = true;
10194                }
10195            }
10196        }
10197        return killed;
10198    }
10199
10200    @Override
10201    public void hang(final IBinder who, boolean allowRestart) {
10202        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10203                != PackageManager.PERMISSION_GRANTED) {
10204            throw new SecurityException("Requires permission "
10205                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10206        }
10207
10208        final IBinder.DeathRecipient death = new DeathRecipient() {
10209            @Override
10210            public void binderDied() {
10211                synchronized (this) {
10212                    notifyAll();
10213                }
10214            }
10215        };
10216
10217        try {
10218            who.linkToDeath(death, 0);
10219        } catch (RemoteException e) {
10220            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10221            return;
10222        }
10223
10224        synchronized (this) {
10225            Watchdog.getInstance().setAllowRestart(allowRestart);
10226            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10227            synchronized (death) {
10228                while (who.isBinderAlive()) {
10229                    try {
10230                        death.wait();
10231                    } catch (InterruptedException e) {
10232                    }
10233                }
10234            }
10235            Watchdog.getInstance().setAllowRestart(true);
10236        }
10237    }
10238
10239    @Override
10240    public void restart() {
10241        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10242                != PackageManager.PERMISSION_GRANTED) {
10243            throw new SecurityException("Requires permission "
10244                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10245        }
10246
10247        Log.i(TAG, "Sending shutdown broadcast...");
10248
10249        BroadcastReceiver br = new BroadcastReceiver() {
10250            @Override public void onReceive(Context context, Intent intent) {
10251                // Now the broadcast is done, finish up the low-level shutdown.
10252                Log.i(TAG, "Shutting down activity manager...");
10253                shutdown(10000);
10254                Log.i(TAG, "Shutdown complete, restarting!");
10255                Process.killProcess(Process.myPid());
10256                System.exit(10);
10257            }
10258        };
10259
10260        // First send the high-level shut down broadcast.
10261        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10262        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10263        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10264        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10265        mContext.sendOrderedBroadcastAsUser(intent,
10266                UserHandle.ALL, null, br, mHandler, 0, null, null);
10267        */
10268        br.onReceive(mContext, intent);
10269    }
10270
10271    private long getLowRamTimeSinceIdle(long now) {
10272        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10273    }
10274
10275    @Override
10276    public void performIdleMaintenance() {
10277        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10278                != PackageManager.PERMISSION_GRANTED) {
10279            throw new SecurityException("Requires permission "
10280                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10281        }
10282
10283        synchronized (this) {
10284            final long now = SystemClock.uptimeMillis();
10285            final long timeSinceLastIdle = now - mLastIdleTime;
10286            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10287            mLastIdleTime = now;
10288            mLowRamTimeSinceLastIdle = 0;
10289            if (mLowRamStartTime != 0) {
10290                mLowRamStartTime = now;
10291            }
10292
10293            StringBuilder sb = new StringBuilder(128);
10294            sb.append("Idle maintenance over ");
10295            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10296            sb.append(" low RAM for ");
10297            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10298            Slog.i(TAG, sb.toString());
10299
10300            // If at least 1/3 of our time since the last idle period has been spent
10301            // with RAM low, then we want to kill processes.
10302            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10303
10304            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10305                ProcessRecord proc = mLruProcesses.get(i);
10306                if (proc.notCachedSinceIdle) {
10307                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10308                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10309                        if (doKilling && proc.initialIdlePss != 0
10310                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10311                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10312                                    + " from " + proc.initialIdlePss + ")");
10313                        }
10314                    }
10315                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10316                    proc.notCachedSinceIdle = true;
10317                    proc.initialIdlePss = 0;
10318                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10319                            isSleeping(), now);
10320                }
10321            }
10322
10323            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10324            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10325        }
10326    }
10327
10328    private void retrieveSettings() {
10329        final ContentResolver resolver = mContext.getContentResolver();
10330        String debugApp = Settings.Global.getString(
10331            resolver, Settings.Global.DEBUG_APP);
10332        boolean waitForDebugger = Settings.Global.getInt(
10333            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10334        boolean alwaysFinishActivities = Settings.Global.getInt(
10335            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10336        boolean forceRtl = Settings.Global.getInt(
10337                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10338        // Transfer any global setting for forcing RTL layout, into a System Property
10339        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10340
10341        Configuration configuration = new Configuration();
10342        Settings.System.getConfiguration(resolver, configuration);
10343        if (forceRtl) {
10344            // This will take care of setting the correct layout direction flags
10345            configuration.setLayoutDirection(configuration.locale);
10346        }
10347
10348        synchronized (this) {
10349            mDebugApp = mOrigDebugApp = debugApp;
10350            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10351            mAlwaysFinishActivities = alwaysFinishActivities;
10352            // This happens before any activities are started, so we can
10353            // change mConfiguration in-place.
10354            updateConfigurationLocked(configuration, null, false, true);
10355            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10356        }
10357    }
10358
10359    public boolean testIsSystemReady() {
10360        // no need to synchronize(this) just to read & return the value
10361        return mSystemReady;
10362    }
10363
10364    private static File getCalledPreBootReceiversFile() {
10365        File dataDir = Environment.getDataDirectory();
10366        File systemDir = new File(dataDir, "system");
10367        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10368        return fname;
10369    }
10370
10371    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10372        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10373        File file = getCalledPreBootReceiversFile();
10374        FileInputStream fis = null;
10375        try {
10376            fis = new FileInputStream(file);
10377            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10378            int fvers = dis.readInt();
10379            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10380                String vers = dis.readUTF();
10381                String codename = dis.readUTF();
10382                String build = dis.readUTF();
10383                if (android.os.Build.VERSION.RELEASE.equals(vers)
10384                        && android.os.Build.VERSION.CODENAME.equals(codename)
10385                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10386                    int num = dis.readInt();
10387                    while (num > 0) {
10388                        num--;
10389                        String pkg = dis.readUTF();
10390                        String cls = dis.readUTF();
10391                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10392                    }
10393                }
10394            }
10395        } catch (FileNotFoundException e) {
10396        } catch (IOException e) {
10397            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10398        } finally {
10399            if (fis != null) {
10400                try {
10401                    fis.close();
10402                } catch (IOException e) {
10403                }
10404            }
10405        }
10406        return lastDoneReceivers;
10407    }
10408
10409    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10410        File file = getCalledPreBootReceiversFile();
10411        FileOutputStream fos = null;
10412        DataOutputStream dos = null;
10413        try {
10414            fos = new FileOutputStream(file);
10415            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10416            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10417            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10418            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10419            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10420            dos.writeInt(list.size());
10421            for (int i=0; i<list.size(); i++) {
10422                dos.writeUTF(list.get(i).getPackageName());
10423                dos.writeUTF(list.get(i).getClassName());
10424            }
10425        } catch (IOException e) {
10426            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10427            file.delete();
10428        } finally {
10429            FileUtils.sync(fos);
10430            if (dos != null) {
10431                try {
10432                    dos.close();
10433                } catch (IOException e) {
10434                    // TODO Auto-generated catch block
10435                    e.printStackTrace();
10436                }
10437            }
10438        }
10439    }
10440
10441    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10442            ArrayList<ComponentName> doneReceivers, int userId) {
10443        boolean waitingUpdate = false;
10444        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10445        List<ResolveInfo> ris = null;
10446        try {
10447            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10448                    intent, null, 0, userId);
10449        } catch (RemoteException e) {
10450        }
10451        if (ris != null) {
10452            for (int i=ris.size()-1; i>=0; i--) {
10453                if ((ris.get(i).activityInfo.applicationInfo.flags
10454                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10455                    ris.remove(i);
10456                }
10457            }
10458            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10459
10460            // For User 0, load the version number. When delivering to a new user, deliver
10461            // to all receivers.
10462            if (userId == UserHandle.USER_OWNER) {
10463                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10464                for (int i=0; i<ris.size(); i++) {
10465                    ActivityInfo ai = ris.get(i).activityInfo;
10466                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10467                    if (lastDoneReceivers.contains(comp)) {
10468                        // We already did the pre boot receiver for this app with the current
10469                        // platform version, so don't do it again...
10470                        ris.remove(i);
10471                        i--;
10472                        // ...however, do keep it as one that has been done, so we don't
10473                        // forget about it when rewriting the file of last done receivers.
10474                        doneReceivers.add(comp);
10475                    }
10476                }
10477            }
10478
10479            // If primary user, send broadcast to all available users, else just to userId
10480            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10481                    : new int[] { userId };
10482            for (int i = 0; i < ris.size(); i++) {
10483                ActivityInfo ai = ris.get(i).activityInfo;
10484                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10485                doneReceivers.add(comp);
10486                intent.setComponent(comp);
10487                for (int j=0; j<users.length; j++) {
10488                    IIntentReceiver finisher = null;
10489                    // On last receiver and user, set up a completion callback
10490                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10491                        finisher = new IIntentReceiver.Stub() {
10492                            public void performReceive(Intent intent, int resultCode,
10493                                    String data, Bundle extras, boolean ordered,
10494                                    boolean sticky, int sendingUser) {
10495                                // The raw IIntentReceiver interface is called
10496                                // with the AM lock held, so redispatch to
10497                                // execute our code without the lock.
10498                                mHandler.post(onFinishCallback);
10499                            }
10500                        };
10501                    }
10502                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10503                            + " for user " + users[j]);
10504                    broadcastIntentLocked(null, null, intent, null, finisher,
10505                            0, null, null, null, AppOpsManager.OP_NONE,
10506                            true, false, MY_PID, Process.SYSTEM_UID,
10507                            users[j]);
10508                    if (finisher != null) {
10509                        waitingUpdate = true;
10510                    }
10511                }
10512            }
10513        }
10514
10515        return waitingUpdate;
10516    }
10517
10518    public void systemReady(final Runnable goingCallback) {
10519        synchronized(this) {
10520            if (mSystemReady) {
10521                // If we're done calling all the receivers, run the next "boot phase" passed in
10522                // by the SystemServer
10523                if (goingCallback != null) {
10524                    goingCallback.run();
10525                }
10526                return;
10527            }
10528
10529            // Make sure we have the current profile info, since it is needed for
10530            // security checks.
10531            updateCurrentProfileIdsLocked();
10532
10533            if (mRecentTasks == null) {
10534                mRecentTasks = mTaskPersister.restoreTasksLocked();
10535                if (!mRecentTasks.isEmpty()) {
10536                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10537                }
10538                mTaskPersister.startPersisting();
10539            }
10540
10541            // Check to see if there are any update receivers to run.
10542            if (!mDidUpdate) {
10543                if (mWaitingUpdate) {
10544                    return;
10545                }
10546                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10547                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10548                    public void run() {
10549                        synchronized (ActivityManagerService.this) {
10550                            mDidUpdate = true;
10551                        }
10552                        writeLastDonePreBootReceivers(doneReceivers);
10553                        showBootMessage(mContext.getText(
10554                                R.string.android_upgrading_complete),
10555                                false);
10556                        systemReady(goingCallback);
10557                    }
10558                }, doneReceivers, UserHandle.USER_OWNER);
10559
10560                if (mWaitingUpdate) {
10561                    return;
10562                }
10563                mDidUpdate = true;
10564            }
10565
10566            mAppOpsService.systemReady();
10567            mSystemReady = true;
10568        }
10569
10570        ArrayList<ProcessRecord> procsToKill = null;
10571        synchronized(mPidsSelfLocked) {
10572            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10573                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10574                if (!isAllowedWhileBooting(proc.info)){
10575                    if (procsToKill == null) {
10576                        procsToKill = new ArrayList<ProcessRecord>();
10577                    }
10578                    procsToKill.add(proc);
10579                }
10580            }
10581        }
10582
10583        synchronized(this) {
10584            if (procsToKill != null) {
10585                for (int i=procsToKill.size()-1; i>=0; i--) {
10586                    ProcessRecord proc = procsToKill.get(i);
10587                    Slog.i(TAG, "Removing system update proc: " + proc);
10588                    removeProcessLocked(proc, true, false, "system update done");
10589                }
10590            }
10591
10592            // Now that we have cleaned up any update processes, we
10593            // are ready to start launching real processes and know that
10594            // we won't trample on them any more.
10595            mProcessesReady = true;
10596        }
10597
10598        Slog.i(TAG, "System now ready");
10599        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10600            SystemClock.uptimeMillis());
10601
10602        synchronized(this) {
10603            // Make sure we have no pre-ready processes sitting around.
10604
10605            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10606                ResolveInfo ri = mContext.getPackageManager()
10607                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10608                                STOCK_PM_FLAGS);
10609                CharSequence errorMsg = null;
10610                if (ri != null) {
10611                    ActivityInfo ai = ri.activityInfo;
10612                    ApplicationInfo app = ai.applicationInfo;
10613                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10614                        mTopAction = Intent.ACTION_FACTORY_TEST;
10615                        mTopData = null;
10616                        mTopComponent = new ComponentName(app.packageName,
10617                                ai.name);
10618                    } else {
10619                        errorMsg = mContext.getResources().getText(
10620                                com.android.internal.R.string.factorytest_not_system);
10621                    }
10622                } else {
10623                    errorMsg = mContext.getResources().getText(
10624                            com.android.internal.R.string.factorytest_no_action);
10625                }
10626                if (errorMsg != null) {
10627                    mTopAction = null;
10628                    mTopData = null;
10629                    mTopComponent = null;
10630                    Message msg = Message.obtain();
10631                    msg.what = SHOW_FACTORY_ERROR_MSG;
10632                    msg.getData().putCharSequence("msg", errorMsg);
10633                    mHandler.sendMessage(msg);
10634                }
10635            }
10636        }
10637
10638        retrieveSettings();
10639
10640        synchronized (this) {
10641            readGrantedUriPermissionsLocked();
10642        }
10643
10644        if (goingCallback != null) goingCallback.run();
10645
10646        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10647                Integer.toString(mCurrentUserId), mCurrentUserId);
10648        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10649                Integer.toString(mCurrentUserId), mCurrentUserId);
10650        mSystemServiceManager.startUser(mCurrentUserId);
10651
10652        synchronized (this) {
10653            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10654                try {
10655                    List apps = AppGlobals.getPackageManager().
10656                        getPersistentApplications(STOCK_PM_FLAGS);
10657                    if (apps != null) {
10658                        int N = apps.size();
10659                        int i;
10660                        for (i=0; i<N; i++) {
10661                            ApplicationInfo info
10662                                = (ApplicationInfo)apps.get(i);
10663                            if (info != null &&
10664                                    !info.packageName.equals("android")) {
10665                                addAppLocked(info, false, null /* ABI override */);
10666                            }
10667                        }
10668                    }
10669                } catch (RemoteException ex) {
10670                    // pm is in same process, this will never happen.
10671                }
10672            }
10673
10674            // Start up initial activity.
10675            mBooting = true;
10676
10677            try {
10678                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10679                    Message msg = Message.obtain();
10680                    msg.what = SHOW_UID_ERROR_MSG;
10681                    mHandler.sendMessage(msg);
10682                }
10683            } catch (RemoteException e) {
10684            }
10685
10686            long ident = Binder.clearCallingIdentity();
10687            try {
10688                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10689                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10690                        | Intent.FLAG_RECEIVER_FOREGROUND);
10691                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10692                broadcastIntentLocked(null, null, intent,
10693                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10694                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10695                intent = new Intent(Intent.ACTION_USER_STARTING);
10696                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10697                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10698                broadcastIntentLocked(null, null, intent,
10699                        null, new IIntentReceiver.Stub() {
10700                            @Override
10701                            public void performReceive(Intent intent, int resultCode, String data,
10702                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10703                                    throws RemoteException {
10704                            }
10705                        }, 0, null, null,
10706                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10707                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10708            } catch (Throwable t) {
10709                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10710            } finally {
10711                Binder.restoreCallingIdentity(ident);
10712            }
10713            mStackSupervisor.resumeTopActivitiesLocked();
10714            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10715        }
10716    }
10717
10718    private boolean makeAppCrashingLocked(ProcessRecord app,
10719            String shortMsg, String longMsg, String stackTrace) {
10720        app.crashing = true;
10721        app.crashingReport = generateProcessError(app,
10722                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10723        startAppProblemLocked(app);
10724        app.stopFreezingAllLocked();
10725        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10726    }
10727
10728    private void makeAppNotRespondingLocked(ProcessRecord app,
10729            String activity, String shortMsg, String longMsg) {
10730        app.notResponding = true;
10731        app.notRespondingReport = generateProcessError(app,
10732                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10733                activity, shortMsg, longMsg, null);
10734        startAppProblemLocked(app);
10735        app.stopFreezingAllLocked();
10736    }
10737
10738    /**
10739     * Generate a process error record, suitable for attachment to a ProcessRecord.
10740     *
10741     * @param app The ProcessRecord in which the error occurred.
10742     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10743     *                      ActivityManager.AppErrorStateInfo
10744     * @param activity The activity associated with the crash, if known.
10745     * @param shortMsg Short message describing the crash.
10746     * @param longMsg Long message describing the crash.
10747     * @param stackTrace Full crash stack trace, may be null.
10748     *
10749     * @return Returns a fully-formed AppErrorStateInfo record.
10750     */
10751    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10752            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10753        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10754
10755        report.condition = condition;
10756        report.processName = app.processName;
10757        report.pid = app.pid;
10758        report.uid = app.info.uid;
10759        report.tag = activity;
10760        report.shortMsg = shortMsg;
10761        report.longMsg = longMsg;
10762        report.stackTrace = stackTrace;
10763
10764        return report;
10765    }
10766
10767    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10768        synchronized (this) {
10769            app.crashing = false;
10770            app.crashingReport = null;
10771            app.notResponding = false;
10772            app.notRespondingReport = null;
10773            if (app.anrDialog == fromDialog) {
10774                app.anrDialog = null;
10775            }
10776            if (app.waitDialog == fromDialog) {
10777                app.waitDialog = null;
10778            }
10779            if (app.pid > 0 && app.pid != MY_PID) {
10780                handleAppCrashLocked(app, null, null, null);
10781                killUnneededProcessLocked(app, "user request after error");
10782            }
10783        }
10784    }
10785
10786    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10787            String stackTrace) {
10788        long now = SystemClock.uptimeMillis();
10789
10790        Long crashTime;
10791        if (!app.isolated) {
10792            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10793        } else {
10794            crashTime = null;
10795        }
10796        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10797            // This process loses!
10798            Slog.w(TAG, "Process " + app.info.processName
10799                    + " has crashed too many times: killing!");
10800            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10801                    app.userId, app.info.processName, app.uid);
10802            mStackSupervisor.handleAppCrashLocked(app);
10803            if (!app.persistent) {
10804                // We don't want to start this process again until the user
10805                // explicitly does so...  but for persistent process, we really
10806                // need to keep it running.  If a persistent process is actually
10807                // repeatedly crashing, then badness for everyone.
10808                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10809                        app.info.processName);
10810                if (!app.isolated) {
10811                    // XXX We don't have a way to mark isolated processes
10812                    // as bad, since they don't have a peristent identity.
10813                    mBadProcesses.put(app.info.processName, app.uid,
10814                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10815                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10816                }
10817                app.bad = true;
10818                app.removed = true;
10819                // Don't let services in this process be restarted and potentially
10820                // annoy the user repeatedly.  Unless it is persistent, since those
10821                // processes run critical code.
10822                removeProcessLocked(app, false, false, "crash");
10823                mStackSupervisor.resumeTopActivitiesLocked();
10824                return false;
10825            }
10826            mStackSupervisor.resumeTopActivitiesLocked();
10827        } else {
10828            mStackSupervisor.finishTopRunningActivityLocked(app);
10829        }
10830
10831        // Bump up the crash count of any services currently running in the proc.
10832        for (int i=app.services.size()-1; i>=0; i--) {
10833            // Any services running in the application need to be placed
10834            // back in the pending list.
10835            ServiceRecord sr = app.services.valueAt(i);
10836            sr.crashCount++;
10837        }
10838
10839        // If the crashing process is what we consider to be the "home process" and it has been
10840        // replaced by a third-party app, clear the package preferred activities from packages
10841        // with a home activity running in the process to prevent a repeatedly crashing app
10842        // from blocking the user to manually clear the list.
10843        final ArrayList<ActivityRecord> activities = app.activities;
10844        if (app == mHomeProcess && activities.size() > 0
10845                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10846            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10847                final ActivityRecord r = activities.get(activityNdx);
10848                if (r.isHomeActivity()) {
10849                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10850                    try {
10851                        ActivityThread.getPackageManager()
10852                                .clearPackagePreferredActivities(r.packageName);
10853                    } catch (RemoteException c) {
10854                        // pm is in same process, this will never happen.
10855                    }
10856                }
10857            }
10858        }
10859
10860        if (!app.isolated) {
10861            // XXX Can't keep track of crash times for isolated processes,
10862            // because they don't have a perisistent identity.
10863            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10864        }
10865
10866        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10867        return true;
10868    }
10869
10870    void startAppProblemLocked(ProcessRecord app) {
10871        // If this app is not running under the current user, then we
10872        // can't give it a report button because that would require
10873        // launching the report UI under a different user.
10874        app.errorReportReceiver = null;
10875
10876        for (int userId : mCurrentProfileIds) {
10877            if (app.userId == userId) {
10878                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10879                        mContext, app.info.packageName, app.info.flags);
10880            }
10881        }
10882        skipCurrentReceiverLocked(app);
10883    }
10884
10885    void skipCurrentReceiverLocked(ProcessRecord app) {
10886        for (BroadcastQueue queue : mBroadcastQueues) {
10887            queue.skipCurrentReceiverLocked(app);
10888        }
10889    }
10890
10891    /**
10892     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10893     * The application process will exit immediately after this call returns.
10894     * @param app object of the crashing app, null for the system server
10895     * @param crashInfo describing the exception
10896     */
10897    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10898        ProcessRecord r = findAppProcess(app, "Crash");
10899        final String processName = app == null ? "system_server"
10900                : (r == null ? "unknown" : r.processName);
10901
10902        handleApplicationCrashInner("crash", r, processName, crashInfo);
10903    }
10904
10905    /* Native crash reporting uses this inner version because it needs to be somewhat
10906     * decoupled from the AM-managed cleanup lifecycle
10907     */
10908    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10909            ApplicationErrorReport.CrashInfo crashInfo) {
10910        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10911                UserHandle.getUserId(Binder.getCallingUid()), processName,
10912                r == null ? -1 : r.info.flags,
10913                crashInfo.exceptionClassName,
10914                crashInfo.exceptionMessage,
10915                crashInfo.throwFileName,
10916                crashInfo.throwLineNumber);
10917
10918        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10919
10920        crashApplication(r, crashInfo);
10921    }
10922
10923    public void handleApplicationStrictModeViolation(
10924            IBinder app,
10925            int violationMask,
10926            StrictMode.ViolationInfo info) {
10927        ProcessRecord r = findAppProcess(app, "StrictMode");
10928        if (r == null) {
10929            return;
10930        }
10931
10932        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10933            Integer stackFingerprint = info.hashCode();
10934            boolean logIt = true;
10935            synchronized (mAlreadyLoggedViolatedStacks) {
10936                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10937                    logIt = false;
10938                    // TODO: sub-sample into EventLog for these, with
10939                    // the info.durationMillis?  Then we'd get
10940                    // the relative pain numbers, without logging all
10941                    // the stack traces repeatedly.  We'd want to do
10942                    // likewise in the client code, which also does
10943                    // dup suppression, before the Binder call.
10944                } else {
10945                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10946                        mAlreadyLoggedViolatedStacks.clear();
10947                    }
10948                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10949                }
10950            }
10951            if (logIt) {
10952                logStrictModeViolationToDropBox(r, info);
10953            }
10954        }
10955
10956        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10957            AppErrorResult result = new AppErrorResult();
10958            synchronized (this) {
10959                final long origId = Binder.clearCallingIdentity();
10960
10961                Message msg = Message.obtain();
10962                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10963                HashMap<String, Object> data = new HashMap<String, Object>();
10964                data.put("result", result);
10965                data.put("app", r);
10966                data.put("violationMask", violationMask);
10967                data.put("info", info);
10968                msg.obj = data;
10969                mHandler.sendMessage(msg);
10970
10971                Binder.restoreCallingIdentity(origId);
10972            }
10973            int res = result.get();
10974            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10975        }
10976    }
10977
10978    // Depending on the policy in effect, there could be a bunch of
10979    // these in quick succession so we try to batch these together to
10980    // minimize disk writes, number of dropbox entries, and maximize
10981    // compression, by having more fewer, larger records.
10982    private void logStrictModeViolationToDropBox(
10983            ProcessRecord process,
10984            StrictMode.ViolationInfo info) {
10985        if (info == null) {
10986            return;
10987        }
10988        final boolean isSystemApp = process == null ||
10989                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10990                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10991        final String processName = process == null ? "unknown" : process.processName;
10992        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10993        final DropBoxManager dbox = (DropBoxManager)
10994                mContext.getSystemService(Context.DROPBOX_SERVICE);
10995
10996        // Exit early if the dropbox isn't configured to accept this report type.
10997        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10998
10999        boolean bufferWasEmpty;
11000        boolean needsFlush;
11001        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11002        synchronized (sb) {
11003            bufferWasEmpty = sb.length() == 0;
11004            appendDropBoxProcessHeaders(process, processName, sb);
11005            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11006            sb.append("System-App: ").append(isSystemApp).append("\n");
11007            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11008            if (info.violationNumThisLoop != 0) {
11009                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11010            }
11011            if (info.numAnimationsRunning != 0) {
11012                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11013            }
11014            if (info.broadcastIntentAction != null) {
11015                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11016            }
11017            if (info.durationMillis != -1) {
11018                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11019            }
11020            if (info.numInstances != -1) {
11021                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11022            }
11023            if (info.tags != null) {
11024                for (String tag : info.tags) {
11025                    sb.append("Span-Tag: ").append(tag).append("\n");
11026                }
11027            }
11028            sb.append("\n");
11029            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11030                sb.append(info.crashInfo.stackTrace);
11031            }
11032            sb.append("\n");
11033
11034            // Only buffer up to ~64k.  Various logging bits truncate
11035            // things at 128k.
11036            needsFlush = (sb.length() > 64 * 1024);
11037        }
11038
11039        // Flush immediately if the buffer's grown too large, or this
11040        // is a non-system app.  Non-system apps are isolated with a
11041        // different tag & policy and not batched.
11042        //
11043        // Batching is useful during internal testing with
11044        // StrictMode settings turned up high.  Without batching,
11045        // thousands of separate files could be created on boot.
11046        if (!isSystemApp || needsFlush) {
11047            new Thread("Error dump: " + dropboxTag) {
11048                @Override
11049                public void run() {
11050                    String report;
11051                    synchronized (sb) {
11052                        report = sb.toString();
11053                        sb.delete(0, sb.length());
11054                        sb.trimToSize();
11055                    }
11056                    if (report.length() != 0) {
11057                        dbox.addText(dropboxTag, report);
11058                    }
11059                }
11060            }.start();
11061            return;
11062        }
11063
11064        // System app batching:
11065        if (!bufferWasEmpty) {
11066            // An existing dropbox-writing thread is outstanding, so
11067            // we don't need to start it up.  The existing thread will
11068            // catch the buffer appends we just did.
11069            return;
11070        }
11071
11072        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11073        // (After this point, we shouldn't access AMS internal data structures.)
11074        new Thread("Error dump: " + dropboxTag) {
11075            @Override
11076            public void run() {
11077                // 5 second sleep to let stacks arrive and be batched together
11078                try {
11079                    Thread.sleep(5000);  // 5 seconds
11080                } catch (InterruptedException e) {}
11081
11082                String errorReport;
11083                synchronized (mStrictModeBuffer) {
11084                    errorReport = mStrictModeBuffer.toString();
11085                    if (errorReport.length() == 0) {
11086                        return;
11087                    }
11088                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11089                    mStrictModeBuffer.trimToSize();
11090                }
11091                dbox.addText(dropboxTag, errorReport);
11092            }
11093        }.start();
11094    }
11095
11096    /**
11097     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11098     * @param app object of the crashing app, null for the system server
11099     * @param tag reported by the caller
11100     * @param crashInfo describing the context of the error
11101     * @return true if the process should exit immediately (WTF is fatal)
11102     */
11103    public boolean handleApplicationWtf(IBinder app, String tag,
11104            ApplicationErrorReport.CrashInfo crashInfo) {
11105        ProcessRecord r = findAppProcess(app, "WTF");
11106        final String processName = app == null ? "system_server"
11107                : (r == null ? "unknown" : r.processName);
11108
11109        EventLog.writeEvent(EventLogTags.AM_WTF,
11110                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11111                processName,
11112                r == null ? -1 : r.info.flags,
11113                tag, crashInfo.exceptionMessage);
11114
11115        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11116
11117        if (r != null && r.pid != Process.myPid() &&
11118                Settings.Global.getInt(mContext.getContentResolver(),
11119                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11120            crashApplication(r, crashInfo);
11121            return true;
11122        } else {
11123            return false;
11124        }
11125    }
11126
11127    /**
11128     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11129     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11130     */
11131    private ProcessRecord findAppProcess(IBinder app, String reason) {
11132        if (app == null) {
11133            return null;
11134        }
11135
11136        synchronized (this) {
11137            final int NP = mProcessNames.getMap().size();
11138            for (int ip=0; ip<NP; ip++) {
11139                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11140                final int NA = apps.size();
11141                for (int ia=0; ia<NA; ia++) {
11142                    ProcessRecord p = apps.valueAt(ia);
11143                    if (p.thread != null && p.thread.asBinder() == app) {
11144                        return p;
11145                    }
11146                }
11147            }
11148
11149            Slog.w(TAG, "Can't find mystery application for " + reason
11150                    + " from pid=" + Binder.getCallingPid()
11151                    + " uid=" + Binder.getCallingUid() + ": " + app);
11152            return null;
11153        }
11154    }
11155
11156    /**
11157     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11158     * to append various headers to the dropbox log text.
11159     */
11160    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11161            StringBuilder sb) {
11162        // Watchdog thread ends up invoking this function (with
11163        // a null ProcessRecord) to add the stack file to dropbox.
11164        // Do not acquire a lock on this (am) in such cases, as it
11165        // could cause a potential deadlock, if and when watchdog
11166        // is invoked due to unavailability of lock on am and it
11167        // would prevent watchdog from killing system_server.
11168        if (process == null) {
11169            sb.append("Process: ").append(processName).append("\n");
11170            return;
11171        }
11172        // Note: ProcessRecord 'process' is guarded by the service
11173        // instance.  (notably process.pkgList, which could otherwise change
11174        // concurrently during execution of this method)
11175        synchronized (this) {
11176            sb.append("Process: ").append(processName).append("\n");
11177            int flags = process.info.flags;
11178            IPackageManager pm = AppGlobals.getPackageManager();
11179            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11180            for (int ip=0; ip<process.pkgList.size(); ip++) {
11181                String pkg = process.pkgList.keyAt(ip);
11182                sb.append("Package: ").append(pkg);
11183                try {
11184                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11185                    if (pi != null) {
11186                        sb.append(" v").append(pi.versionCode);
11187                        if (pi.versionName != null) {
11188                            sb.append(" (").append(pi.versionName).append(")");
11189                        }
11190                    }
11191                } catch (RemoteException e) {
11192                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11193                }
11194                sb.append("\n");
11195            }
11196        }
11197    }
11198
11199    private static String processClass(ProcessRecord process) {
11200        if (process == null || process.pid == MY_PID) {
11201            return "system_server";
11202        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11203            return "system_app";
11204        } else {
11205            return "data_app";
11206        }
11207    }
11208
11209    /**
11210     * Write a description of an error (crash, WTF, ANR) to the drop box.
11211     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11212     * @param process which caused the error, null means the system server
11213     * @param activity which triggered the error, null if unknown
11214     * @param parent activity related to the error, null if unknown
11215     * @param subject line related to the error, null if absent
11216     * @param report in long form describing the error, null if absent
11217     * @param logFile to include in the report, null if none
11218     * @param crashInfo giving an application stack trace, null if absent
11219     */
11220    public void addErrorToDropBox(String eventType,
11221            ProcessRecord process, String processName, ActivityRecord activity,
11222            ActivityRecord parent, String subject,
11223            final String report, final File logFile,
11224            final ApplicationErrorReport.CrashInfo crashInfo) {
11225        // NOTE -- this must never acquire the ActivityManagerService lock,
11226        // otherwise the watchdog may be prevented from resetting the system.
11227
11228        final String dropboxTag = processClass(process) + "_" + eventType;
11229        final DropBoxManager dbox = (DropBoxManager)
11230                mContext.getSystemService(Context.DROPBOX_SERVICE);
11231
11232        // Exit early if the dropbox isn't configured to accept this report type.
11233        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11234
11235        final StringBuilder sb = new StringBuilder(1024);
11236        appendDropBoxProcessHeaders(process, processName, sb);
11237        if (activity != null) {
11238            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11239        }
11240        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11241            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11242        }
11243        if (parent != null && parent != activity) {
11244            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11245        }
11246        if (subject != null) {
11247            sb.append("Subject: ").append(subject).append("\n");
11248        }
11249        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11250        if (Debug.isDebuggerConnected()) {
11251            sb.append("Debugger: Connected\n");
11252        }
11253        sb.append("\n");
11254
11255        // Do the rest in a worker thread to avoid blocking the caller on I/O
11256        // (After this point, we shouldn't access AMS internal data structures.)
11257        Thread worker = new Thread("Error dump: " + dropboxTag) {
11258            @Override
11259            public void run() {
11260                if (report != null) {
11261                    sb.append(report);
11262                }
11263                if (logFile != null) {
11264                    try {
11265                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11266                                    "\n\n[[TRUNCATED]]"));
11267                    } catch (IOException e) {
11268                        Slog.e(TAG, "Error reading " + logFile, e);
11269                    }
11270                }
11271                if (crashInfo != null && crashInfo.stackTrace != null) {
11272                    sb.append(crashInfo.stackTrace);
11273                }
11274
11275                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11276                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11277                if (lines > 0) {
11278                    sb.append("\n");
11279
11280                    // Merge several logcat streams, and take the last N lines
11281                    InputStreamReader input = null;
11282                    try {
11283                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11284                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11285                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11286
11287                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11288                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11289                        input = new InputStreamReader(logcat.getInputStream());
11290
11291                        int num;
11292                        char[] buf = new char[8192];
11293                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11294                    } catch (IOException e) {
11295                        Slog.e(TAG, "Error running logcat", e);
11296                    } finally {
11297                        if (input != null) try { input.close(); } catch (IOException e) {}
11298                    }
11299                }
11300
11301                dbox.addText(dropboxTag, sb.toString());
11302            }
11303        };
11304
11305        if (process == null) {
11306            // If process is null, we are being called from some internal code
11307            // and may be about to die -- run this synchronously.
11308            worker.run();
11309        } else {
11310            worker.start();
11311        }
11312    }
11313
11314    /**
11315     * Bring up the "unexpected error" dialog box for a crashing app.
11316     * Deal with edge cases (intercepts from instrumented applications,
11317     * ActivityController, error intent receivers, that sort of thing).
11318     * @param r the application crashing
11319     * @param crashInfo describing the failure
11320     */
11321    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11322        long timeMillis = System.currentTimeMillis();
11323        String shortMsg = crashInfo.exceptionClassName;
11324        String longMsg = crashInfo.exceptionMessage;
11325        String stackTrace = crashInfo.stackTrace;
11326        if (shortMsg != null && longMsg != null) {
11327            longMsg = shortMsg + ": " + longMsg;
11328        } else if (shortMsg != null) {
11329            longMsg = shortMsg;
11330        }
11331
11332        AppErrorResult result = new AppErrorResult();
11333        synchronized (this) {
11334            if (mController != null) {
11335                try {
11336                    String name = r != null ? r.processName : null;
11337                    int pid = r != null ? r.pid : Binder.getCallingPid();
11338                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11339                    if (!mController.appCrashed(name, pid,
11340                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11341                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11342                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11343                            Slog.w(TAG, "Skip killing native crashed app " + name
11344                                    + "(" + pid + ") during testing");
11345                        } else {
11346                            Slog.w(TAG, "Force-killing crashed app " + name
11347                                    + " at watcher's request");
11348                            Process.killProcess(pid);
11349                            if (r != null) {
11350                                Process.killProcessGroup(uid, pid);
11351                            }
11352                        }
11353                        return;
11354                    }
11355                } catch (RemoteException e) {
11356                    mController = null;
11357                    Watchdog.getInstance().setActivityController(null);
11358                }
11359            }
11360
11361            final long origId = Binder.clearCallingIdentity();
11362
11363            // If this process is running instrumentation, finish it.
11364            if (r != null && r.instrumentationClass != null) {
11365                Slog.w(TAG, "Error in app " + r.processName
11366                      + " running instrumentation " + r.instrumentationClass + ":");
11367                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11368                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11369                Bundle info = new Bundle();
11370                info.putString("shortMsg", shortMsg);
11371                info.putString("longMsg", longMsg);
11372                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11373                Binder.restoreCallingIdentity(origId);
11374                return;
11375            }
11376
11377            // If we can't identify the process or it's already exceeded its crash quota,
11378            // quit right away without showing a crash dialog.
11379            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11380                Binder.restoreCallingIdentity(origId);
11381                return;
11382            }
11383
11384            Message msg = Message.obtain();
11385            msg.what = SHOW_ERROR_MSG;
11386            HashMap data = new HashMap();
11387            data.put("result", result);
11388            data.put("app", r);
11389            msg.obj = data;
11390            mHandler.sendMessage(msg);
11391
11392            Binder.restoreCallingIdentity(origId);
11393        }
11394
11395        int res = result.get();
11396
11397        Intent appErrorIntent = null;
11398        synchronized (this) {
11399            if (r != null && !r.isolated) {
11400                // XXX Can't keep track of crash time for isolated processes,
11401                // since they don't have a persistent identity.
11402                mProcessCrashTimes.put(r.info.processName, r.uid,
11403                        SystemClock.uptimeMillis());
11404            }
11405            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11406                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11407            }
11408        }
11409
11410        if (appErrorIntent != null) {
11411            try {
11412                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11413            } catch (ActivityNotFoundException e) {
11414                Slog.w(TAG, "bug report receiver dissappeared", e);
11415            }
11416        }
11417    }
11418
11419    Intent createAppErrorIntentLocked(ProcessRecord r,
11420            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11421        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11422        if (report == null) {
11423            return null;
11424        }
11425        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11426        result.setComponent(r.errorReportReceiver);
11427        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11428        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11429        return result;
11430    }
11431
11432    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11433            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11434        if (r.errorReportReceiver == null) {
11435            return null;
11436        }
11437
11438        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11439            return null;
11440        }
11441
11442        ApplicationErrorReport report = new ApplicationErrorReport();
11443        report.packageName = r.info.packageName;
11444        report.installerPackageName = r.errorReportReceiver.getPackageName();
11445        report.processName = r.processName;
11446        report.time = timeMillis;
11447        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11448
11449        if (r.crashing || r.forceCrashReport) {
11450            report.type = ApplicationErrorReport.TYPE_CRASH;
11451            report.crashInfo = crashInfo;
11452        } else if (r.notResponding) {
11453            report.type = ApplicationErrorReport.TYPE_ANR;
11454            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11455
11456            report.anrInfo.activity = r.notRespondingReport.tag;
11457            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11458            report.anrInfo.info = r.notRespondingReport.longMsg;
11459        }
11460
11461        return report;
11462    }
11463
11464    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11465        enforceNotIsolatedCaller("getProcessesInErrorState");
11466        // assume our apps are happy - lazy create the list
11467        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11468
11469        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11470                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11471        int userId = UserHandle.getUserId(Binder.getCallingUid());
11472
11473        synchronized (this) {
11474
11475            // iterate across all processes
11476            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11477                ProcessRecord app = mLruProcesses.get(i);
11478                if (!allUsers && app.userId != userId) {
11479                    continue;
11480                }
11481                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11482                    // This one's in trouble, so we'll generate a report for it
11483                    // crashes are higher priority (in case there's a crash *and* an anr)
11484                    ActivityManager.ProcessErrorStateInfo report = null;
11485                    if (app.crashing) {
11486                        report = app.crashingReport;
11487                    } else if (app.notResponding) {
11488                        report = app.notRespondingReport;
11489                    }
11490
11491                    if (report != null) {
11492                        if (errList == null) {
11493                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11494                        }
11495                        errList.add(report);
11496                    } else {
11497                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11498                                " crashing = " + app.crashing +
11499                                " notResponding = " + app.notResponding);
11500                    }
11501                }
11502            }
11503        }
11504
11505        return errList;
11506    }
11507
11508    static int procStateToImportance(int procState, int memAdj,
11509            ActivityManager.RunningAppProcessInfo currApp) {
11510        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11511        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11512            currApp.lru = memAdj;
11513        } else {
11514            currApp.lru = 0;
11515        }
11516        return imp;
11517    }
11518
11519    private void fillInProcMemInfo(ProcessRecord app,
11520            ActivityManager.RunningAppProcessInfo outInfo) {
11521        outInfo.pid = app.pid;
11522        outInfo.uid = app.info.uid;
11523        if (mHeavyWeightProcess == app) {
11524            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11525        }
11526        if (app.persistent) {
11527            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11528        }
11529        if (app.activities.size() > 0) {
11530            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11531        }
11532        outInfo.lastTrimLevel = app.trimMemoryLevel;
11533        int adj = app.curAdj;
11534        int procState = app.curProcState;
11535        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11536        outInfo.importanceReasonCode = app.adjTypeCode;
11537        outInfo.processState = app.curProcState;
11538    }
11539
11540    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11541        enforceNotIsolatedCaller("getRunningAppProcesses");
11542        // Lazy instantiation of list
11543        List<ActivityManager.RunningAppProcessInfo> runList = null;
11544        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11545                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11546        int userId = UserHandle.getUserId(Binder.getCallingUid());
11547        synchronized (this) {
11548            // Iterate across all processes
11549            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11550                ProcessRecord app = mLruProcesses.get(i);
11551                if (!allUsers && app.userId != userId) {
11552                    continue;
11553                }
11554                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11555                    // Generate process state info for running application
11556                    ActivityManager.RunningAppProcessInfo currApp =
11557                        new ActivityManager.RunningAppProcessInfo(app.processName,
11558                                app.pid, app.getPackageList());
11559                    fillInProcMemInfo(app, currApp);
11560                    if (app.adjSource instanceof ProcessRecord) {
11561                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11562                        currApp.importanceReasonImportance =
11563                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11564                                        app.adjSourceProcState);
11565                    } else if (app.adjSource instanceof ActivityRecord) {
11566                        ActivityRecord r = (ActivityRecord)app.adjSource;
11567                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11568                    }
11569                    if (app.adjTarget instanceof ComponentName) {
11570                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11571                    }
11572                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11573                    //        + " lru=" + currApp.lru);
11574                    if (runList == null) {
11575                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11576                    }
11577                    runList.add(currApp);
11578                }
11579            }
11580        }
11581        return runList;
11582    }
11583
11584    public List<ApplicationInfo> getRunningExternalApplications() {
11585        enforceNotIsolatedCaller("getRunningExternalApplications");
11586        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11587        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11588        if (runningApps != null && runningApps.size() > 0) {
11589            Set<String> extList = new HashSet<String>();
11590            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11591                if (app.pkgList != null) {
11592                    for (String pkg : app.pkgList) {
11593                        extList.add(pkg);
11594                    }
11595                }
11596            }
11597            IPackageManager pm = AppGlobals.getPackageManager();
11598            for (String pkg : extList) {
11599                try {
11600                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11601                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11602                        retList.add(info);
11603                    }
11604                } catch (RemoteException e) {
11605                }
11606            }
11607        }
11608        return retList;
11609    }
11610
11611    @Override
11612    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11613        enforceNotIsolatedCaller("getMyMemoryState");
11614        synchronized (this) {
11615            ProcessRecord proc;
11616            synchronized (mPidsSelfLocked) {
11617                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11618            }
11619            fillInProcMemInfo(proc, outInfo);
11620        }
11621    }
11622
11623    @Override
11624    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11625        if (checkCallingPermission(android.Manifest.permission.DUMP)
11626                != PackageManager.PERMISSION_GRANTED) {
11627            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11628                    + Binder.getCallingPid()
11629                    + ", uid=" + Binder.getCallingUid()
11630                    + " without permission "
11631                    + android.Manifest.permission.DUMP);
11632            return;
11633        }
11634
11635        boolean dumpAll = false;
11636        boolean dumpClient = false;
11637        String dumpPackage = null;
11638
11639        int opti = 0;
11640        while (opti < args.length) {
11641            String opt = args[opti];
11642            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11643                break;
11644            }
11645            opti++;
11646            if ("-a".equals(opt)) {
11647                dumpAll = true;
11648            } else if ("-c".equals(opt)) {
11649                dumpClient = true;
11650            } else if ("-h".equals(opt)) {
11651                pw.println("Activity manager dump options:");
11652                pw.println("  [-a] [-c] [-h] [cmd] ...");
11653                pw.println("  cmd may be one of:");
11654                pw.println("    a[ctivities]: activity stack state");
11655                pw.println("    r[recents]: recent activities state");
11656                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11657                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11658                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11659                pw.println("    o[om]: out of memory management");
11660                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11661                pw.println("    provider [COMP_SPEC]: provider client-side state");
11662                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11663                pw.println("    service [COMP_SPEC]: service client-side state");
11664                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11665                pw.println("    all: dump all activities");
11666                pw.println("    top: dump the top activity");
11667                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11668                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11669                pw.println("    a partial substring in a component name, a");
11670                pw.println("    hex object identifier.");
11671                pw.println("  -a: include all available server state.");
11672                pw.println("  -c: include client state.");
11673                return;
11674            } else {
11675                pw.println("Unknown argument: " + opt + "; use -h for help");
11676            }
11677        }
11678
11679        long origId = Binder.clearCallingIdentity();
11680        boolean more = false;
11681        // Is the caller requesting to dump a particular piece of data?
11682        if (opti < args.length) {
11683            String cmd = args[opti];
11684            opti++;
11685            if ("activities".equals(cmd) || "a".equals(cmd)) {
11686                synchronized (this) {
11687                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11688                }
11689            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11690                synchronized (this) {
11691                    dumpRecentsLocked(fd, pw, args, opti, true, null);
11692                }
11693            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11694                String[] newArgs;
11695                String name;
11696                if (opti >= args.length) {
11697                    name = null;
11698                    newArgs = EMPTY_STRING_ARRAY;
11699                } else {
11700                    name = args[opti];
11701                    opti++;
11702                    newArgs = new String[args.length - opti];
11703                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11704                            args.length - opti);
11705                }
11706                synchronized (this) {
11707                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11708                }
11709            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11710                String[] newArgs;
11711                String name;
11712                if (opti >= args.length) {
11713                    name = null;
11714                    newArgs = EMPTY_STRING_ARRAY;
11715                } else {
11716                    name = args[opti];
11717                    opti++;
11718                    newArgs = new String[args.length - opti];
11719                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11720                            args.length - opti);
11721                }
11722                synchronized (this) {
11723                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11724                }
11725            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11726                String[] newArgs;
11727                String name;
11728                if (opti >= args.length) {
11729                    name = null;
11730                    newArgs = EMPTY_STRING_ARRAY;
11731                } else {
11732                    name = args[opti];
11733                    opti++;
11734                    newArgs = new String[args.length - opti];
11735                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11736                            args.length - opti);
11737                }
11738                synchronized (this) {
11739                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11740                }
11741            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11742                synchronized (this) {
11743                    dumpOomLocked(fd, pw, args, opti, true);
11744                }
11745            } else if ("provider".equals(cmd)) {
11746                String[] newArgs;
11747                String name;
11748                if (opti >= args.length) {
11749                    name = null;
11750                    newArgs = EMPTY_STRING_ARRAY;
11751                } else {
11752                    name = args[opti];
11753                    opti++;
11754                    newArgs = new String[args.length - opti];
11755                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11756                }
11757                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11758                    pw.println("No providers match: " + name);
11759                    pw.println("Use -h for help.");
11760                }
11761            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11762                synchronized (this) {
11763                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11764                }
11765            } else if ("service".equals(cmd)) {
11766                String[] newArgs;
11767                String name;
11768                if (opti >= args.length) {
11769                    name = null;
11770                    newArgs = EMPTY_STRING_ARRAY;
11771                } else {
11772                    name = args[opti];
11773                    opti++;
11774                    newArgs = new String[args.length - opti];
11775                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11776                            args.length - opti);
11777                }
11778                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11779                    pw.println("No services match: " + name);
11780                    pw.println("Use -h for help.");
11781                }
11782            } else if ("package".equals(cmd)) {
11783                String[] newArgs;
11784                if (opti >= args.length) {
11785                    pw.println("package: no package name specified");
11786                    pw.println("Use -h for help.");
11787                } else {
11788                    dumpPackage = args[opti];
11789                    opti++;
11790                    newArgs = new String[args.length - opti];
11791                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11792                            args.length - opti);
11793                    args = newArgs;
11794                    opti = 0;
11795                    more = true;
11796                }
11797            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11798                synchronized (this) {
11799                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11800                }
11801            } else {
11802                // Dumping a single activity?
11803                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11804                    pw.println("Bad activity command, or no activities match: " + cmd);
11805                    pw.println("Use -h for help.");
11806                }
11807            }
11808            if (!more) {
11809                Binder.restoreCallingIdentity(origId);
11810                return;
11811            }
11812        }
11813
11814        // No piece of data specified, dump everything.
11815        synchronized (this) {
11816            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11817            pw.println();
11818            if (dumpAll) {
11819                pw.println("-------------------------------------------------------------------------------");
11820            }
11821            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11822            pw.println();
11823            if (dumpAll) {
11824                pw.println("-------------------------------------------------------------------------------");
11825            }
11826            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11827            pw.println();
11828            if (dumpAll) {
11829                pw.println("-------------------------------------------------------------------------------");
11830            }
11831            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11832            pw.println();
11833            if (dumpAll) {
11834                pw.println("-------------------------------------------------------------------------------");
11835            }
11836            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11837            pw.println();
11838            if (dumpAll) {
11839                pw.println("-------------------------------------------------------------------------------");
11840            }
11841            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11842            pw.println();
11843            if (dumpAll) {
11844                pw.println("-------------------------------------------------------------------------------");
11845            }
11846            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11847        }
11848        Binder.restoreCallingIdentity(origId);
11849    }
11850
11851    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11852            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11853        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11854
11855        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11856                dumpPackage);
11857        boolean needSep = printedAnything;
11858
11859        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11860                dumpPackage, needSep, "  mFocusedActivity: ");
11861        if (printed) {
11862            printedAnything = true;
11863            needSep = false;
11864        }
11865
11866        if (dumpPackage == null) {
11867            if (needSep) {
11868                pw.println();
11869            }
11870            needSep = true;
11871            printedAnything = true;
11872            mStackSupervisor.dump(pw, "  ");
11873        }
11874
11875        if (!printedAnything) {
11876            pw.println("  (nothing)");
11877        }
11878    }
11879
11880    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11881            int opti, boolean dumpAll, String dumpPackage) {
11882        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
11883
11884        boolean printedAnything = false;
11885
11886        if (mRecentTasks.size() > 0) {
11887            boolean printedHeader = false;
11888
11889            final int N = mRecentTasks.size();
11890            for (int i=0; i<N; i++) {
11891                TaskRecord tr = mRecentTasks.get(i);
11892                if (dumpPackage != null) {
11893                    if (tr.realActivity == null ||
11894                            !dumpPackage.equals(tr.realActivity)) {
11895                        continue;
11896                    }
11897                }
11898                if (!printedHeader) {
11899                    pw.println("  Recent tasks:");
11900                    printedHeader = true;
11901                    printedAnything = true;
11902                }
11903                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11904                        pw.println(tr);
11905                if (dumpAll) {
11906                    mRecentTasks.get(i).dump(pw, "    ");
11907                }
11908            }
11909        }
11910
11911        if (!printedAnything) {
11912            pw.println("  (nothing)");
11913        }
11914    }
11915
11916    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11917            int opti, boolean dumpAll, String dumpPackage) {
11918        boolean needSep = false;
11919        boolean printedAnything = false;
11920        int numPers = 0;
11921
11922        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11923
11924        if (dumpAll) {
11925            final int NP = mProcessNames.getMap().size();
11926            for (int ip=0; ip<NP; ip++) {
11927                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11928                final int NA = procs.size();
11929                for (int ia=0; ia<NA; ia++) {
11930                    ProcessRecord r = procs.valueAt(ia);
11931                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11932                        continue;
11933                    }
11934                    if (!needSep) {
11935                        pw.println("  All known processes:");
11936                        needSep = true;
11937                        printedAnything = true;
11938                    }
11939                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11940                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11941                        pw.print(" "); pw.println(r);
11942                    r.dump(pw, "    ");
11943                    if (r.persistent) {
11944                        numPers++;
11945                    }
11946                }
11947            }
11948        }
11949
11950        if (mIsolatedProcesses.size() > 0) {
11951            boolean printed = false;
11952            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11953                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11954                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11955                    continue;
11956                }
11957                if (!printed) {
11958                    if (needSep) {
11959                        pw.println();
11960                    }
11961                    pw.println("  Isolated process list (sorted by uid):");
11962                    printedAnything = true;
11963                    printed = true;
11964                    needSep = true;
11965                }
11966                pw.println(String.format("%sIsolated #%2d: %s",
11967                        "    ", i, r.toString()));
11968            }
11969        }
11970
11971        if (mLruProcesses.size() > 0) {
11972            if (needSep) {
11973                pw.println();
11974            }
11975            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11976                    pw.print(" total, non-act at ");
11977                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11978                    pw.print(", non-svc at ");
11979                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11980                    pw.println("):");
11981            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11982            needSep = true;
11983            printedAnything = true;
11984        }
11985
11986        if (dumpAll || dumpPackage != null) {
11987            synchronized (mPidsSelfLocked) {
11988                boolean printed = false;
11989                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11990                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11991                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11992                        continue;
11993                    }
11994                    if (!printed) {
11995                        if (needSep) pw.println();
11996                        needSep = true;
11997                        pw.println("  PID mappings:");
11998                        printed = true;
11999                        printedAnything = true;
12000                    }
12001                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12002                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12003                }
12004            }
12005        }
12006
12007        if (mForegroundProcesses.size() > 0) {
12008            synchronized (mPidsSelfLocked) {
12009                boolean printed = false;
12010                for (int i=0; i<mForegroundProcesses.size(); i++) {
12011                    ProcessRecord r = mPidsSelfLocked.get(
12012                            mForegroundProcesses.valueAt(i).pid);
12013                    if (dumpPackage != null && (r == null
12014                            || !r.pkgList.containsKey(dumpPackage))) {
12015                        continue;
12016                    }
12017                    if (!printed) {
12018                        if (needSep) pw.println();
12019                        needSep = true;
12020                        pw.println("  Foreground Processes:");
12021                        printed = true;
12022                        printedAnything = true;
12023                    }
12024                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12025                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12026                }
12027            }
12028        }
12029
12030        if (mPersistentStartingProcesses.size() > 0) {
12031            if (needSep) pw.println();
12032            needSep = true;
12033            printedAnything = true;
12034            pw.println("  Persisent processes that are starting:");
12035            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12036                    "Starting Norm", "Restarting PERS", dumpPackage);
12037        }
12038
12039        if (mRemovedProcesses.size() > 0) {
12040            if (needSep) pw.println();
12041            needSep = true;
12042            printedAnything = true;
12043            pw.println("  Processes that are being removed:");
12044            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12045                    "Removed Norm", "Removed PERS", dumpPackage);
12046        }
12047
12048        if (mProcessesOnHold.size() > 0) {
12049            if (needSep) pw.println();
12050            needSep = true;
12051            printedAnything = true;
12052            pw.println("  Processes that are on old until the system is ready:");
12053            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12054                    "OnHold Norm", "OnHold PERS", dumpPackage);
12055        }
12056
12057        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12058
12059        if (mProcessCrashTimes.getMap().size() > 0) {
12060            boolean printed = false;
12061            long now = SystemClock.uptimeMillis();
12062            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12063            final int NP = pmap.size();
12064            for (int ip=0; ip<NP; ip++) {
12065                String pname = pmap.keyAt(ip);
12066                SparseArray<Long> uids = pmap.valueAt(ip);
12067                final int N = uids.size();
12068                for (int i=0; i<N; i++) {
12069                    int puid = uids.keyAt(i);
12070                    ProcessRecord r = mProcessNames.get(pname, puid);
12071                    if (dumpPackage != null && (r == null
12072                            || !r.pkgList.containsKey(dumpPackage))) {
12073                        continue;
12074                    }
12075                    if (!printed) {
12076                        if (needSep) pw.println();
12077                        needSep = true;
12078                        pw.println("  Time since processes crashed:");
12079                        printed = true;
12080                        printedAnything = true;
12081                    }
12082                    pw.print("    Process "); pw.print(pname);
12083                            pw.print(" uid "); pw.print(puid);
12084                            pw.print(": last crashed ");
12085                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12086                            pw.println(" ago");
12087                }
12088            }
12089        }
12090
12091        if (mBadProcesses.getMap().size() > 0) {
12092            boolean printed = false;
12093            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12094            final int NP = pmap.size();
12095            for (int ip=0; ip<NP; ip++) {
12096                String pname = pmap.keyAt(ip);
12097                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12098                final int N = uids.size();
12099                for (int i=0; i<N; i++) {
12100                    int puid = uids.keyAt(i);
12101                    ProcessRecord r = mProcessNames.get(pname, puid);
12102                    if (dumpPackage != null && (r == null
12103                            || !r.pkgList.containsKey(dumpPackage))) {
12104                        continue;
12105                    }
12106                    if (!printed) {
12107                        if (needSep) pw.println();
12108                        needSep = true;
12109                        pw.println("  Bad processes:");
12110                        printedAnything = true;
12111                    }
12112                    BadProcessInfo info = uids.valueAt(i);
12113                    pw.print("    Bad process "); pw.print(pname);
12114                            pw.print(" uid "); pw.print(puid);
12115                            pw.print(": crashed at time "); pw.println(info.time);
12116                    if (info.shortMsg != null) {
12117                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12118                    }
12119                    if (info.longMsg != null) {
12120                        pw.print("      Long msg: "); pw.println(info.longMsg);
12121                    }
12122                    if (info.stack != null) {
12123                        pw.println("      Stack:");
12124                        int lastPos = 0;
12125                        for (int pos=0; pos<info.stack.length(); pos++) {
12126                            if (info.stack.charAt(pos) == '\n') {
12127                                pw.print("        ");
12128                                pw.write(info.stack, lastPos, pos-lastPos);
12129                                pw.println();
12130                                lastPos = pos+1;
12131                            }
12132                        }
12133                        if (lastPos < info.stack.length()) {
12134                            pw.print("        ");
12135                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12136                            pw.println();
12137                        }
12138                    }
12139                }
12140            }
12141        }
12142
12143        if (dumpPackage == null) {
12144            pw.println();
12145            needSep = false;
12146            pw.println("  mStartedUsers:");
12147            for (int i=0; i<mStartedUsers.size(); i++) {
12148                UserStartedState uss = mStartedUsers.valueAt(i);
12149                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12150                        pw.print(": "); uss.dump("", pw);
12151            }
12152            pw.print("  mStartedUserArray: [");
12153            for (int i=0; i<mStartedUserArray.length; i++) {
12154                if (i > 0) pw.print(", ");
12155                pw.print(mStartedUserArray[i]);
12156            }
12157            pw.println("]");
12158            pw.print("  mUserLru: [");
12159            for (int i=0; i<mUserLru.size(); i++) {
12160                if (i > 0) pw.print(", ");
12161                pw.print(mUserLru.get(i));
12162            }
12163            pw.println("]");
12164            if (dumpAll) {
12165                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12166            }
12167            synchronized (mUserProfileGroupIdsSelfLocked) {
12168                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12169                    pw.println("  mUserProfileGroupIds:");
12170                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12171                        pw.print("    User #");
12172                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12173                        pw.print(" -> profile #");
12174                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12175                    }
12176                }
12177            }
12178        }
12179        if (mHomeProcess != null && (dumpPackage == null
12180                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12181            if (needSep) {
12182                pw.println();
12183                needSep = false;
12184            }
12185            pw.println("  mHomeProcess: " + mHomeProcess);
12186        }
12187        if (mPreviousProcess != null && (dumpPackage == null
12188                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12189            if (needSep) {
12190                pw.println();
12191                needSep = false;
12192            }
12193            pw.println("  mPreviousProcess: " + mPreviousProcess);
12194        }
12195        if (dumpAll) {
12196            StringBuilder sb = new StringBuilder(128);
12197            sb.append("  mPreviousProcessVisibleTime: ");
12198            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12199            pw.println(sb);
12200        }
12201        if (mHeavyWeightProcess != null && (dumpPackage == null
12202                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12203            if (needSep) {
12204                pw.println();
12205                needSep = false;
12206            }
12207            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12208        }
12209        if (dumpPackage == null) {
12210            pw.println("  mConfiguration: " + mConfiguration);
12211        }
12212        if (dumpAll) {
12213            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12214            if (mCompatModePackages.getPackages().size() > 0) {
12215                boolean printed = false;
12216                for (Map.Entry<String, Integer> entry
12217                        : mCompatModePackages.getPackages().entrySet()) {
12218                    String pkg = entry.getKey();
12219                    int mode = entry.getValue();
12220                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12221                        continue;
12222                    }
12223                    if (!printed) {
12224                        pw.println("  mScreenCompatPackages:");
12225                        printed = true;
12226                    }
12227                    pw.print("    "); pw.print(pkg); pw.print(": ");
12228                            pw.print(mode); pw.println();
12229                }
12230            }
12231        }
12232        if (dumpPackage == null) {
12233            if (mSleeping || mWentToSleep || mLockScreenShown) {
12234                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12235                        + " mLockScreenShown " + mLockScreenShown);
12236            }
12237            if (mShuttingDown || mRunningVoice) {
12238                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12239            }
12240        }
12241        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12242                || mOrigWaitForDebugger) {
12243            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12244                    || dumpPackage.equals(mOrigDebugApp)) {
12245                if (needSep) {
12246                    pw.println();
12247                    needSep = false;
12248                }
12249                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12250                        + " mDebugTransient=" + mDebugTransient
12251                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12252            }
12253        }
12254        if (mOpenGlTraceApp != null) {
12255            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12256                if (needSep) {
12257                    pw.println();
12258                    needSep = false;
12259                }
12260                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12261            }
12262        }
12263        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12264                || mProfileFd != null) {
12265            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12266                if (needSep) {
12267                    pw.println();
12268                    needSep = false;
12269                }
12270                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12271                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12272                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12273                        + mAutoStopProfiler);
12274            }
12275        }
12276        if (dumpPackage == null) {
12277            if (mAlwaysFinishActivities || mController != null) {
12278                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12279                        + " mController=" + mController);
12280            }
12281            if (dumpAll) {
12282                pw.println("  Total persistent processes: " + numPers);
12283                pw.println("  mProcessesReady=" + mProcessesReady
12284                        + " mSystemReady=" + mSystemReady);
12285                pw.println("  mBooting=" + mBooting
12286                        + " mBooted=" + mBooted
12287                        + " mFactoryTest=" + mFactoryTest);
12288                pw.print("  mLastPowerCheckRealtime=");
12289                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12290                        pw.println("");
12291                pw.print("  mLastPowerCheckUptime=");
12292                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12293                        pw.println("");
12294                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12295                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12296                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12297                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12298                        + " (" + mLruProcesses.size() + " total)"
12299                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12300                        + " mNumServiceProcs=" + mNumServiceProcs
12301                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12302                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12303                        + " mLastMemoryLevel" + mLastMemoryLevel
12304                        + " mLastNumProcesses" + mLastNumProcesses);
12305                long now = SystemClock.uptimeMillis();
12306                pw.print("  mLastIdleTime=");
12307                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12308                        pw.print(" mLowRamSinceLastIdle=");
12309                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12310                        pw.println();
12311            }
12312        }
12313
12314        if (!printedAnything) {
12315            pw.println("  (nothing)");
12316        }
12317    }
12318
12319    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12320            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12321        if (mProcessesToGc.size() > 0) {
12322            boolean printed = false;
12323            long now = SystemClock.uptimeMillis();
12324            for (int i=0; i<mProcessesToGc.size(); i++) {
12325                ProcessRecord proc = mProcessesToGc.get(i);
12326                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12327                    continue;
12328                }
12329                if (!printed) {
12330                    if (needSep) pw.println();
12331                    needSep = true;
12332                    pw.println("  Processes that are waiting to GC:");
12333                    printed = true;
12334                }
12335                pw.print("    Process "); pw.println(proc);
12336                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12337                        pw.print(", last gced=");
12338                        pw.print(now-proc.lastRequestedGc);
12339                        pw.print(" ms ago, last lowMem=");
12340                        pw.print(now-proc.lastLowMemory);
12341                        pw.println(" ms ago");
12342
12343            }
12344        }
12345        return needSep;
12346    }
12347
12348    void printOomLevel(PrintWriter pw, String name, int adj) {
12349        pw.print("    ");
12350        if (adj >= 0) {
12351            pw.print(' ');
12352            if (adj < 10) pw.print(' ');
12353        } else {
12354            if (adj > -10) pw.print(' ');
12355        }
12356        pw.print(adj);
12357        pw.print(": ");
12358        pw.print(name);
12359        pw.print(" (");
12360        pw.print(mProcessList.getMemLevel(adj)/1024);
12361        pw.println(" kB)");
12362    }
12363
12364    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12365            int opti, boolean dumpAll) {
12366        boolean needSep = false;
12367
12368        if (mLruProcesses.size() > 0) {
12369            if (needSep) pw.println();
12370            needSep = true;
12371            pw.println("  OOM levels:");
12372            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12373            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12374            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12375            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12376            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12377            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12378            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12379            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12380            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12381            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12382            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12383            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12384            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12385
12386            if (needSep) pw.println();
12387            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12388                    pw.print(" total, non-act at ");
12389                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12390                    pw.print(", non-svc at ");
12391                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12392                    pw.println("):");
12393            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12394            needSep = true;
12395        }
12396
12397        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12398
12399        pw.println();
12400        pw.println("  mHomeProcess: " + mHomeProcess);
12401        pw.println("  mPreviousProcess: " + mPreviousProcess);
12402        if (mHeavyWeightProcess != null) {
12403            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12404        }
12405
12406        return true;
12407    }
12408
12409    /**
12410     * There are three ways to call this:
12411     *  - no provider specified: dump all the providers
12412     *  - a flattened component name that matched an existing provider was specified as the
12413     *    first arg: dump that one provider
12414     *  - the first arg isn't the flattened component name of an existing provider:
12415     *    dump all providers whose component contains the first arg as a substring
12416     */
12417    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12418            int opti, boolean dumpAll) {
12419        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12420    }
12421
12422    static class ItemMatcher {
12423        ArrayList<ComponentName> components;
12424        ArrayList<String> strings;
12425        ArrayList<Integer> objects;
12426        boolean all;
12427
12428        ItemMatcher() {
12429            all = true;
12430        }
12431
12432        void build(String name) {
12433            ComponentName componentName = ComponentName.unflattenFromString(name);
12434            if (componentName != null) {
12435                if (components == null) {
12436                    components = new ArrayList<ComponentName>();
12437                }
12438                components.add(componentName);
12439                all = false;
12440            } else {
12441                int objectId = 0;
12442                // Not a '/' separated full component name; maybe an object ID?
12443                try {
12444                    objectId = Integer.parseInt(name, 16);
12445                    if (objects == null) {
12446                        objects = new ArrayList<Integer>();
12447                    }
12448                    objects.add(objectId);
12449                    all = false;
12450                } catch (RuntimeException e) {
12451                    // Not an integer; just do string match.
12452                    if (strings == null) {
12453                        strings = new ArrayList<String>();
12454                    }
12455                    strings.add(name);
12456                    all = false;
12457                }
12458            }
12459        }
12460
12461        int build(String[] args, int opti) {
12462            for (; opti<args.length; opti++) {
12463                String name = args[opti];
12464                if ("--".equals(name)) {
12465                    return opti+1;
12466                }
12467                build(name);
12468            }
12469            return opti;
12470        }
12471
12472        boolean match(Object object, ComponentName comp) {
12473            if (all) {
12474                return true;
12475            }
12476            if (components != null) {
12477                for (int i=0; i<components.size(); i++) {
12478                    if (components.get(i).equals(comp)) {
12479                        return true;
12480                    }
12481                }
12482            }
12483            if (objects != null) {
12484                for (int i=0; i<objects.size(); i++) {
12485                    if (System.identityHashCode(object) == objects.get(i)) {
12486                        return true;
12487                    }
12488                }
12489            }
12490            if (strings != null) {
12491                String flat = comp.flattenToString();
12492                for (int i=0; i<strings.size(); i++) {
12493                    if (flat.contains(strings.get(i))) {
12494                        return true;
12495                    }
12496                }
12497            }
12498            return false;
12499        }
12500    }
12501
12502    /**
12503     * There are three things that cmd can be:
12504     *  - a flattened component name that matches an existing activity
12505     *  - the cmd arg isn't the flattened component name of an existing activity:
12506     *    dump all activity whose component contains the cmd as a substring
12507     *  - A hex number of the ActivityRecord object instance.
12508     */
12509    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12510            int opti, boolean dumpAll) {
12511        ArrayList<ActivityRecord> activities;
12512
12513        synchronized (this) {
12514            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12515        }
12516
12517        if (activities.size() <= 0) {
12518            return false;
12519        }
12520
12521        String[] newArgs = new String[args.length - opti];
12522        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12523
12524        TaskRecord lastTask = null;
12525        boolean needSep = false;
12526        for (int i=activities.size()-1; i>=0; i--) {
12527            ActivityRecord r = activities.get(i);
12528            if (needSep) {
12529                pw.println();
12530            }
12531            needSep = true;
12532            synchronized (this) {
12533                if (lastTask != r.task) {
12534                    lastTask = r.task;
12535                    pw.print("TASK "); pw.print(lastTask.affinity);
12536                            pw.print(" id="); pw.println(lastTask.taskId);
12537                    if (dumpAll) {
12538                        lastTask.dump(pw, "  ");
12539                    }
12540                }
12541            }
12542            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12543        }
12544        return true;
12545    }
12546
12547    /**
12548     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12549     * there is a thread associated with the activity.
12550     */
12551    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12552            final ActivityRecord r, String[] args, boolean dumpAll) {
12553        String innerPrefix = prefix + "  ";
12554        synchronized (this) {
12555            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12556                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12557                    pw.print(" pid=");
12558                    if (r.app != null) pw.println(r.app.pid);
12559                    else pw.println("(not running)");
12560            if (dumpAll) {
12561                r.dump(pw, innerPrefix);
12562            }
12563        }
12564        if (r.app != null && r.app.thread != null) {
12565            // flush anything that is already in the PrintWriter since the thread is going
12566            // to write to the file descriptor directly
12567            pw.flush();
12568            try {
12569                TransferPipe tp = new TransferPipe();
12570                try {
12571                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12572                            r.appToken, innerPrefix, args);
12573                    tp.go(fd);
12574                } finally {
12575                    tp.kill();
12576                }
12577            } catch (IOException e) {
12578                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12579            } catch (RemoteException e) {
12580                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12581            }
12582        }
12583    }
12584
12585    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12586            int opti, boolean dumpAll, String dumpPackage) {
12587        boolean needSep = false;
12588        boolean onlyHistory = false;
12589        boolean printedAnything = false;
12590
12591        if ("history".equals(dumpPackage)) {
12592            if (opti < args.length && "-s".equals(args[opti])) {
12593                dumpAll = false;
12594            }
12595            onlyHistory = true;
12596            dumpPackage = null;
12597        }
12598
12599        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12600        if (!onlyHistory && dumpAll) {
12601            if (mRegisteredReceivers.size() > 0) {
12602                boolean printed = false;
12603                Iterator it = mRegisteredReceivers.values().iterator();
12604                while (it.hasNext()) {
12605                    ReceiverList r = (ReceiverList)it.next();
12606                    if (dumpPackage != null && (r.app == null ||
12607                            !dumpPackage.equals(r.app.info.packageName))) {
12608                        continue;
12609                    }
12610                    if (!printed) {
12611                        pw.println("  Registered Receivers:");
12612                        needSep = true;
12613                        printed = true;
12614                        printedAnything = true;
12615                    }
12616                    pw.print("  * "); pw.println(r);
12617                    r.dump(pw, "    ");
12618                }
12619            }
12620
12621            if (mReceiverResolver.dump(pw, needSep ?
12622                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12623                    "    ", dumpPackage, false)) {
12624                needSep = true;
12625                printedAnything = true;
12626            }
12627        }
12628
12629        for (BroadcastQueue q : mBroadcastQueues) {
12630            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12631            printedAnything |= needSep;
12632        }
12633
12634        needSep = true;
12635
12636        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12637            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12638                if (needSep) {
12639                    pw.println();
12640                }
12641                needSep = true;
12642                printedAnything = true;
12643                pw.print("  Sticky broadcasts for user ");
12644                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12645                StringBuilder sb = new StringBuilder(128);
12646                for (Map.Entry<String, ArrayList<Intent>> ent
12647                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12648                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12649                    if (dumpAll) {
12650                        pw.println(":");
12651                        ArrayList<Intent> intents = ent.getValue();
12652                        final int N = intents.size();
12653                        for (int i=0; i<N; i++) {
12654                            sb.setLength(0);
12655                            sb.append("    Intent: ");
12656                            intents.get(i).toShortString(sb, false, true, false, false);
12657                            pw.println(sb.toString());
12658                            Bundle bundle = intents.get(i).getExtras();
12659                            if (bundle != null) {
12660                                pw.print("      ");
12661                                pw.println(bundle.toString());
12662                            }
12663                        }
12664                    } else {
12665                        pw.println("");
12666                    }
12667                }
12668            }
12669        }
12670
12671        if (!onlyHistory && dumpAll) {
12672            pw.println();
12673            for (BroadcastQueue queue : mBroadcastQueues) {
12674                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12675                        + queue.mBroadcastsScheduled);
12676            }
12677            pw.println("  mHandler:");
12678            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12679            needSep = true;
12680            printedAnything = true;
12681        }
12682
12683        if (!printedAnything) {
12684            pw.println("  (nothing)");
12685        }
12686    }
12687
12688    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12689            int opti, boolean dumpAll, String dumpPackage) {
12690        boolean needSep;
12691        boolean printedAnything = false;
12692
12693        ItemMatcher matcher = new ItemMatcher();
12694        matcher.build(args, opti);
12695
12696        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12697
12698        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12699        printedAnything |= needSep;
12700
12701        if (mLaunchingProviders.size() > 0) {
12702            boolean printed = false;
12703            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12704                ContentProviderRecord r = mLaunchingProviders.get(i);
12705                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12706                    continue;
12707                }
12708                if (!printed) {
12709                    if (needSep) pw.println();
12710                    needSep = true;
12711                    pw.println("  Launching content providers:");
12712                    printed = true;
12713                    printedAnything = true;
12714                }
12715                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12716                        pw.println(r);
12717            }
12718        }
12719
12720        if (mGrantedUriPermissions.size() > 0) {
12721            boolean printed = false;
12722            int dumpUid = -2;
12723            if (dumpPackage != null) {
12724                try {
12725                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12726                } catch (NameNotFoundException e) {
12727                    dumpUid = -1;
12728                }
12729            }
12730            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12731                int uid = mGrantedUriPermissions.keyAt(i);
12732                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12733                    continue;
12734                }
12735                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12736                if (!printed) {
12737                    if (needSep) pw.println();
12738                    needSep = true;
12739                    pw.println("  Granted Uri Permissions:");
12740                    printed = true;
12741                    printedAnything = true;
12742                }
12743                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12744                for (UriPermission perm : perms.values()) {
12745                    pw.print("    "); pw.println(perm);
12746                    if (dumpAll) {
12747                        perm.dump(pw, "      ");
12748                    }
12749                }
12750            }
12751        }
12752
12753        if (!printedAnything) {
12754            pw.println("  (nothing)");
12755        }
12756    }
12757
12758    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12759            int opti, boolean dumpAll, String dumpPackage) {
12760        boolean printed = false;
12761
12762        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12763
12764        if (mIntentSenderRecords.size() > 0) {
12765            Iterator<WeakReference<PendingIntentRecord>> it
12766                    = mIntentSenderRecords.values().iterator();
12767            while (it.hasNext()) {
12768                WeakReference<PendingIntentRecord> ref = it.next();
12769                PendingIntentRecord rec = ref != null ? ref.get(): null;
12770                if (dumpPackage != null && (rec == null
12771                        || !dumpPackage.equals(rec.key.packageName))) {
12772                    continue;
12773                }
12774                printed = true;
12775                if (rec != null) {
12776                    pw.print("  * "); pw.println(rec);
12777                    if (dumpAll) {
12778                        rec.dump(pw, "    ");
12779                    }
12780                } else {
12781                    pw.print("  * "); pw.println(ref);
12782                }
12783            }
12784        }
12785
12786        if (!printed) {
12787            pw.println("  (nothing)");
12788        }
12789    }
12790
12791    private static final int dumpProcessList(PrintWriter pw,
12792            ActivityManagerService service, List list,
12793            String prefix, String normalLabel, String persistentLabel,
12794            String dumpPackage) {
12795        int numPers = 0;
12796        final int N = list.size()-1;
12797        for (int i=N; i>=0; i--) {
12798            ProcessRecord r = (ProcessRecord)list.get(i);
12799            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12800                continue;
12801            }
12802            pw.println(String.format("%s%s #%2d: %s",
12803                    prefix, (r.persistent ? persistentLabel : normalLabel),
12804                    i, r.toString()));
12805            if (r.persistent) {
12806                numPers++;
12807            }
12808        }
12809        return numPers;
12810    }
12811
12812    private static final boolean dumpProcessOomList(PrintWriter pw,
12813            ActivityManagerService service, List<ProcessRecord> origList,
12814            String prefix, String normalLabel, String persistentLabel,
12815            boolean inclDetails, String dumpPackage) {
12816
12817        ArrayList<Pair<ProcessRecord, Integer>> list
12818                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12819        for (int i=0; i<origList.size(); i++) {
12820            ProcessRecord r = origList.get(i);
12821            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12822                continue;
12823            }
12824            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12825        }
12826
12827        if (list.size() <= 0) {
12828            return false;
12829        }
12830
12831        Comparator<Pair<ProcessRecord, Integer>> comparator
12832                = new Comparator<Pair<ProcessRecord, Integer>>() {
12833            @Override
12834            public int compare(Pair<ProcessRecord, Integer> object1,
12835                    Pair<ProcessRecord, Integer> object2) {
12836                if (object1.first.setAdj != object2.first.setAdj) {
12837                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12838                }
12839                if (object1.second.intValue() != object2.second.intValue()) {
12840                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12841                }
12842                return 0;
12843            }
12844        };
12845
12846        Collections.sort(list, comparator);
12847
12848        final long curRealtime = SystemClock.elapsedRealtime();
12849        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12850        final long curUptime = SystemClock.uptimeMillis();
12851        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12852
12853        for (int i=list.size()-1; i>=0; i--) {
12854            ProcessRecord r = list.get(i).first;
12855            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12856            char schedGroup;
12857            switch (r.setSchedGroup) {
12858                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12859                    schedGroup = 'B';
12860                    break;
12861                case Process.THREAD_GROUP_DEFAULT:
12862                    schedGroup = 'F';
12863                    break;
12864                default:
12865                    schedGroup = '?';
12866                    break;
12867            }
12868            char foreground;
12869            if (r.foregroundActivities) {
12870                foreground = 'A';
12871            } else if (r.foregroundServices) {
12872                foreground = 'S';
12873            } else {
12874                foreground = ' ';
12875            }
12876            String procState = ProcessList.makeProcStateString(r.curProcState);
12877            pw.print(prefix);
12878            pw.print(r.persistent ? persistentLabel : normalLabel);
12879            pw.print(" #");
12880            int num = (origList.size()-1)-list.get(i).second;
12881            if (num < 10) pw.print(' ');
12882            pw.print(num);
12883            pw.print(": ");
12884            pw.print(oomAdj);
12885            pw.print(' ');
12886            pw.print(schedGroup);
12887            pw.print('/');
12888            pw.print(foreground);
12889            pw.print('/');
12890            pw.print(procState);
12891            pw.print(" trm:");
12892            if (r.trimMemoryLevel < 10) pw.print(' ');
12893            pw.print(r.trimMemoryLevel);
12894            pw.print(' ');
12895            pw.print(r.toShortString());
12896            pw.print(" (");
12897            pw.print(r.adjType);
12898            pw.println(')');
12899            if (r.adjSource != null || r.adjTarget != null) {
12900                pw.print(prefix);
12901                pw.print("    ");
12902                if (r.adjTarget instanceof ComponentName) {
12903                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12904                } else if (r.adjTarget != null) {
12905                    pw.print(r.adjTarget.toString());
12906                } else {
12907                    pw.print("{null}");
12908                }
12909                pw.print("<=");
12910                if (r.adjSource instanceof ProcessRecord) {
12911                    pw.print("Proc{");
12912                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12913                    pw.println("}");
12914                } else if (r.adjSource != null) {
12915                    pw.println(r.adjSource.toString());
12916                } else {
12917                    pw.println("{null}");
12918                }
12919            }
12920            if (inclDetails) {
12921                pw.print(prefix);
12922                pw.print("    ");
12923                pw.print("oom: max="); pw.print(r.maxAdj);
12924                pw.print(" curRaw="); pw.print(r.curRawAdj);
12925                pw.print(" setRaw="); pw.print(r.setRawAdj);
12926                pw.print(" cur="); pw.print(r.curAdj);
12927                pw.print(" set="); pw.println(r.setAdj);
12928                pw.print(prefix);
12929                pw.print("    ");
12930                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12931                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12932                pw.print(" lastPss="); pw.print(r.lastPss);
12933                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12934                pw.print(prefix);
12935                pw.print("    ");
12936                pw.print("cached="); pw.print(r.cached);
12937                pw.print(" empty="); pw.print(r.empty);
12938                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12939
12940                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12941                    if (r.lastWakeTime != 0) {
12942                        long wtime;
12943                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12944                        synchronized (stats) {
12945                            wtime = stats.getProcessWakeTime(r.info.uid,
12946                                    r.pid, curRealtime);
12947                        }
12948                        long timeUsed = wtime - r.lastWakeTime;
12949                        pw.print(prefix);
12950                        pw.print("    ");
12951                        pw.print("keep awake over ");
12952                        TimeUtils.formatDuration(realtimeSince, pw);
12953                        pw.print(" used ");
12954                        TimeUtils.formatDuration(timeUsed, pw);
12955                        pw.print(" (");
12956                        pw.print((timeUsed*100)/realtimeSince);
12957                        pw.println("%)");
12958                    }
12959                    if (r.lastCpuTime != 0) {
12960                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12961                        pw.print(prefix);
12962                        pw.print("    ");
12963                        pw.print("run cpu over ");
12964                        TimeUtils.formatDuration(uptimeSince, pw);
12965                        pw.print(" used ");
12966                        TimeUtils.formatDuration(timeUsed, pw);
12967                        pw.print(" (");
12968                        pw.print((timeUsed*100)/uptimeSince);
12969                        pw.println("%)");
12970                    }
12971                }
12972            }
12973        }
12974        return true;
12975    }
12976
12977    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12978        ArrayList<ProcessRecord> procs;
12979        synchronized (this) {
12980            if (args != null && args.length > start
12981                    && args[start].charAt(0) != '-') {
12982                procs = new ArrayList<ProcessRecord>();
12983                int pid = -1;
12984                try {
12985                    pid = Integer.parseInt(args[start]);
12986                } catch (NumberFormatException e) {
12987                }
12988                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12989                    ProcessRecord proc = mLruProcesses.get(i);
12990                    if (proc.pid == pid) {
12991                        procs.add(proc);
12992                    } else if (proc.processName.equals(args[start])) {
12993                        procs.add(proc);
12994                    }
12995                }
12996                if (procs.size() <= 0) {
12997                    return null;
12998                }
12999            } else {
13000                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13001            }
13002        }
13003        return procs;
13004    }
13005
13006    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13007            PrintWriter pw, String[] args) {
13008        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13009        if (procs == null) {
13010            pw.println("No process found for: " + args[0]);
13011            return;
13012        }
13013
13014        long uptime = SystemClock.uptimeMillis();
13015        long realtime = SystemClock.elapsedRealtime();
13016        pw.println("Applications Graphics Acceleration Info:");
13017        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13018
13019        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13020            ProcessRecord r = procs.get(i);
13021            if (r.thread != null) {
13022                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13023                pw.flush();
13024                try {
13025                    TransferPipe tp = new TransferPipe();
13026                    try {
13027                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13028                        tp.go(fd);
13029                    } finally {
13030                        tp.kill();
13031                    }
13032                } catch (IOException e) {
13033                    pw.println("Failure while dumping the app: " + r);
13034                    pw.flush();
13035                } catch (RemoteException e) {
13036                    pw.println("Got a RemoteException while dumping the app " + r);
13037                    pw.flush();
13038                }
13039            }
13040        }
13041    }
13042
13043    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13044        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13045        if (procs == null) {
13046            pw.println("No process found for: " + args[0]);
13047            return;
13048        }
13049
13050        pw.println("Applications Database Info:");
13051
13052        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13053            ProcessRecord r = procs.get(i);
13054            if (r.thread != null) {
13055                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13056                pw.flush();
13057                try {
13058                    TransferPipe tp = new TransferPipe();
13059                    try {
13060                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13061                        tp.go(fd);
13062                    } finally {
13063                        tp.kill();
13064                    }
13065                } catch (IOException e) {
13066                    pw.println("Failure while dumping the app: " + r);
13067                    pw.flush();
13068                } catch (RemoteException e) {
13069                    pw.println("Got a RemoteException while dumping the app " + r);
13070                    pw.flush();
13071                }
13072            }
13073        }
13074    }
13075
13076    final static class MemItem {
13077        final boolean isProc;
13078        final String label;
13079        final String shortLabel;
13080        final long pss;
13081        final int id;
13082        final boolean hasActivities;
13083        ArrayList<MemItem> subitems;
13084
13085        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13086                boolean _hasActivities) {
13087            isProc = true;
13088            label = _label;
13089            shortLabel = _shortLabel;
13090            pss = _pss;
13091            id = _id;
13092            hasActivities = _hasActivities;
13093        }
13094
13095        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13096            isProc = false;
13097            label = _label;
13098            shortLabel = _shortLabel;
13099            pss = _pss;
13100            id = _id;
13101            hasActivities = false;
13102        }
13103    }
13104
13105    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13106            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13107        if (sort && !isCompact) {
13108            Collections.sort(items, new Comparator<MemItem>() {
13109                @Override
13110                public int compare(MemItem lhs, MemItem rhs) {
13111                    if (lhs.pss < rhs.pss) {
13112                        return 1;
13113                    } else if (lhs.pss > rhs.pss) {
13114                        return -1;
13115                    }
13116                    return 0;
13117                }
13118            });
13119        }
13120
13121        for (int i=0; i<items.size(); i++) {
13122            MemItem mi = items.get(i);
13123            if (!isCompact) {
13124                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13125            } else if (mi.isProc) {
13126                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13127                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13128                pw.println(mi.hasActivities ? ",a" : ",e");
13129            } else {
13130                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13131                pw.println(mi.pss);
13132            }
13133            if (mi.subitems != null) {
13134                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13135                        true, isCompact);
13136            }
13137        }
13138    }
13139
13140    // These are in KB.
13141    static final long[] DUMP_MEM_BUCKETS = new long[] {
13142        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13143        120*1024, 160*1024, 200*1024,
13144        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13145        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13146    };
13147
13148    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13149            boolean stackLike) {
13150        int start = label.lastIndexOf('.');
13151        if (start >= 0) start++;
13152        else start = 0;
13153        int end = label.length();
13154        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13155            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13156                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13157                out.append(bucket);
13158                out.append(stackLike ? "MB." : "MB ");
13159                out.append(label, start, end);
13160                return;
13161            }
13162        }
13163        out.append(memKB/1024);
13164        out.append(stackLike ? "MB." : "MB ");
13165        out.append(label, start, end);
13166    }
13167
13168    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13169            ProcessList.NATIVE_ADJ,
13170            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13171            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13172            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13173            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13174            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13175    };
13176    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13177            "Native",
13178            "System", "Persistent", "Foreground",
13179            "Visible", "Perceptible",
13180            "Heavy Weight", "Backup",
13181            "A Services", "Home",
13182            "Previous", "B Services", "Cached"
13183    };
13184    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13185            "native",
13186            "sys", "pers", "fore",
13187            "vis", "percept",
13188            "heavy", "backup",
13189            "servicea", "home",
13190            "prev", "serviceb", "cached"
13191    };
13192
13193    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13194            long realtime, boolean isCheckinRequest, boolean isCompact) {
13195        if (isCheckinRequest || isCompact) {
13196            // short checkin version
13197            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13198        } else {
13199            pw.println("Applications Memory Usage (kB):");
13200            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13201        }
13202    }
13203
13204    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13205            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13206        boolean dumpDetails = false;
13207        boolean dumpFullDetails = false;
13208        boolean dumpDalvik = false;
13209        boolean oomOnly = false;
13210        boolean isCompact = false;
13211        boolean localOnly = false;
13212
13213        int opti = 0;
13214        while (opti < args.length) {
13215            String opt = args[opti];
13216            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13217                break;
13218            }
13219            opti++;
13220            if ("-a".equals(opt)) {
13221                dumpDetails = true;
13222                dumpFullDetails = true;
13223                dumpDalvik = true;
13224            } else if ("-d".equals(opt)) {
13225                dumpDalvik = true;
13226            } else if ("-c".equals(opt)) {
13227                isCompact = true;
13228            } else if ("--oom".equals(opt)) {
13229                oomOnly = true;
13230            } else if ("--local".equals(opt)) {
13231                localOnly = true;
13232            } else if ("-h".equals(opt)) {
13233                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13234                pw.println("  -a: include all available information for each process.");
13235                pw.println("  -d: include dalvik details when dumping process details.");
13236                pw.println("  -c: dump in a compact machine-parseable representation.");
13237                pw.println("  --oom: only show processes organized by oom adj.");
13238                pw.println("  --local: only collect details locally, don't call process.");
13239                pw.println("If [process] is specified it can be the name or ");
13240                pw.println("pid of a specific process to dump.");
13241                return;
13242            } else {
13243                pw.println("Unknown argument: " + opt + "; use -h for help");
13244            }
13245        }
13246
13247        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13248        long uptime = SystemClock.uptimeMillis();
13249        long realtime = SystemClock.elapsedRealtime();
13250        final long[] tmpLong = new long[1];
13251
13252        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13253        if (procs == null) {
13254            // No Java processes.  Maybe they want to print a native process.
13255            if (args != null && args.length > opti
13256                    && args[opti].charAt(0) != '-') {
13257                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13258                        = new ArrayList<ProcessCpuTracker.Stats>();
13259                updateCpuStatsNow();
13260                int findPid = -1;
13261                try {
13262                    findPid = Integer.parseInt(args[opti]);
13263                } catch (NumberFormatException e) {
13264                }
13265                synchronized (mProcessCpuThread) {
13266                    final int N = mProcessCpuTracker.countStats();
13267                    for (int i=0; i<N; i++) {
13268                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13269                        if (st.pid == findPid || (st.baseName != null
13270                                && st.baseName.equals(args[opti]))) {
13271                            nativeProcs.add(st);
13272                        }
13273                    }
13274                }
13275                if (nativeProcs.size() > 0) {
13276                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13277                            isCompact);
13278                    Debug.MemoryInfo mi = null;
13279                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13280                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13281                        final int pid = r.pid;
13282                        if (!isCheckinRequest && dumpDetails) {
13283                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13284                        }
13285                        if (mi == null) {
13286                            mi = new Debug.MemoryInfo();
13287                        }
13288                        if (dumpDetails || (!brief && !oomOnly)) {
13289                            Debug.getMemoryInfo(pid, mi);
13290                        } else {
13291                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13292                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13293                        }
13294                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13295                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13296                        if (isCheckinRequest) {
13297                            pw.println();
13298                        }
13299                    }
13300                    return;
13301                }
13302            }
13303            pw.println("No process found for: " + args[opti]);
13304            return;
13305        }
13306
13307        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13308            dumpDetails = true;
13309        }
13310
13311        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13312
13313        String[] innerArgs = new String[args.length-opti];
13314        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13315
13316        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13317        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13318        long nativePss=0, dalvikPss=0, otherPss=0;
13319        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13320
13321        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13322        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13323                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13324
13325        long totalPss = 0;
13326        long cachedPss = 0;
13327
13328        Debug.MemoryInfo mi = null;
13329        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13330            final ProcessRecord r = procs.get(i);
13331            final IApplicationThread thread;
13332            final int pid;
13333            final int oomAdj;
13334            final boolean hasActivities;
13335            synchronized (this) {
13336                thread = r.thread;
13337                pid = r.pid;
13338                oomAdj = r.getSetAdjWithServices();
13339                hasActivities = r.activities.size() > 0;
13340            }
13341            if (thread != null) {
13342                if (!isCheckinRequest && dumpDetails) {
13343                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13344                }
13345                if (mi == null) {
13346                    mi = new Debug.MemoryInfo();
13347                }
13348                if (dumpDetails || (!brief && !oomOnly)) {
13349                    Debug.getMemoryInfo(pid, mi);
13350                } else {
13351                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13352                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13353                }
13354                if (dumpDetails) {
13355                    if (localOnly) {
13356                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13357                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13358                        if (isCheckinRequest) {
13359                            pw.println();
13360                        }
13361                    } else {
13362                        try {
13363                            pw.flush();
13364                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13365                                    dumpDalvik, innerArgs);
13366                        } catch (RemoteException e) {
13367                            if (!isCheckinRequest) {
13368                                pw.println("Got RemoteException!");
13369                                pw.flush();
13370                            }
13371                        }
13372                    }
13373                }
13374
13375                final long myTotalPss = mi.getTotalPss();
13376                final long myTotalUss = mi.getTotalUss();
13377
13378                synchronized (this) {
13379                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13380                        // Record this for posterity if the process has been stable.
13381                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13382                    }
13383                }
13384
13385                if (!isCheckinRequest && mi != null) {
13386                    totalPss += myTotalPss;
13387                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13388                            (hasActivities ? " / activities)" : ")"),
13389                            r.processName, myTotalPss, pid, hasActivities);
13390                    procMems.add(pssItem);
13391                    procMemsMap.put(pid, pssItem);
13392
13393                    nativePss += mi.nativePss;
13394                    dalvikPss += mi.dalvikPss;
13395                    otherPss += mi.otherPss;
13396                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13397                        long mem = mi.getOtherPss(j);
13398                        miscPss[j] += mem;
13399                        otherPss -= mem;
13400                    }
13401
13402                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13403                        cachedPss += myTotalPss;
13404                    }
13405
13406                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13407                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13408                                || oomIndex == (oomPss.length-1)) {
13409                            oomPss[oomIndex] += myTotalPss;
13410                            if (oomProcs[oomIndex] == null) {
13411                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13412                            }
13413                            oomProcs[oomIndex].add(pssItem);
13414                            break;
13415                        }
13416                    }
13417                }
13418            }
13419        }
13420
13421        long nativeProcTotalPss = 0;
13422
13423        if (!isCheckinRequest && procs.size() > 1) {
13424            // If we are showing aggregations, also look for native processes to
13425            // include so that our aggregations are more accurate.
13426            updateCpuStatsNow();
13427            synchronized (mProcessCpuThread) {
13428                final int N = mProcessCpuTracker.countStats();
13429                for (int i=0; i<N; i++) {
13430                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13431                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13432                        if (mi == null) {
13433                            mi = new Debug.MemoryInfo();
13434                        }
13435                        if (!brief && !oomOnly) {
13436                            Debug.getMemoryInfo(st.pid, mi);
13437                        } else {
13438                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13439                            mi.nativePrivateDirty = (int)tmpLong[0];
13440                        }
13441
13442                        final long myTotalPss = mi.getTotalPss();
13443                        totalPss += myTotalPss;
13444                        nativeProcTotalPss += myTotalPss;
13445
13446                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13447                                st.name, myTotalPss, st.pid, false);
13448                        procMems.add(pssItem);
13449
13450                        nativePss += mi.nativePss;
13451                        dalvikPss += mi.dalvikPss;
13452                        otherPss += mi.otherPss;
13453                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13454                            long mem = mi.getOtherPss(j);
13455                            miscPss[j] += mem;
13456                            otherPss -= mem;
13457                        }
13458                        oomPss[0] += myTotalPss;
13459                        if (oomProcs[0] == null) {
13460                            oomProcs[0] = new ArrayList<MemItem>();
13461                        }
13462                        oomProcs[0].add(pssItem);
13463                    }
13464                }
13465            }
13466
13467            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13468
13469            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13470            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13471            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13472            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13473                String label = Debug.MemoryInfo.getOtherLabel(j);
13474                catMems.add(new MemItem(label, label, miscPss[j], j));
13475            }
13476
13477            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13478            for (int j=0; j<oomPss.length; j++) {
13479                if (oomPss[j] != 0) {
13480                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13481                            : DUMP_MEM_OOM_LABEL[j];
13482                    MemItem item = new MemItem(label, label, oomPss[j],
13483                            DUMP_MEM_OOM_ADJ[j]);
13484                    item.subitems = oomProcs[j];
13485                    oomMems.add(item);
13486                }
13487            }
13488
13489            if (!brief && !oomOnly && !isCompact) {
13490                pw.println();
13491                pw.println("Total PSS by process:");
13492                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13493                pw.println();
13494            }
13495            if (!isCompact) {
13496                pw.println("Total PSS by OOM adjustment:");
13497            }
13498            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13499            if (!brief && !oomOnly) {
13500                PrintWriter out = categoryPw != null ? categoryPw : pw;
13501                if (!isCompact) {
13502                    out.println();
13503                    out.println("Total PSS by category:");
13504                }
13505                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13506            }
13507            if (!isCompact) {
13508                pw.println();
13509            }
13510            MemInfoReader memInfo = new MemInfoReader();
13511            memInfo.readMemInfo();
13512            if (nativeProcTotalPss > 0) {
13513                synchronized (this) {
13514                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13515                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13516                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13517                            nativeProcTotalPss);
13518                }
13519            }
13520            if (!brief) {
13521                if (!isCompact) {
13522                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13523                    pw.print(" kB (status ");
13524                    switch (mLastMemoryLevel) {
13525                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13526                            pw.println("normal)");
13527                            break;
13528                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13529                            pw.println("moderate)");
13530                            break;
13531                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13532                            pw.println("low)");
13533                            break;
13534                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13535                            pw.println("critical)");
13536                            break;
13537                        default:
13538                            pw.print(mLastMemoryLevel);
13539                            pw.println(")");
13540                            break;
13541                    }
13542                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13543                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13544                            pw.print(cachedPss); pw.print(" cached pss + ");
13545                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13546                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13547                } else {
13548                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13549                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13550                            + memInfo.getFreeSizeKb()); pw.print(",");
13551                    pw.println(totalPss - cachedPss);
13552                }
13553            }
13554            if (!isCompact) {
13555                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13556                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13557                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13558                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13559                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13560                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13561                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13562                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13563                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13564                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13565                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13566            }
13567            if (!brief) {
13568                if (memInfo.getZramTotalSizeKb() != 0) {
13569                    if (!isCompact) {
13570                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13571                                pw.print(" kB physical used for ");
13572                                pw.print(memInfo.getSwapTotalSizeKb()
13573                                        - memInfo.getSwapFreeSizeKb());
13574                                pw.print(" kB in swap (");
13575                                pw.print(memInfo.getSwapTotalSizeKb());
13576                                pw.println(" kB total swap)");
13577                    } else {
13578                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13579                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13580                                pw.println(memInfo.getSwapFreeSizeKb());
13581                    }
13582                }
13583                final int[] SINGLE_LONG_FORMAT = new int[] {
13584                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13585                };
13586                long[] longOut = new long[1];
13587                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13588                        SINGLE_LONG_FORMAT, null, longOut, null);
13589                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13590                longOut[0] = 0;
13591                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13592                        SINGLE_LONG_FORMAT, null, longOut, null);
13593                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13594                longOut[0] = 0;
13595                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13596                        SINGLE_LONG_FORMAT, null, longOut, null);
13597                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13598                longOut[0] = 0;
13599                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13600                        SINGLE_LONG_FORMAT, null, longOut, null);
13601                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13602                if (!isCompact) {
13603                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13604                        pw.print("      KSM: "); pw.print(sharing);
13605                                pw.print(" kB saved from shared ");
13606                                pw.print(shared); pw.println(" kB");
13607                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13608                                pw.print(voltile); pw.println(" kB volatile");
13609                    }
13610                    pw.print("   Tuning: ");
13611                    pw.print(ActivityManager.staticGetMemoryClass());
13612                    pw.print(" (large ");
13613                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13614                    pw.print("), oom ");
13615                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13616                    pw.print(" kB");
13617                    pw.print(", restore limit ");
13618                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13619                    pw.print(" kB");
13620                    if (ActivityManager.isLowRamDeviceStatic()) {
13621                        pw.print(" (low-ram)");
13622                    }
13623                    if (ActivityManager.isHighEndGfx()) {
13624                        pw.print(" (high-end-gfx)");
13625                    }
13626                    pw.println();
13627                } else {
13628                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13629                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13630                    pw.println(voltile);
13631                    pw.print("tuning,");
13632                    pw.print(ActivityManager.staticGetMemoryClass());
13633                    pw.print(',');
13634                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13635                    pw.print(',');
13636                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13637                    if (ActivityManager.isLowRamDeviceStatic()) {
13638                        pw.print(",low-ram");
13639                    }
13640                    if (ActivityManager.isHighEndGfx()) {
13641                        pw.print(",high-end-gfx");
13642                    }
13643                    pw.println();
13644                }
13645            }
13646        }
13647    }
13648
13649    /**
13650     * Searches array of arguments for the specified string
13651     * @param args array of argument strings
13652     * @param value value to search for
13653     * @return true if the value is contained in the array
13654     */
13655    private static boolean scanArgs(String[] args, String value) {
13656        if (args != null) {
13657            for (String arg : args) {
13658                if (value.equals(arg)) {
13659                    return true;
13660                }
13661            }
13662        }
13663        return false;
13664    }
13665
13666    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13667            ContentProviderRecord cpr, boolean always) {
13668        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13669
13670        if (!inLaunching || always) {
13671            synchronized (cpr) {
13672                cpr.launchingApp = null;
13673                cpr.notifyAll();
13674            }
13675            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13676            String names[] = cpr.info.authority.split(";");
13677            for (int j = 0; j < names.length; j++) {
13678                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13679            }
13680        }
13681
13682        for (int i=0; i<cpr.connections.size(); i++) {
13683            ContentProviderConnection conn = cpr.connections.get(i);
13684            if (conn.waiting) {
13685                // If this connection is waiting for the provider, then we don't
13686                // need to mess with its process unless we are always removing
13687                // or for some reason the provider is not currently launching.
13688                if (inLaunching && !always) {
13689                    continue;
13690                }
13691            }
13692            ProcessRecord capp = conn.client;
13693            conn.dead = true;
13694            if (conn.stableCount > 0) {
13695                if (!capp.persistent && capp.thread != null
13696                        && capp.pid != 0
13697                        && capp.pid != MY_PID) {
13698                    killUnneededProcessLocked(capp, "depends on provider "
13699                            + cpr.name.flattenToShortString()
13700                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13701                }
13702            } else if (capp.thread != null && conn.provider.provider != null) {
13703                try {
13704                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13705                } catch (RemoteException e) {
13706                }
13707                // In the protocol here, we don't expect the client to correctly
13708                // clean up this connection, we'll just remove it.
13709                cpr.connections.remove(i);
13710                conn.client.conProviders.remove(conn);
13711            }
13712        }
13713
13714        if (inLaunching && always) {
13715            mLaunchingProviders.remove(cpr);
13716        }
13717        return inLaunching;
13718    }
13719
13720    /**
13721     * Main code for cleaning up a process when it has gone away.  This is
13722     * called both as a result of the process dying, or directly when stopping
13723     * a process when running in single process mode.
13724     */
13725    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13726            boolean restarting, boolean allowRestart, int index) {
13727        if (index >= 0) {
13728            removeLruProcessLocked(app);
13729            ProcessList.remove(app.pid);
13730        }
13731
13732        mProcessesToGc.remove(app);
13733        mPendingPssProcesses.remove(app);
13734
13735        // Dismiss any open dialogs.
13736        if (app.crashDialog != null && !app.forceCrashReport) {
13737            app.crashDialog.dismiss();
13738            app.crashDialog = null;
13739        }
13740        if (app.anrDialog != null) {
13741            app.anrDialog.dismiss();
13742            app.anrDialog = null;
13743        }
13744        if (app.waitDialog != null) {
13745            app.waitDialog.dismiss();
13746            app.waitDialog = null;
13747        }
13748
13749        app.crashing = false;
13750        app.notResponding = false;
13751
13752        app.resetPackageList(mProcessStats);
13753        app.unlinkDeathRecipient();
13754        app.makeInactive(mProcessStats);
13755        app.waitingToKill = null;
13756        app.forcingToForeground = null;
13757        updateProcessForegroundLocked(app, false, false);
13758        app.foregroundActivities = false;
13759        app.hasShownUi = false;
13760        app.treatLikeActivity = false;
13761        app.hasAboveClient = false;
13762        app.hasClientActivities = false;
13763
13764        mServices.killServicesLocked(app, allowRestart);
13765
13766        boolean restart = false;
13767
13768        // Remove published content providers.
13769        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13770            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13771            final boolean always = app.bad || !allowRestart;
13772            if (removeDyingProviderLocked(app, cpr, always) || always) {
13773                // We left the provider in the launching list, need to
13774                // restart it.
13775                restart = true;
13776            }
13777
13778            cpr.provider = null;
13779            cpr.proc = null;
13780        }
13781        app.pubProviders.clear();
13782
13783        // Take care of any launching providers waiting for this process.
13784        if (checkAppInLaunchingProvidersLocked(app, false)) {
13785            restart = true;
13786        }
13787
13788        // Unregister from connected content providers.
13789        if (!app.conProviders.isEmpty()) {
13790            for (int i=0; i<app.conProviders.size(); i++) {
13791                ContentProviderConnection conn = app.conProviders.get(i);
13792                conn.provider.connections.remove(conn);
13793            }
13794            app.conProviders.clear();
13795        }
13796
13797        // At this point there may be remaining entries in mLaunchingProviders
13798        // where we were the only one waiting, so they are no longer of use.
13799        // Look for these and clean up if found.
13800        // XXX Commented out for now.  Trying to figure out a way to reproduce
13801        // the actual situation to identify what is actually going on.
13802        if (false) {
13803            for (int i=0; i<mLaunchingProviders.size(); i++) {
13804                ContentProviderRecord cpr = (ContentProviderRecord)
13805                        mLaunchingProviders.get(i);
13806                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13807                    synchronized (cpr) {
13808                        cpr.launchingApp = null;
13809                        cpr.notifyAll();
13810                    }
13811                }
13812            }
13813        }
13814
13815        skipCurrentReceiverLocked(app);
13816
13817        // Unregister any receivers.
13818        for (int i=app.receivers.size()-1; i>=0; i--) {
13819            removeReceiverLocked(app.receivers.valueAt(i));
13820        }
13821        app.receivers.clear();
13822
13823        // If the app is undergoing backup, tell the backup manager about it
13824        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13825            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13826                    + mBackupTarget.appInfo + " died during backup");
13827            try {
13828                IBackupManager bm = IBackupManager.Stub.asInterface(
13829                        ServiceManager.getService(Context.BACKUP_SERVICE));
13830                bm.agentDisconnected(app.info.packageName);
13831            } catch (RemoteException e) {
13832                // can't happen; backup manager is local
13833            }
13834        }
13835
13836        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13837            ProcessChangeItem item = mPendingProcessChanges.get(i);
13838            if (item.pid == app.pid) {
13839                mPendingProcessChanges.remove(i);
13840                mAvailProcessChanges.add(item);
13841            }
13842        }
13843        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13844
13845        // If the caller is restarting this app, then leave it in its
13846        // current lists and let the caller take care of it.
13847        if (restarting) {
13848            return;
13849        }
13850
13851        if (!app.persistent || app.isolated) {
13852            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13853                    "Removing non-persistent process during cleanup: " + app);
13854            mProcessNames.remove(app.processName, app.uid);
13855            mIsolatedProcesses.remove(app.uid);
13856            if (mHeavyWeightProcess == app) {
13857                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13858                        mHeavyWeightProcess.userId, 0));
13859                mHeavyWeightProcess = null;
13860            }
13861        } else if (!app.removed) {
13862            // This app is persistent, so we need to keep its record around.
13863            // If it is not already on the pending app list, add it there
13864            // and start a new process for it.
13865            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13866                mPersistentStartingProcesses.add(app);
13867                restart = true;
13868            }
13869        }
13870        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13871                "Clean-up removing on hold: " + app);
13872        mProcessesOnHold.remove(app);
13873
13874        if (app == mHomeProcess) {
13875            mHomeProcess = null;
13876        }
13877        if (app == mPreviousProcess) {
13878            mPreviousProcess = null;
13879        }
13880
13881        if (restart && !app.isolated) {
13882            // We have components that still need to be running in the
13883            // process, so re-launch it.
13884            mProcessNames.put(app.processName, app.uid, app);
13885            startProcessLocked(app, "restart", app.processName);
13886        } else if (app.pid > 0 && app.pid != MY_PID) {
13887            // Goodbye!
13888            boolean removed;
13889            synchronized (mPidsSelfLocked) {
13890                mPidsSelfLocked.remove(app.pid);
13891                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13892            }
13893            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13894            if (app.isolated) {
13895                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13896            }
13897            app.setPid(0);
13898        }
13899    }
13900
13901    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13902        // Look through the content providers we are waiting to have launched,
13903        // and if any run in this process then either schedule a restart of
13904        // the process or kill the client waiting for it if this process has
13905        // gone bad.
13906        int NL = mLaunchingProviders.size();
13907        boolean restart = false;
13908        for (int i=0; i<NL; i++) {
13909            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13910            if (cpr.launchingApp == app) {
13911                if (!alwaysBad && !app.bad) {
13912                    restart = true;
13913                } else {
13914                    removeDyingProviderLocked(app, cpr, true);
13915                    // cpr should have been removed from mLaunchingProviders
13916                    NL = mLaunchingProviders.size();
13917                    i--;
13918                }
13919            }
13920        }
13921        return restart;
13922    }
13923
13924    // =========================================================
13925    // SERVICES
13926    // =========================================================
13927
13928    @Override
13929    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13930            int flags) {
13931        enforceNotIsolatedCaller("getServices");
13932        synchronized (this) {
13933            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13934        }
13935    }
13936
13937    @Override
13938    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13939        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13940        synchronized (this) {
13941            return mServices.getRunningServiceControlPanelLocked(name);
13942        }
13943    }
13944
13945    @Override
13946    public ComponentName startService(IApplicationThread caller, Intent service,
13947            String resolvedType, int userId) {
13948        enforceNotIsolatedCaller("startService");
13949        // Refuse possible leaked file descriptors
13950        if (service != null && service.hasFileDescriptors() == true) {
13951            throw new IllegalArgumentException("File descriptors passed in Intent");
13952        }
13953
13954        if (DEBUG_SERVICE)
13955            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13956        synchronized(this) {
13957            final int callingPid = Binder.getCallingPid();
13958            final int callingUid = Binder.getCallingUid();
13959            final long origId = Binder.clearCallingIdentity();
13960            ComponentName res = mServices.startServiceLocked(caller, service,
13961                    resolvedType, callingPid, callingUid, userId);
13962            Binder.restoreCallingIdentity(origId);
13963            return res;
13964        }
13965    }
13966
13967    ComponentName startServiceInPackage(int uid,
13968            Intent service, String resolvedType, int userId) {
13969        synchronized(this) {
13970            if (DEBUG_SERVICE)
13971                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13972            final long origId = Binder.clearCallingIdentity();
13973            ComponentName res = mServices.startServiceLocked(null, service,
13974                    resolvedType, -1, uid, userId);
13975            Binder.restoreCallingIdentity(origId);
13976            return res;
13977        }
13978    }
13979
13980    @Override
13981    public int stopService(IApplicationThread caller, Intent service,
13982            String resolvedType, int userId) {
13983        enforceNotIsolatedCaller("stopService");
13984        // Refuse possible leaked file descriptors
13985        if (service != null && service.hasFileDescriptors() == true) {
13986            throw new IllegalArgumentException("File descriptors passed in Intent");
13987        }
13988
13989        synchronized(this) {
13990            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13991        }
13992    }
13993
13994    @Override
13995    public IBinder peekService(Intent service, String resolvedType) {
13996        enforceNotIsolatedCaller("peekService");
13997        // Refuse possible leaked file descriptors
13998        if (service != null && service.hasFileDescriptors() == true) {
13999            throw new IllegalArgumentException("File descriptors passed in Intent");
14000        }
14001        synchronized(this) {
14002            return mServices.peekServiceLocked(service, resolvedType);
14003        }
14004    }
14005
14006    @Override
14007    public boolean stopServiceToken(ComponentName className, IBinder token,
14008            int startId) {
14009        synchronized(this) {
14010            return mServices.stopServiceTokenLocked(className, token, startId);
14011        }
14012    }
14013
14014    @Override
14015    public void setServiceForeground(ComponentName className, IBinder token,
14016            int id, Notification notification, boolean removeNotification) {
14017        synchronized(this) {
14018            mServices.setServiceForegroundLocked(className, token, id, notification,
14019                    removeNotification);
14020        }
14021    }
14022
14023    @Override
14024    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14025            boolean requireFull, String name, String callerPackage) {
14026        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14027                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14028    }
14029
14030    int unsafeConvertIncomingUser(int userId) {
14031        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14032                ? mCurrentUserId : userId;
14033    }
14034
14035    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14036            int allowMode, String name, String callerPackage) {
14037        final int callingUserId = UserHandle.getUserId(callingUid);
14038        if (callingUserId == userId) {
14039            return userId;
14040        }
14041
14042        // Note that we may be accessing mCurrentUserId outside of a lock...
14043        // shouldn't be a big deal, if this is being called outside
14044        // of a locked context there is intrinsically a race with
14045        // the value the caller will receive and someone else changing it.
14046        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14047        // we will switch to the calling user if access to the current user fails.
14048        int targetUserId = unsafeConvertIncomingUser(userId);
14049
14050        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14051            final boolean allow;
14052            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14053                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14054                // If the caller has this permission, they always pass go.  And collect $200.
14055                allow = true;
14056            } else if (allowMode == ALLOW_FULL_ONLY) {
14057                // We require full access, sucks to be you.
14058                allow = false;
14059            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14060                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14061                // If the caller does not have either permission, they are always doomed.
14062                allow = false;
14063            } else if (allowMode == ALLOW_NON_FULL) {
14064                // We are blanket allowing non-full access, you lucky caller!
14065                allow = true;
14066            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14067                // We may or may not allow this depending on whether the two users are
14068                // in the same profile.
14069                synchronized (mUserProfileGroupIdsSelfLocked) {
14070                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14071                            UserInfo.NO_PROFILE_GROUP_ID);
14072                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14073                            UserInfo.NO_PROFILE_GROUP_ID);
14074                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14075                            && callingProfile == targetProfile;
14076                }
14077            } else {
14078                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14079            }
14080            if (!allow) {
14081                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14082                    // In this case, they would like to just execute as their
14083                    // owner user instead of failing.
14084                    targetUserId = callingUserId;
14085                } else {
14086                    StringBuilder builder = new StringBuilder(128);
14087                    builder.append("Permission Denial: ");
14088                    builder.append(name);
14089                    if (callerPackage != null) {
14090                        builder.append(" from ");
14091                        builder.append(callerPackage);
14092                    }
14093                    builder.append(" asks to run as user ");
14094                    builder.append(userId);
14095                    builder.append(" but is calling from user ");
14096                    builder.append(UserHandle.getUserId(callingUid));
14097                    builder.append("; this requires ");
14098                    builder.append(INTERACT_ACROSS_USERS_FULL);
14099                    if (allowMode != ALLOW_FULL_ONLY) {
14100                        builder.append(" or ");
14101                        builder.append(INTERACT_ACROSS_USERS);
14102                    }
14103                    String msg = builder.toString();
14104                    Slog.w(TAG, msg);
14105                    throw new SecurityException(msg);
14106                }
14107            }
14108        }
14109        if (!allowAll && targetUserId < 0) {
14110            throw new IllegalArgumentException(
14111                    "Call does not support special user #" + targetUserId);
14112        }
14113        return targetUserId;
14114    }
14115
14116    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14117            String className, int flags) {
14118        boolean result = false;
14119        // For apps that don't have pre-defined UIDs, check for permission
14120        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14121            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14122                if (ActivityManager.checkUidPermission(
14123                        INTERACT_ACROSS_USERS,
14124                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14125                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14126                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14127                            + " requests FLAG_SINGLE_USER, but app does not hold "
14128                            + INTERACT_ACROSS_USERS;
14129                    Slog.w(TAG, msg);
14130                    throw new SecurityException(msg);
14131                }
14132                // Permission passed
14133                result = true;
14134            }
14135        } else if ("system".equals(componentProcessName)) {
14136            result = true;
14137        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14138                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14139            // Phone app is allowed to export singleuser providers.
14140            result = true;
14141        } else {
14142            // App with pre-defined UID, check if it's a persistent app
14143            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14144        }
14145        if (DEBUG_MU) {
14146            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14147                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14148        }
14149        return result;
14150    }
14151
14152    /**
14153     * Checks to see if the caller is in the same app as the singleton
14154     * component, or the component is in a special app. It allows special apps
14155     * to export singleton components but prevents exporting singleton
14156     * components for regular apps.
14157     */
14158    boolean isValidSingletonCall(int callingUid, int componentUid) {
14159        int componentAppId = UserHandle.getAppId(componentUid);
14160        return UserHandle.isSameApp(callingUid, componentUid)
14161                || componentAppId == Process.SYSTEM_UID
14162                || componentAppId == Process.PHONE_UID
14163                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14164                        == PackageManager.PERMISSION_GRANTED;
14165    }
14166
14167    public int bindService(IApplicationThread caller, IBinder token,
14168            Intent service, String resolvedType,
14169            IServiceConnection connection, int flags, int userId) {
14170        enforceNotIsolatedCaller("bindService");
14171        // Refuse possible leaked file descriptors
14172        if (service != null && service.hasFileDescriptors() == true) {
14173            throw new IllegalArgumentException("File descriptors passed in Intent");
14174        }
14175
14176        synchronized(this) {
14177            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14178                    connection, flags, userId);
14179        }
14180    }
14181
14182    public boolean unbindService(IServiceConnection connection) {
14183        synchronized (this) {
14184            return mServices.unbindServiceLocked(connection);
14185        }
14186    }
14187
14188    public void publishService(IBinder token, Intent intent, IBinder service) {
14189        // Refuse possible leaked file descriptors
14190        if (intent != null && intent.hasFileDescriptors() == true) {
14191            throw new IllegalArgumentException("File descriptors passed in Intent");
14192        }
14193
14194        synchronized(this) {
14195            if (!(token instanceof ServiceRecord)) {
14196                throw new IllegalArgumentException("Invalid service token");
14197            }
14198            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14199        }
14200    }
14201
14202    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14203        // Refuse possible leaked file descriptors
14204        if (intent != null && intent.hasFileDescriptors() == true) {
14205            throw new IllegalArgumentException("File descriptors passed in Intent");
14206        }
14207
14208        synchronized(this) {
14209            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14210        }
14211    }
14212
14213    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14214        synchronized(this) {
14215            if (!(token instanceof ServiceRecord)) {
14216                throw new IllegalArgumentException("Invalid service token");
14217            }
14218            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14219        }
14220    }
14221
14222    // =========================================================
14223    // BACKUP AND RESTORE
14224    // =========================================================
14225
14226    // Cause the target app to be launched if necessary and its backup agent
14227    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14228    // activity manager to announce its creation.
14229    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14230        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14231        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14232
14233        synchronized(this) {
14234            // !!! TODO: currently no check here that we're already bound
14235            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14236            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14237            synchronized (stats) {
14238                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14239            }
14240
14241            // Backup agent is now in use, its package can't be stopped.
14242            try {
14243                AppGlobals.getPackageManager().setPackageStoppedState(
14244                        app.packageName, false, UserHandle.getUserId(app.uid));
14245            } catch (RemoteException e) {
14246            } catch (IllegalArgumentException e) {
14247                Slog.w(TAG, "Failed trying to unstop package "
14248                        + app.packageName + ": " + e);
14249            }
14250
14251            BackupRecord r = new BackupRecord(ss, app, backupMode);
14252            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14253                    ? new ComponentName(app.packageName, app.backupAgentName)
14254                    : new ComponentName("android", "FullBackupAgent");
14255            // startProcessLocked() returns existing proc's record if it's already running
14256            ProcessRecord proc = startProcessLocked(app.processName, app,
14257                    false, 0, "backup", hostingName, false, false, false);
14258            if (proc == null) {
14259                Slog.e(TAG, "Unable to start backup agent process " + r);
14260                return false;
14261            }
14262
14263            r.app = proc;
14264            mBackupTarget = r;
14265            mBackupAppName = app.packageName;
14266
14267            // Try not to kill the process during backup
14268            updateOomAdjLocked(proc);
14269
14270            // If the process is already attached, schedule the creation of the backup agent now.
14271            // If it is not yet live, this will be done when it attaches to the framework.
14272            if (proc.thread != null) {
14273                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14274                try {
14275                    proc.thread.scheduleCreateBackupAgent(app,
14276                            compatibilityInfoForPackageLocked(app), backupMode);
14277                } catch (RemoteException e) {
14278                    // Will time out on the backup manager side
14279                }
14280            } else {
14281                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14282            }
14283            // Invariants: at this point, the target app process exists and the application
14284            // is either already running or in the process of coming up.  mBackupTarget and
14285            // mBackupAppName describe the app, so that when it binds back to the AM we
14286            // know that it's scheduled for a backup-agent operation.
14287        }
14288
14289        return true;
14290    }
14291
14292    @Override
14293    public void clearPendingBackup() {
14294        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14295        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14296
14297        synchronized (this) {
14298            mBackupTarget = null;
14299            mBackupAppName = null;
14300        }
14301    }
14302
14303    // A backup agent has just come up
14304    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14305        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14306                + " = " + agent);
14307
14308        synchronized(this) {
14309            if (!agentPackageName.equals(mBackupAppName)) {
14310                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14311                return;
14312            }
14313        }
14314
14315        long oldIdent = Binder.clearCallingIdentity();
14316        try {
14317            IBackupManager bm = IBackupManager.Stub.asInterface(
14318                    ServiceManager.getService(Context.BACKUP_SERVICE));
14319            bm.agentConnected(agentPackageName, agent);
14320        } catch (RemoteException e) {
14321            // can't happen; the backup manager service is local
14322        } catch (Exception e) {
14323            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14324            e.printStackTrace();
14325        } finally {
14326            Binder.restoreCallingIdentity(oldIdent);
14327        }
14328    }
14329
14330    // done with this agent
14331    public void unbindBackupAgent(ApplicationInfo appInfo) {
14332        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14333        if (appInfo == null) {
14334            Slog.w(TAG, "unbind backup agent for null app");
14335            return;
14336        }
14337
14338        synchronized(this) {
14339            try {
14340                if (mBackupAppName == null) {
14341                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14342                    return;
14343                }
14344
14345                if (!mBackupAppName.equals(appInfo.packageName)) {
14346                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14347                    return;
14348                }
14349
14350                // Not backing this app up any more; reset its OOM adjustment
14351                final ProcessRecord proc = mBackupTarget.app;
14352                updateOomAdjLocked(proc);
14353
14354                // If the app crashed during backup, 'thread' will be null here
14355                if (proc.thread != null) {
14356                    try {
14357                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14358                                compatibilityInfoForPackageLocked(appInfo));
14359                    } catch (Exception e) {
14360                        Slog.e(TAG, "Exception when unbinding backup agent:");
14361                        e.printStackTrace();
14362                    }
14363                }
14364            } finally {
14365                mBackupTarget = null;
14366                mBackupAppName = null;
14367            }
14368        }
14369    }
14370    // =========================================================
14371    // BROADCASTS
14372    // =========================================================
14373
14374    private final List getStickiesLocked(String action, IntentFilter filter,
14375            List cur, int userId) {
14376        final ContentResolver resolver = mContext.getContentResolver();
14377        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14378        if (stickies == null) {
14379            return cur;
14380        }
14381        final ArrayList<Intent> list = stickies.get(action);
14382        if (list == null) {
14383            return cur;
14384        }
14385        int N = list.size();
14386        for (int i=0; i<N; i++) {
14387            Intent intent = list.get(i);
14388            if (filter.match(resolver, intent, true, TAG) >= 0) {
14389                if (cur == null) {
14390                    cur = new ArrayList<Intent>();
14391                }
14392                cur.add(intent);
14393            }
14394        }
14395        return cur;
14396    }
14397
14398    boolean isPendingBroadcastProcessLocked(int pid) {
14399        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14400                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14401    }
14402
14403    void skipPendingBroadcastLocked(int pid) {
14404            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14405            for (BroadcastQueue queue : mBroadcastQueues) {
14406                queue.skipPendingBroadcastLocked(pid);
14407            }
14408    }
14409
14410    // The app just attached; send any pending broadcasts that it should receive
14411    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14412        boolean didSomething = false;
14413        for (BroadcastQueue queue : mBroadcastQueues) {
14414            didSomething |= queue.sendPendingBroadcastsLocked(app);
14415        }
14416        return didSomething;
14417    }
14418
14419    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14420            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14421        enforceNotIsolatedCaller("registerReceiver");
14422        int callingUid;
14423        int callingPid;
14424        synchronized(this) {
14425            ProcessRecord callerApp = null;
14426            if (caller != null) {
14427                callerApp = getRecordForAppLocked(caller);
14428                if (callerApp == null) {
14429                    throw new SecurityException(
14430                            "Unable to find app for caller " + caller
14431                            + " (pid=" + Binder.getCallingPid()
14432                            + ") when registering receiver " + receiver);
14433                }
14434                if (callerApp.info.uid != Process.SYSTEM_UID &&
14435                        !callerApp.pkgList.containsKey(callerPackage) &&
14436                        !"android".equals(callerPackage)) {
14437                    throw new SecurityException("Given caller package " + callerPackage
14438                            + " is not running in process " + callerApp);
14439                }
14440                callingUid = callerApp.info.uid;
14441                callingPid = callerApp.pid;
14442            } else {
14443                callerPackage = null;
14444                callingUid = Binder.getCallingUid();
14445                callingPid = Binder.getCallingPid();
14446            }
14447
14448            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14449                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14450
14451            List allSticky = null;
14452
14453            // Look for any matching sticky broadcasts...
14454            Iterator actions = filter.actionsIterator();
14455            if (actions != null) {
14456                while (actions.hasNext()) {
14457                    String action = (String)actions.next();
14458                    allSticky = getStickiesLocked(action, filter, allSticky,
14459                            UserHandle.USER_ALL);
14460                    allSticky = getStickiesLocked(action, filter, allSticky,
14461                            UserHandle.getUserId(callingUid));
14462                }
14463            } else {
14464                allSticky = getStickiesLocked(null, filter, allSticky,
14465                        UserHandle.USER_ALL);
14466                allSticky = getStickiesLocked(null, filter, allSticky,
14467                        UserHandle.getUserId(callingUid));
14468            }
14469
14470            // The first sticky in the list is returned directly back to
14471            // the client.
14472            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14473
14474            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14475                    + ": " + sticky);
14476
14477            if (receiver == null) {
14478                return sticky;
14479            }
14480
14481            ReceiverList rl
14482                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14483            if (rl == null) {
14484                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14485                        userId, receiver);
14486                if (rl.app != null) {
14487                    rl.app.receivers.add(rl);
14488                } else {
14489                    try {
14490                        receiver.asBinder().linkToDeath(rl, 0);
14491                    } catch (RemoteException e) {
14492                        return sticky;
14493                    }
14494                    rl.linkedToDeath = true;
14495                }
14496                mRegisteredReceivers.put(receiver.asBinder(), rl);
14497            } else if (rl.uid != callingUid) {
14498                throw new IllegalArgumentException(
14499                        "Receiver requested to register for uid " + callingUid
14500                        + " was previously registered for uid " + rl.uid);
14501            } else if (rl.pid != callingPid) {
14502                throw new IllegalArgumentException(
14503                        "Receiver requested to register for pid " + callingPid
14504                        + " was previously registered for pid " + rl.pid);
14505            } else if (rl.userId != userId) {
14506                throw new IllegalArgumentException(
14507                        "Receiver requested to register for user " + userId
14508                        + " was previously registered for user " + rl.userId);
14509            }
14510            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14511                    permission, callingUid, userId);
14512            rl.add(bf);
14513            if (!bf.debugCheck()) {
14514                Slog.w(TAG, "==> For Dynamic broadast");
14515            }
14516            mReceiverResolver.addFilter(bf);
14517
14518            // Enqueue broadcasts for all existing stickies that match
14519            // this filter.
14520            if (allSticky != null) {
14521                ArrayList receivers = new ArrayList();
14522                receivers.add(bf);
14523
14524                int N = allSticky.size();
14525                for (int i=0; i<N; i++) {
14526                    Intent intent = (Intent)allSticky.get(i);
14527                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14528                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14529                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14530                            null, null, false, true, true, -1);
14531                    queue.enqueueParallelBroadcastLocked(r);
14532                    queue.scheduleBroadcastsLocked();
14533                }
14534            }
14535
14536            return sticky;
14537        }
14538    }
14539
14540    public void unregisterReceiver(IIntentReceiver receiver) {
14541        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14542
14543        final long origId = Binder.clearCallingIdentity();
14544        try {
14545            boolean doTrim = false;
14546
14547            synchronized(this) {
14548                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14549                if (rl != null) {
14550                    if (rl.curBroadcast != null) {
14551                        BroadcastRecord r = rl.curBroadcast;
14552                        final boolean doNext = finishReceiverLocked(
14553                                receiver.asBinder(), r.resultCode, r.resultData,
14554                                r.resultExtras, r.resultAbort);
14555                        if (doNext) {
14556                            doTrim = true;
14557                            r.queue.processNextBroadcast(false);
14558                        }
14559                    }
14560
14561                    if (rl.app != null) {
14562                        rl.app.receivers.remove(rl);
14563                    }
14564                    removeReceiverLocked(rl);
14565                    if (rl.linkedToDeath) {
14566                        rl.linkedToDeath = false;
14567                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14568                    }
14569                }
14570            }
14571
14572            // If we actually concluded any broadcasts, we might now be able
14573            // to trim the recipients' apps from our working set
14574            if (doTrim) {
14575                trimApplications();
14576                return;
14577            }
14578
14579        } finally {
14580            Binder.restoreCallingIdentity(origId);
14581        }
14582    }
14583
14584    void removeReceiverLocked(ReceiverList rl) {
14585        mRegisteredReceivers.remove(rl.receiver.asBinder());
14586        int N = rl.size();
14587        for (int i=0; i<N; i++) {
14588            mReceiverResolver.removeFilter(rl.get(i));
14589        }
14590    }
14591
14592    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14593        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14594            ProcessRecord r = mLruProcesses.get(i);
14595            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14596                try {
14597                    r.thread.dispatchPackageBroadcast(cmd, packages);
14598                } catch (RemoteException ex) {
14599                }
14600            }
14601        }
14602    }
14603
14604    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14605            int[] users) {
14606        List<ResolveInfo> receivers = null;
14607        try {
14608            HashSet<ComponentName> singleUserReceivers = null;
14609            boolean scannedFirstReceivers = false;
14610            for (int user : users) {
14611                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14612                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14613                if (user != 0 && newReceivers != null) {
14614                    // If this is not the primary user, we need to check for
14615                    // any receivers that should be filtered out.
14616                    for (int i=0; i<newReceivers.size(); i++) {
14617                        ResolveInfo ri = newReceivers.get(i);
14618                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14619                            newReceivers.remove(i);
14620                            i--;
14621                        }
14622                    }
14623                }
14624                if (newReceivers != null && newReceivers.size() == 0) {
14625                    newReceivers = null;
14626                }
14627                if (receivers == null) {
14628                    receivers = newReceivers;
14629                } else if (newReceivers != null) {
14630                    // We need to concatenate the additional receivers
14631                    // found with what we have do far.  This would be easy,
14632                    // but we also need to de-dup any receivers that are
14633                    // singleUser.
14634                    if (!scannedFirstReceivers) {
14635                        // Collect any single user receivers we had already retrieved.
14636                        scannedFirstReceivers = true;
14637                        for (int i=0; i<receivers.size(); i++) {
14638                            ResolveInfo ri = receivers.get(i);
14639                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14640                                ComponentName cn = new ComponentName(
14641                                        ri.activityInfo.packageName, ri.activityInfo.name);
14642                                if (singleUserReceivers == null) {
14643                                    singleUserReceivers = new HashSet<ComponentName>();
14644                                }
14645                                singleUserReceivers.add(cn);
14646                            }
14647                        }
14648                    }
14649                    // Add the new results to the existing results, tracking
14650                    // and de-dupping single user receivers.
14651                    for (int i=0; i<newReceivers.size(); i++) {
14652                        ResolveInfo ri = newReceivers.get(i);
14653                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14654                            ComponentName cn = new ComponentName(
14655                                    ri.activityInfo.packageName, ri.activityInfo.name);
14656                            if (singleUserReceivers == null) {
14657                                singleUserReceivers = new HashSet<ComponentName>();
14658                            }
14659                            if (!singleUserReceivers.contains(cn)) {
14660                                singleUserReceivers.add(cn);
14661                                receivers.add(ri);
14662                            }
14663                        } else {
14664                            receivers.add(ri);
14665                        }
14666                    }
14667                }
14668            }
14669        } catch (RemoteException ex) {
14670            // pm is in same process, this will never happen.
14671        }
14672        return receivers;
14673    }
14674
14675    private final int broadcastIntentLocked(ProcessRecord callerApp,
14676            String callerPackage, Intent intent, String resolvedType,
14677            IIntentReceiver resultTo, int resultCode, String resultData,
14678            Bundle map, String requiredPermission, int appOp,
14679            boolean ordered, boolean sticky, int callingPid, int callingUid,
14680            int userId) {
14681        intent = new Intent(intent);
14682
14683        // By default broadcasts do not go to stopped apps.
14684        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14685
14686        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14687            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14688            + " ordered=" + ordered + " userid=" + userId);
14689        if ((resultTo != null) && !ordered) {
14690            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14691        }
14692
14693        userId = handleIncomingUser(callingPid, callingUid, userId,
14694                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14695
14696        // Make sure that the user who is receiving this broadcast is started.
14697        // If not, we will just skip it.
14698
14699
14700        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14701            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14702                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14703                Slog.w(TAG, "Skipping broadcast of " + intent
14704                        + ": user " + userId + " is stopped");
14705                return ActivityManager.BROADCAST_SUCCESS;
14706            }
14707        }
14708
14709        /*
14710         * Prevent non-system code (defined here to be non-persistent
14711         * processes) from sending protected broadcasts.
14712         */
14713        int callingAppId = UserHandle.getAppId(callingUid);
14714        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14715            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14716            || callingAppId == Process.NFC_UID || callingUid == 0) {
14717            // Always okay.
14718        } else if (callerApp == null || !callerApp.persistent) {
14719            try {
14720                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14721                        intent.getAction())) {
14722                    String msg = "Permission Denial: not allowed to send broadcast "
14723                            + intent.getAction() + " from pid="
14724                            + callingPid + ", uid=" + callingUid;
14725                    Slog.w(TAG, msg);
14726                    throw new SecurityException(msg);
14727                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14728                    // Special case for compatibility: we don't want apps to send this,
14729                    // but historically it has not been protected and apps may be using it
14730                    // to poke their own app widget.  So, instead of making it protected,
14731                    // just limit it to the caller.
14732                    if (callerApp == null) {
14733                        String msg = "Permission Denial: not allowed to send broadcast "
14734                                + intent.getAction() + " from unknown caller.";
14735                        Slog.w(TAG, msg);
14736                        throw new SecurityException(msg);
14737                    } else if (intent.getComponent() != null) {
14738                        // They are good enough to send to an explicit component...  verify
14739                        // it is being sent to the calling app.
14740                        if (!intent.getComponent().getPackageName().equals(
14741                                callerApp.info.packageName)) {
14742                            String msg = "Permission Denial: not allowed to send broadcast "
14743                                    + intent.getAction() + " to "
14744                                    + intent.getComponent().getPackageName() + " from "
14745                                    + callerApp.info.packageName;
14746                            Slog.w(TAG, msg);
14747                            throw new SecurityException(msg);
14748                        }
14749                    } else {
14750                        // Limit broadcast to their own package.
14751                        intent.setPackage(callerApp.info.packageName);
14752                    }
14753                }
14754            } catch (RemoteException e) {
14755                Slog.w(TAG, "Remote exception", e);
14756                return ActivityManager.BROADCAST_SUCCESS;
14757            }
14758        }
14759
14760        // Handle special intents: if this broadcast is from the package
14761        // manager about a package being removed, we need to remove all of
14762        // its activities from the history stack.
14763        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14764                intent.getAction());
14765        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14766                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14767                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14768                || uidRemoved) {
14769            if (checkComponentPermission(
14770                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14771                    callingPid, callingUid, -1, true)
14772                    == PackageManager.PERMISSION_GRANTED) {
14773                if (uidRemoved) {
14774                    final Bundle intentExtras = intent.getExtras();
14775                    final int uid = intentExtras != null
14776                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14777                    if (uid >= 0) {
14778                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14779                        synchronized (bs) {
14780                            bs.removeUidStatsLocked(uid);
14781                        }
14782                        mAppOpsService.uidRemoved(uid);
14783                    }
14784                } else {
14785                    // If resources are unavailable just force stop all
14786                    // those packages and flush the attribute cache as well.
14787                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14788                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14789                        if (list != null && (list.length > 0)) {
14790                            for (String pkg : list) {
14791                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14792                                        "storage unmount");
14793                            }
14794                            sendPackageBroadcastLocked(
14795                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14796                        }
14797                    } else {
14798                        Uri data = intent.getData();
14799                        String ssp;
14800                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14801                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14802                                    intent.getAction());
14803                            boolean fullUninstall = removed &&
14804                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14805                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14806                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14807                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14808                                        false, fullUninstall, userId,
14809                                        removed ? "pkg removed" : "pkg changed");
14810                            }
14811                            if (removed) {
14812                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14813                                        new String[] {ssp}, userId);
14814                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14815                                    mAppOpsService.packageRemoved(
14816                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14817
14818                                    // Remove all permissions granted from/to this package
14819                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14820                                }
14821                            }
14822                        }
14823                    }
14824                }
14825            } else {
14826                String msg = "Permission Denial: " + intent.getAction()
14827                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14828                        + ", uid=" + callingUid + ")"
14829                        + " requires "
14830                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14831                Slog.w(TAG, msg);
14832                throw new SecurityException(msg);
14833            }
14834
14835        // Special case for adding a package: by default turn on compatibility
14836        // mode.
14837        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14838            Uri data = intent.getData();
14839            String ssp;
14840            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14841                mCompatModePackages.handlePackageAddedLocked(ssp,
14842                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14843            }
14844        }
14845
14846        /*
14847         * If this is the time zone changed action, queue up a message that will reset the timezone
14848         * of all currently running processes. This message will get queued up before the broadcast
14849         * happens.
14850         */
14851        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14852            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14853        }
14854
14855        /*
14856         * If the user set the time, let all running processes know.
14857         */
14858        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14859            final int is24Hour = intent.getBooleanExtra(
14860                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14861            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14862        }
14863
14864        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14865            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14866        }
14867
14868        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14869            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14870            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14871        }
14872
14873        // Add to the sticky list if requested.
14874        if (sticky) {
14875            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14876                    callingPid, callingUid)
14877                    != PackageManager.PERMISSION_GRANTED) {
14878                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14879                        + callingPid + ", uid=" + callingUid
14880                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14881                Slog.w(TAG, msg);
14882                throw new SecurityException(msg);
14883            }
14884            if (requiredPermission != null) {
14885                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14886                        + " and enforce permission " + requiredPermission);
14887                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14888            }
14889            if (intent.getComponent() != null) {
14890                throw new SecurityException(
14891                        "Sticky broadcasts can't target a specific component");
14892            }
14893            // We use userId directly here, since the "all" target is maintained
14894            // as a separate set of sticky broadcasts.
14895            if (userId != UserHandle.USER_ALL) {
14896                // But first, if this is not a broadcast to all users, then
14897                // make sure it doesn't conflict with an existing broadcast to
14898                // all users.
14899                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14900                        UserHandle.USER_ALL);
14901                if (stickies != null) {
14902                    ArrayList<Intent> list = stickies.get(intent.getAction());
14903                    if (list != null) {
14904                        int N = list.size();
14905                        int i;
14906                        for (i=0; i<N; i++) {
14907                            if (intent.filterEquals(list.get(i))) {
14908                                throw new IllegalArgumentException(
14909                                        "Sticky broadcast " + intent + " for user "
14910                                        + userId + " conflicts with existing global broadcast");
14911                            }
14912                        }
14913                    }
14914                }
14915            }
14916            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14917            if (stickies == null) {
14918                stickies = new ArrayMap<String, ArrayList<Intent>>();
14919                mStickyBroadcasts.put(userId, stickies);
14920            }
14921            ArrayList<Intent> list = stickies.get(intent.getAction());
14922            if (list == null) {
14923                list = new ArrayList<Intent>();
14924                stickies.put(intent.getAction(), list);
14925            }
14926            int N = list.size();
14927            int i;
14928            for (i=0; i<N; i++) {
14929                if (intent.filterEquals(list.get(i))) {
14930                    // This sticky already exists, replace it.
14931                    list.set(i, new Intent(intent));
14932                    break;
14933                }
14934            }
14935            if (i >= N) {
14936                list.add(new Intent(intent));
14937            }
14938        }
14939
14940        int[] users;
14941        if (userId == UserHandle.USER_ALL) {
14942            // Caller wants broadcast to go to all started users.
14943            users = mStartedUserArray;
14944        } else {
14945            // Caller wants broadcast to go to one specific user.
14946            users = new int[] {userId};
14947        }
14948
14949        // Figure out who all will receive this broadcast.
14950        List receivers = null;
14951        List<BroadcastFilter> registeredReceivers = null;
14952        // Need to resolve the intent to interested receivers...
14953        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14954                 == 0) {
14955            receivers = collectReceiverComponents(intent, resolvedType, users);
14956        }
14957        if (intent.getComponent() == null) {
14958            registeredReceivers = mReceiverResolver.queryIntent(intent,
14959                    resolvedType, false, userId);
14960        }
14961
14962        final boolean replacePending =
14963                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14964
14965        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14966                + " replacePending=" + replacePending);
14967
14968        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14969        if (!ordered && NR > 0) {
14970            // If we are not serializing this broadcast, then send the
14971            // registered receivers separately so they don't wait for the
14972            // components to be launched.
14973            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14974            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14975                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14976                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14977                    ordered, sticky, false, userId);
14978            if (DEBUG_BROADCAST) Slog.v(
14979                    TAG, "Enqueueing parallel broadcast " + r);
14980            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14981            if (!replaced) {
14982                queue.enqueueParallelBroadcastLocked(r);
14983                queue.scheduleBroadcastsLocked();
14984            }
14985            registeredReceivers = null;
14986            NR = 0;
14987        }
14988
14989        // Merge into one list.
14990        int ir = 0;
14991        if (receivers != null) {
14992            // A special case for PACKAGE_ADDED: do not allow the package
14993            // being added to see this broadcast.  This prevents them from
14994            // using this as a back door to get run as soon as they are
14995            // installed.  Maybe in the future we want to have a special install
14996            // broadcast or such for apps, but we'd like to deliberately make
14997            // this decision.
14998            String skipPackages[] = null;
14999            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15000                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15001                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15002                Uri data = intent.getData();
15003                if (data != null) {
15004                    String pkgName = data.getSchemeSpecificPart();
15005                    if (pkgName != null) {
15006                        skipPackages = new String[] { pkgName };
15007                    }
15008                }
15009            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15010                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15011            }
15012            if (skipPackages != null && (skipPackages.length > 0)) {
15013                for (String skipPackage : skipPackages) {
15014                    if (skipPackage != null) {
15015                        int NT = receivers.size();
15016                        for (int it=0; it<NT; it++) {
15017                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15018                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15019                                receivers.remove(it);
15020                                it--;
15021                                NT--;
15022                            }
15023                        }
15024                    }
15025                }
15026            }
15027
15028            int NT = receivers != null ? receivers.size() : 0;
15029            int it = 0;
15030            ResolveInfo curt = null;
15031            BroadcastFilter curr = null;
15032            while (it < NT && ir < NR) {
15033                if (curt == null) {
15034                    curt = (ResolveInfo)receivers.get(it);
15035                }
15036                if (curr == null) {
15037                    curr = registeredReceivers.get(ir);
15038                }
15039                if (curr.getPriority() >= curt.priority) {
15040                    // Insert this broadcast record into the final list.
15041                    receivers.add(it, curr);
15042                    ir++;
15043                    curr = null;
15044                    it++;
15045                    NT++;
15046                } else {
15047                    // Skip to the next ResolveInfo in the final list.
15048                    it++;
15049                    curt = null;
15050                }
15051            }
15052        }
15053        while (ir < NR) {
15054            if (receivers == null) {
15055                receivers = new ArrayList();
15056            }
15057            receivers.add(registeredReceivers.get(ir));
15058            ir++;
15059        }
15060
15061        if ((receivers != null && receivers.size() > 0)
15062                || resultTo != null) {
15063            BroadcastQueue queue = broadcastQueueForIntent(intent);
15064            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15065                    callerPackage, callingPid, callingUid, resolvedType,
15066                    requiredPermission, appOp, receivers, resultTo, resultCode,
15067                    resultData, map, ordered, sticky, false, userId);
15068            if (DEBUG_BROADCAST) Slog.v(
15069                    TAG, "Enqueueing ordered broadcast " + r
15070                    + ": prev had " + queue.mOrderedBroadcasts.size());
15071            if (DEBUG_BROADCAST) {
15072                int seq = r.intent.getIntExtra("seq", -1);
15073                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15074            }
15075            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15076            if (!replaced) {
15077                queue.enqueueOrderedBroadcastLocked(r);
15078                queue.scheduleBroadcastsLocked();
15079            }
15080        }
15081
15082        return ActivityManager.BROADCAST_SUCCESS;
15083    }
15084
15085    final Intent verifyBroadcastLocked(Intent intent) {
15086        // Refuse possible leaked file descriptors
15087        if (intent != null && intent.hasFileDescriptors() == true) {
15088            throw new IllegalArgumentException("File descriptors passed in Intent");
15089        }
15090
15091        int flags = intent.getFlags();
15092
15093        if (!mProcessesReady) {
15094            // if the caller really truly claims to know what they're doing, go
15095            // ahead and allow the broadcast without launching any receivers
15096            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15097                intent = new Intent(intent);
15098                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15099            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15100                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15101                        + " before boot completion");
15102                throw new IllegalStateException("Cannot broadcast before boot completed");
15103            }
15104        }
15105
15106        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15107            throw new IllegalArgumentException(
15108                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15109        }
15110
15111        return intent;
15112    }
15113
15114    public final int broadcastIntent(IApplicationThread caller,
15115            Intent intent, String resolvedType, IIntentReceiver resultTo,
15116            int resultCode, String resultData, Bundle map,
15117            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15118        enforceNotIsolatedCaller("broadcastIntent");
15119        synchronized(this) {
15120            intent = verifyBroadcastLocked(intent);
15121
15122            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15123            final int callingPid = Binder.getCallingPid();
15124            final int callingUid = Binder.getCallingUid();
15125            final long origId = Binder.clearCallingIdentity();
15126            int res = broadcastIntentLocked(callerApp,
15127                    callerApp != null ? callerApp.info.packageName : null,
15128                    intent, resolvedType, resultTo,
15129                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15130                    callingPid, callingUid, userId);
15131            Binder.restoreCallingIdentity(origId);
15132            return res;
15133        }
15134    }
15135
15136    int broadcastIntentInPackage(String packageName, int uid,
15137            Intent intent, String resolvedType, IIntentReceiver resultTo,
15138            int resultCode, String resultData, Bundle map,
15139            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15140        synchronized(this) {
15141            intent = verifyBroadcastLocked(intent);
15142
15143            final long origId = Binder.clearCallingIdentity();
15144            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15145                    resultTo, resultCode, resultData, map, requiredPermission,
15146                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15147            Binder.restoreCallingIdentity(origId);
15148            return res;
15149        }
15150    }
15151
15152    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15153        // Refuse possible leaked file descriptors
15154        if (intent != null && intent.hasFileDescriptors() == true) {
15155            throw new IllegalArgumentException("File descriptors passed in Intent");
15156        }
15157
15158        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15159                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15160
15161        synchronized(this) {
15162            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15163                    != PackageManager.PERMISSION_GRANTED) {
15164                String msg = "Permission Denial: unbroadcastIntent() from pid="
15165                        + Binder.getCallingPid()
15166                        + ", uid=" + Binder.getCallingUid()
15167                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15168                Slog.w(TAG, msg);
15169                throw new SecurityException(msg);
15170            }
15171            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15172            if (stickies != null) {
15173                ArrayList<Intent> list = stickies.get(intent.getAction());
15174                if (list != null) {
15175                    int N = list.size();
15176                    int i;
15177                    for (i=0; i<N; i++) {
15178                        if (intent.filterEquals(list.get(i))) {
15179                            list.remove(i);
15180                            break;
15181                        }
15182                    }
15183                    if (list.size() <= 0) {
15184                        stickies.remove(intent.getAction());
15185                    }
15186                }
15187                if (stickies.size() <= 0) {
15188                    mStickyBroadcasts.remove(userId);
15189                }
15190            }
15191        }
15192    }
15193
15194    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15195            String resultData, Bundle resultExtras, boolean resultAbort) {
15196        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15197        if (r == null) {
15198            Slog.w(TAG, "finishReceiver called but not found on queue");
15199            return false;
15200        }
15201
15202        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15203    }
15204
15205    void backgroundServicesFinishedLocked(int userId) {
15206        for (BroadcastQueue queue : mBroadcastQueues) {
15207            queue.backgroundServicesFinishedLocked(userId);
15208        }
15209    }
15210
15211    public void finishReceiver(IBinder who, int resultCode, String resultData,
15212            Bundle resultExtras, boolean resultAbort) {
15213        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15214
15215        // Refuse possible leaked file descriptors
15216        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15217            throw new IllegalArgumentException("File descriptors passed in Bundle");
15218        }
15219
15220        final long origId = Binder.clearCallingIdentity();
15221        try {
15222            boolean doNext = false;
15223            BroadcastRecord r;
15224
15225            synchronized(this) {
15226                r = broadcastRecordForReceiverLocked(who);
15227                if (r != null) {
15228                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15229                        resultData, resultExtras, resultAbort, true);
15230                }
15231            }
15232
15233            if (doNext) {
15234                r.queue.processNextBroadcast(false);
15235            }
15236            trimApplications();
15237        } finally {
15238            Binder.restoreCallingIdentity(origId);
15239        }
15240    }
15241
15242    // =========================================================
15243    // INSTRUMENTATION
15244    // =========================================================
15245
15246    public boolean startInstrumentation(ComponentName className,
15247            String profileFile, int flags, Bundle arguments,
15248            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15249            int userId, String abiOverride) {
15250        enforceNotIsolatedCaller("startInstrumentation");
15251        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15252                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15253        // Refuse possible leaked file descriptors
15254        if (arguments != null && arguments.hasFileDescriptors()) {
15255            throw new IllegalArgumentException("File descriptors passed in Bundle");
15256        }
15257
15258        synchronized(this) {
15259            InstrumentationInfo ii = null;
15260            ApplicationInfo ai = null;
15261            try {
15262                ii = mContext.getPackageManager().getInstrumentationInfo(
15263                    className, STOCK_PM_FLAGS);
15264                ai = AppGlobals.getPackageManager().getApplicationInfo(
15265                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15266            } catch (PackageManager.NameNotFoundException e) {
15267            } catch (RemoteException e) {
15268            }
15269            if (ii == null) {
15270                reportStartInstrumentationFailure(watcher, className,
15271                        "Unable to find instrumentation info for: " + className);
15272                return false;
15273            }
15274            if (ai == null) {
15275                reportStartInstrumentationFailure(watcher, className,
15276                        "Unable to find instrumentation target package: " + ii.targetPackage);
15277                return false;
15278            }
15279
15280            int match = mContext.getPackageManager().checkSignatures(
15281                    ii.targetPackage, ii.packageName);
15282            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15283                String msg = "Permission Denial: starting instrumentation "
15284                        + className + " from pid="
15285                        + Binder.getCallingPid()
15286                        + ", uid=" + Binder.getCallingPid()
15287                        + " not allowed because package " + ii.packageName
15288                        + " does not have a signature matching the target "
15289                        + ii.targetPackage;
15290                reportStartInstrumentationFailure(watcher, className, msg);
15291                throw new SecurityException(msg);
15292            }
15293
15294            final long origId = Binder.clearCallingIdentity();
15295            // Instrumentation can kill and relaunch even persistent processes
15296            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15297                    "start instr");
15298            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15299            app.instrumentationClass = className;
15300            app.instrumentationInfo = ai;
15301            app.instrumentationProfileFile = profileFile;
15302            app.instrumentationArguments = arguments;
15303            app.instrumentationWatcher = watcher;
15304            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15305            app.instrumentationResultClass = className;
15306            Binder.restoreCallingIdentity(origId);
15307        }
15308
15309        return true;
15310    }
15311
15312    /**
15313     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15314     * error to the logs, but if somebody is watching, send the report there too.  This enables
15315     * the "am" command to report errors with more information.
15316     *
15317     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15318     * @param cn The component name of the instrumentation.
15319     * @param report The error report.
15320     */
15321    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15322            ComponentName cn, String report) {
15323        Slog.w(TAG, report);
15324        try {
15325            if (watcher != null) {
15326                Bundle results = new Bundle();
15327                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15328                results.putString("Error", report);
15329                watcher.instrumentationStatus(cn, -1, results);
15330            }
15331        } catch (RemoteException e) {
15332            Slog.w(TAG, e);
15333        }
15334    }
15335
15336    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15337        if (app.instrumentationWatcher != null) {
15338            try {
15339                // NOTE:  IInstrumentationWatcher *must* be oneway here
15340                app.instrumentationWatcher.instrumentationFinished(
15341                    app.instrumentationClass,
15342                    resultCode,
15343                    results);
15344            } catch (RemoteException e) {
15345            }
15346        }
15347        if (app.instrumentationUiAutomationConnection != null) {
15348            try {
15349                app.instrumentationUiAutomationConnection.shutdown();
15350            } catch (RemoteException re) {
15351                /* ignore */
15352            }
15353            // Only a UiAutomation can set this flag and now that
15354            // it is finished we make sure it is reset to its default.
15355            mUserIsMonkey = false;
15356        }
15357        app.instrumentationWatcher = null;
15358        app.instrumentationUiAutomationConnection = null;
15359        app.instrumentationClass = null;
15360        app.instrumentationInfo = null;
15361        app.instrumentationProfileFile = null;
15362        app.instrumentationArguments = null;
15363
15364        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15365                "finished inst");
15366    }
15367
15368    public void finishInstrumentation(IApplicationThread target,
15369            int resultCode, Bundle results) {
15370        int userId = UserHandle.getCallingUserId();
15371        // Refuse possible leaked file descriptors
15372        if (results != null && results.hasFileDescriptors()) {
15373            throw new IllegalArgumentException("File descriptors passed in Intent");
15374        }
15375
15376        synchronized(this) {
15377            ProcessRecord app = getRecordForAppLocked(target);
15378            if (app == null) {
15379                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15380                return;
15381            }
15382            final long origId = Binder.clearCallingIdentity();
15383            finishInstrumentationLocked(app, resultCode, results);
15384            Binder.restoreCallingIdentity(origId);
15385        }
15386    }
15387
15388    // =========================================================
15389    // CONFIGURATION
15390    // =========================================================
15391
15392    public ConfigurationInfo getDeviceConfigurationInfo() {
15393        ConfigurationInfo config = new ConfigurationInfo();
15394        synchronized (this) {
15395            config.reqTouchScreen = mConfiguration.touchscreen;
15396            config.reqKeyboardType = mConfiguration.keyboard;
15397            config.reqNavigation = mConfiguration.navigation;
15398            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15399                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15400                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15401            }
15402            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15403                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15404                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15405            }
15406            config.reqGlEsVersion = GL_ES_VERSION;
15407        }
15408        return config;
15409    }
15410
15411    ActivityStack getFocusedStack() {
15412        return mStackSupervisor.getFocusedStack();
15413    }
15414
15415    public Configuration getConfiguration() {
15416        Configuration ci;
15417        synchronized(this) {
15418            ci = new Configuration(mConfiguration);
15419        }
15420        return ci;
15421    }
15422
15423    public void updatePersistentConfiguration(Configuration values) {
15424        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15425                "updateConfiguration()");
15426        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15427                "updateConfiguration()");
15428        if (values == null) {
15429            throw new NullPointerException("Configuration must not be null");
15430        }
15431
15432        synchronized(this) {
15433            final long origId = Binder.clearCallingIdentity();
15434            updateConfigurationLocked(values, null, true, false);
15435            Binder.restoreCallingIdentity(origId);
15436        }
15437    }
15438
15439    public void updateConfiguration(Configuration values) {
15440        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15441                "updateConfiguration()");
15442
15443        synchronized(this) {
15444            if (values == null && mWindowManager != null) {
15445                // sentinel: fetch the current configuration from the window manager
15446                values = mWindowManager.computeNewConfiguration();
15447            }
15448
15449            if (mWindowManager != null) {
15450                mProcessList.applyDisplaySize(mWindowManager);
15451            }
15452
15453            final long origId = Binder.clearCallingIdentity();
15454            if (values != null) {
15455                Settings.System.clearConfiguration(values);
15456            }
15457            updateConfigurationLocked(values, null, false, false);
15458            Binder.restoreCallingIdentity(origId);
15459        }
15460    }
15461
15462    /**
15463     * Do either or both things: (1) change the current configuration, and (2)
15464     * make sure the given activity is running with the (now) current
15465     * configuration.  Returns true if the activity has been left running, or
15466     * false if <var>starting</var> is being destroyed to match the new
15467     * configuration.
15468     * @param persistent TODO
15469     */
15470    boolean updateConfigurationLocked(Configuration values,
15471            ActivityRecord starting, boolean persistent, boolean initLocale) {
15472        int changes = 0;
15473
15474        if (values != null) {
15475            Configuration newConfig = new Configuration(mConfiguration);
15476            changes = newConfig.updateFrom(values);
15477            if (changes != 0) {
15478                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15479                    Slog.i(TAG, "Updating configuration to: " + values);
15480                }
15481
15482                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15483
15484                if (values.locale != null && !initLocale) {
15485                    saveLocaleLocked(values.locale,
15486                                     !values.locale.equals(mConfiguration.locale),
15487                                     values.userSetLocale);
15488                }
15489
15490                mConfigurationSeq++;
15491                if (mConfigurationSeq <= 0) {
15492                    mConfigurationSeq = 1;
15493                }
15494                newConfig.seq = mConfigurationSeq;
15495                mConfiguration = newConfig;
15496                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15497                //mUsageStatsService.noteStartConfig(newConfig);
15498
15499                final Configuration configCopy = new Configuration(mConfiguration);
15500
15501                // TODO: If our config changes, should we auto dismiss any currently
15502                // showing dialogs?
15503                mShowDialogs = shouldShowDialogs(newConfig);
15504
15505                AttributeCache ac = AttributeCache.instance();
15506                if (ac != null) {
15507                    ac.updateConfiguration(configCopy);
15508                }
15509
15510                // Make sure all resources in our process are updated
15511                // right now, so that anyone who is going to retrieve
15512                // resource values after we return will be sure to get
15513                // the new ones.  This is especially important during
15514                // boot, where the first config change needs to guarantee
15515                // all resources have that config before following boot
15516                // code is executed.
15517                mSystemThread.applyConfigurationToResources(configCopy);
15518
15519                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15520                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15521                    msg.obj = new Configuration(configCopy);
15522                    mHandler.sendMessage(msg);
15523                }
15524
15525                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15526                    ProcessRecord app = mLruProcesses.get(i);
15527                    try {
15528                        if (app.thread != null) {
15529                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15530                                    + app.processName + " new config " + mConfiguration);
15531                            app.thread.scheduleConfigurationChanged(configCopy);
15532                        }
15533                    } catch (Exception e) {
15534                    }
15535                }
15536                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15537                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15538                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15539                        | Intent.FLAG_RECEIVER_FOREGROUND);
15540                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15541                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15542                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15543                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15544                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15545                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15546                    broadcastIntentLocked(null, null, intent,
15547                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15548                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15549                }
15550            }
15551        }
15552
15553        boolean kept = true;
15554        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15555        // mainStack is null during startup.
15556        if (mainStack != null) {
15557            if (changes != 0 && starting == null) {
15558                // If the configuration changed, and the caller is not already
15559                // in the process of starting an activity, then find the top
15560                // activity to check if its configuration needs to change.
15561                starting = mainStack.topRunningActivityLocked(null);
15562            }
15563
15564            if (starting != null) {
15565                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15566                // And we need to make sure at this point that all other activities
15567                // are made visible with the correct configuration.
15568                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15569            }
15570        }
15571
15572        if (values != null && mWindowManager != null) {
15573            mWindowManager.setNewConfiguration(mConfiguration);
15574        }
15575
15576        return kept;
15577    }
15578
15579    /**
15580     * Decide based on the configuration whether we should shouw the ANR,
15581     * crash, etc dialogs.  The idea is that if there is no affordnace to
15582     * press the on-screen buttons, we shouldn't show the dialog.
15583     *
15584     * A thought: SystemUI might also want to get told about this, the Power
15585     * dialog / global actions also might want different behaviors.
15586     */
15587    private static final boolean shouldShowDialogs(Configuration config) {
15588        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15589                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15590    }
15591
15592    /**
15593     * Save the locale.  You must be inside a synchronized (this) block.
15594     */
15595    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15596        if(isDiff) {
15597            SystemProperties.set("user.language", l.getLanguage());
15598            SystemProperties.set("user.region", l.getCountry());
15599        }
15600
15601        if(isPersist) {
15602            SystemProperties.set("persist.sys.language", l.getLanguage());
15603            SystemProperties.set("persist.sys.country", l.getCountry());
15604            SystemProperties.set("persist.sys.localevar", l.getVariant());
15605        }
15606    }
15607
15608    @Override
15609    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
15610        synchronized (this) {
15611            ActivityRecord srec = ActivityRecord.forToken(token);
15612            if (srec.task != null && srec.task.stack != null) {
15613                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
15614            }
15615        }
15616        return false;
15617    }
15618
15619    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15620            Intent resultData) {
15621
15622        synchronized (this) {
15623            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15624            if (stack != null) {
15625                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15626            }
15627            return false;
15628        }
15629    }
15630
15631    public int getLaunchedFromUid(IBinder activityToken) {
15632        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15633        if (srec == null) {
15634            return -1;
15635        }
15636        return srec.launchedFromUid;
15637    }
15638
15639    public String getLaunchedFromPackage(IBinder activityToken) {
15640        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15641        if (srec == null) {
15642            return null;
15643        }
15644        return srec.launchedFromPackage;
15645    }
15646
15647    // =========================================================
15648    // LIFETIME MANAGEMENT
15649    // =========================================================
15650
15651    // Returns which broadcast queue the app is the current [or imminent] receiver
15652    // on, or 'null' if the app is not an active broadcast recipient.
15653    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15654        BroadcastRecord r = app.curReceiver;
15655        if (r != null) {
15656            return r.queue;
15657        }
15658
15659        // It's not the current receiver, but it might be starting up to become one
15660        synchronized (this) {
15661            for (BroadcastQueue queue : mBroadcastQueues) {
15662                r = queue.mPendingBroadcast;
15663                if (r != null && r.curApp == app) {
15664                    // found it; report which queue it's in
15665                    return queue;
15666                }
15667            }
15668        }
15669
15670        return null;
15671    }
15672
15673    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15674            boolean doingAll, long now) {
15675        if (mAdjSeq == app.adjSeq) {
15676            // This adjustment has already been computed.
15677            return app.curRawAdj;
15678        }
15679
15680        if (app.thread == null) {
15681            app.adjSeq = mAdjSeq;
15682            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15683            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15684            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15685        }
15686
15687        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15688        app.adjSource = null;
15689        app.adjTarget = null;
15690        app.empty = false;
15691        app.cached = false;
15692
15693        final int activitiesSize = app.activities.size();
15694
15695        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15696            // The max adjustment doesn't allow this app to be anything
15697            // below foreground, so it is not worth doing work for it.
15698            app.adjType = "fixed";
15699            app.adjSeq = mAdjSeq;
15700            app.curRawAdj = app.maxAdj;
15701            app.foregroundActivities = false;
15702            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15703            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15704            // System processes can do UI, and when they do we want to have
15705            // them trim their memory after the user leaves the UI.  To
15706            // facilitate this, here we need to determine whether or not it
15707            // is currently showing UI.
15708            app.systemNoUi = true;
15709            if (app == TOP_APP) {
15710                app.systemNoUi = false;
15711            } else if (activitiesSize > 0) {
15712                for (int j = 0; j < activitiesSize; j++) {
15713                    final ActivityRecord r = app.activities.get(j);
15714                    if (r.visible) {
15715                        app.systemNoUi = false;
15716                    }
15717                }
15718            }
15719            if (!app.systemNoUi) {
15720                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15721            }
15722            return (app.curAdj=app.maxAdj);
15723        }
15724
15725        app.systemNoUi = false;
15726
15727        // Determine the importance of the process, starting with most
15728        // important to least, and assign an appropriate OOM adjustment.
15729        int adj;
15730        int schedGroup;
15731        int procState;
15732        boolean foregroundActivities = false;
15733        BroadcastQueue queue;
15734        if (app == TOP_APP) {
15735            // The last app on the list is the foreground app.
15736            adj = ProcessList.FOREGROUND_APP_ADJ;
15737            schedGroup = Process.THREAD_GROUP_DEFAULT;
15738            app.adjType = "top-activity";
15739            foregroundActivities = true;
15740            procState = ActivityManager.PROCESS_STATE_TOP;
15741        } else if (app.instrumentationClass != null) {
15742            // Don't want to kill running instrumentation.
15743            adj = ProcessList.FOREGROUND_APP_ADJ;
15744            schedGroup = Process.THREAD_GROUP_DEFAULT;
15745            app.adjType = "instrumentation";
15746            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15747        } else if ((queue = isReceivingBroadcast(app)) != null) {
15748            // An app that is currently receiving a broadcast also
15749            // counts as being in the foreground for OOM killer purposes.
15750            // It's placed in a sched group based on the nature of the
15751            // broadcast as reflected by which queue it's active in.
15752            adj = ProcessList.FOREGROUND_APP_ADJ;
15753            schedGroup = (queue == mFgBroadcastQueue)
15754                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15755            app.adjType = "broadcast";
15756            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15757        } else if (app.executingServices.size() > 0) {
15758            // An app that is currently executing a service callback also
15759            // counts as being in the foreground.
15760            adj = ProcessList.FOREGROUND_APP_ADJ;
15761            schedGroup = app.execServicesFg ?
15762                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15763            app.adjType = "exec-service";
15764            procState = ActivityManager.PROCESS_STATE_SERVICE;
15765            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15766        } else {
15767            // As far as we know the process is empty.  We may change our mind later.
15768            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15769            // At this point we don't actually know the adjustment.  Use the cached adj
15770            // value that the caller wants us to.
15771            adj = cachedAdj;
15772            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15773            app.cached = true;
15774            app.empty = true;
15775            app.adjType = "cch-empty";
15776        }
15777
15778        // Examine all activities if not already foreground.
15779        if (!foregroundActivities && activitiesSize > 0) {
15780            for (int j = 0; j < activitiesSize; j++) {
15781                final ActivityRecord r = app.activities.get(j);
15782                if (r.app != app) {
15783                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15784                            + app + "?!?");
15785                    continue;
15786                }
15787                if (r.visible) {
15788                    // App has a visible activity; only upgrade adjustment.
15789                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15790                        adj = ProcessList.VISIBLE_APP_ADJ;
15791                        app.adjType = "visible";
15792                    }
15793                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15794                        procState = ActivityManager.PROCESS_STATE_TOP;
15795                    }
15796                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15797                    app.cached = false;
15798                    app.empty = false;
15799                    foregroundActivities = true;
15800                    break;
15801                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15802                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15803                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15804                        app.adjType = "pausing";
15805                    }
15806                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15807                        procState = ActivityManager.PROCESS_STATE_TOP;
15808                    }
15809                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15810                    app.cached = false;
15811                    app.empty = false;
15812                    foregroundActivities = true;
15813                } else if (r.state == ActivityState.STOPPING) {
15814                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15815                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15816                        app.adjType = "stopping";
15817                    }
15818                    // For the process state, we will at this point consider the
15819                    // process to be cached.  It will be cached either as an activity
15820                    // or empty depending on whether the activity is finishing.  We do
15821                    // this so that we can treat the process as cached for purposes of
15822                    // memory trimming (determing current memory level, trim command to
15823                    // send to process) since there can be an arbitrary number of stopping
15824                    // processes and they should soon all go into the cached state.
15825                    if (!r.finishing) {
15826                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15827                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15828                        }
15829                    }
15830                    app.cached = false;
15831                    app.empty = false;
15832                    foregroundActivities = true;
15833                } else {
15834                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15835                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15836                        app.adjType = "cch-act";
15837                    }
15838                }
15839            }
15840        }
15841
15842        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15843            if (app.foregroundServices) {
15844                // The user is aware of this app, so make it visible.
15845                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15846                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15847                app.cached = false;
15848                app.adjType = "fg-service";
15849                schedGroup = Process.THREAD_GROUP_DEFAULT;
15850            } else if (app.forcingToForeground != null) {
15851                // The user is aware of this app, so make it visible.
15852                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15853                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15854                app.cached = false;
15855                app.adjType = "force-fg";
15856                app.adjSource = app.forcingToForeground;
15857                schedGroup = Process.THREAD_GROUP_DEFAULT;
15858            }
15859        }
15860
15861        if (app == mHeavyWeightProcess) {
15862            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15863                // We don't want to kill the current heavy-weight process.
15864                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15865                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15866                app.cached = false;
15867                app.adjType = "heavy";
15868            }
15869            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15870                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15871            }
15872        }
15873
15874        if (app == mHomeProcess) {
15875            if (adj > ProcessList.HOME_APP_ADJ) {
15876                // This process is hosting what we currently consider to be the
15877                // home app, so we don't want to let it go into the background.
15878                adj = ProcessList.HOME_APP_ADJ;
15879                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15880                app.cached = false;
15881                app.adjType = "home";
15882            }
15883            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15884                procState = ActivityManager.PROCESS_STATE_HOME;
15885            }
15886        }
15887
15888        if (app == mPreviousProcess && app.activities.size() > 0) {
15889            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15890                // This was the previous process that showed UI to the user.
15891                // We want to try to keep it around more aggressively, to give
15892                // a good experience around switching between two apps.
15893                adj = ProcessList.PREVIOUS_APP_ADJ;
15894                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15895                app.cached = false;
15896                app.adjType = "previous";
15897            }
15898            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15899                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15900            }
15901        }
15902
15903        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15904                + " reason=" + app.adjType);
15905
15906        // By default, we use the computed adjustment.  It may be changed if
15907        // there are applications dependent on our services or providers, but
15908        // this gives us a baseline and makes sure we don't get into an
15909        // infinite recursion.
15910        app.adjSeq = mAdjSeq;
15911        app.curRawAdj = adj;
15912        app.hasStartedServices = false;
15913
15914        if (mBackupTarget != null && app == mBackupTarget.app) {
15915            // If possible we want to avoid killing apps while they're being backed up
15916            if (adj > ProcessList.BACKUP_APP_ADJ) {
15917                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15918                adj = ProcessList.BACKUP_APP_ADJ;
15919                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15920                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15921                }
15922                app.adjType = "backup";
15923                app.cached = false;
15924            }
15925            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15926                procState = ActivityManager.PROCESS_STATE_BACKUP;
15927            }
15928        }
15929
15930        boolean mayBeTop = false;
15931
15932        for (int is = app.services.size()-1;
15933                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15934                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15935                        || procState > ActivityManager.PROCESS_STATE_TOP);
15936                is--) {
15937            ServiceRecord s = app.services.valueAt(is);
15938            if (s.startRequested) {
15939                app.hasStartedServices = true;
15940                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15941                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15942                }
15943                if (app.hasShownUi && app != mHomeProcess) {
15944                    // If this process has shown some UI, let it immediately
15945                    // go to the LRU list because it may be pretty heavy with
15946                    // UI stuff.  We'll tag it with a label just to help
15947                    // debug and understand what is going on.
15948                    if (adj > ProcessList.SERVICE_ADJ) {
15949                        app.adjType = "cch-started-ui-services";
15950                    }
15951                } else {
15952                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15953                        // This service has seen some activity within
15954                        // recent memory, so we will keep its process ahead
15955                        // of the background processes.
15956                        if (adj > ProcessList.SERVICE_ADJ) {
15957                            adj = ProcessList.SERVICE_ADJ;
15958                            app.adjType = "started-services";
15959                            app.cached = false;
15960                        }
15961                    }
15962                    // If we have let the service slide into the background
15963                    // state, still have some text describing what it is doing
15964                    // even though the service no longer has an impact.
15965                    if (adj > ProcessList.SERVICE_ADJ) {
15966                        app.adjType = "cch-started-services";
15967                    }
15968                }
15969            }
15970            for (int conni = s.connections.size()-1;
15971                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15972                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15973                            || procState > ActivityManager.PROCESS_STATE_TOP);
15974                    conni--) {
15975                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15976                for (int i = 0;
15977                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15978                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15979                                || procState > ActivityManager.PROCESS_STATE_TOP);
15980                        i++) {
15981                    // XXX should compute this based on the max of
15982                    // all connected clients.
15983                    ConnectionRecord cr = clist.get(i);
15984                    if (cr.binding.client == app) {
15985                        // Binding to ourself is not interesting.
15986                        continue;
15987                    }
15988                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15989                        ProcessRecord client = cr.binding.client;
15990                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15991                                TOP_APP, doingAll, now);
15992                        int clientProcState = client.curProcState;
15993                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15994                            // If the other app is cached for any reason, for purposes here
15995                            // we are going to consider it empty.  The specific cached state
15996                            // doesn't propagate except under certain conditions.
15997                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15998                        }
15999                        String adjType = null;
16000                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16001                            // Not doing bind OOM management, so treat
16002                            // this guy more like a started service.
16003                            if (app.hasShownUi && app != mHomeProcess) {
16004                                // If this process has shown some UI, let it immediately
16005                                // go to the LRU list because it may be pretty heavy with
16006                                // UI stuff.  We'll tag it with a label just to help
16007                                // debug and understand what is going on.
16008                                if (adj > clientAdj) {
16009                                    adjType = "cch-bound-ui-services";
16010                                }
16011                                app.cached = false;
16012                                clientAdj = adj;
16013                                clientProcState = procState;
16014                            } else {
16015                                if (now >= (s.lastActivity
16016                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16017                                    // This service has not seen activity within
16018                                    // recent memory, so allow it to drop to the
16019                                    // LRU list if there is no other reason to keep
16020                                    // it around.  We'll also tag it with a label just
16021                                    // to help debug and undertand what is going on.
16022                                    if (adj > clientAdj) {
16023                                        adjType = "cch-bound-services";
16024                                    }
16025                                    clientAdj = adj;
16026                                }
16027                            }
16028                        }
16029                        if (adj > clientAdj) {
16030                            // If this process has recently shown UI, and
16031                            // the process that is binding to it is less
16032                            // important than being visible, then we don't
16033                            // care about the binding as much as we care
16034                            // about letting this process get into the LRU
16035                            // list to be killed and restarted if needed for
16036                            // memory.
16037                            if (app.hasShownUi && app != mHomeProcess
16038                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16039                                adjType = "cch-bound-ui-services";
16040                            } else {
16041                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16042                                        |Context.BIND_IMPORTANT)) != 0) {
16043                                    adj = clientAdj;
16044                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16045                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16046                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16047                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16048                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16049                                    adj = clientAdj;
16050                                } else {
16051                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16052                                        adj = ProcessList.VISIBLE_APP_ADJ;
16053                                    }
16054                                }
16055                                if (!client.cached) {
16056                                    app.cached = false;
16057                                }
16058                                adjType = "service";
16059                            }
16060                        }
16061                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16062                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16063                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16064                            }
16065                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16066                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16067                                    // Special handling of clients who are in the top state.
16068                                    // We *may* want to consider this process to be in the
16069                                    // top state as well, but only if there is not another
16070                                    // reason for it to be running.  Being on the top is a
16071                                    // special state, meaning you are specifically running
16072                                    // for the current top app.  If the process is already
16073                                    // running in the background for some other reason, it
16074                                    // is more important to continue considering it to be
16075                                    // in the background state.
16076                                    mayBeTop = true;
16077                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16078                                } else {
16079                                    // Special handling for above-top states (persistent
16080                                    // processes).  These should not bring the current process
16081                                    // into the top state, since they are not on top.  Instead
16082                                    // give them the best state after that.
16083                                    clientProcState =
16084                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16085                                }
16086                            }
16087                        } else {
16088                            if (clientProcState <
16089                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16090                                clientProcState =
16091                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16092                            }
16093                        }
16094                        if (procState > clientProcState) {
16095                            procState = clientProcState;
16096                        }
16097                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16098                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16099                            app.pendingUiClean = true;
16100                        }
16101                        if (adjType != null) {
16102                            app.adjType = adjType;
16103                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16104                                    .REASON_SERVICE_IN_USE;
16105                            app.adjSource = cr.binding.client;
16106                            app.adjSourceProcState = clientProcState;
16107                            app.adjTarget = s.name;
16108                        }
16109                    }
16110                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16111                        app.treatLikeActivity = true;
16112                    }
16113                    final ActivityRecord a = cr.activity;
16114                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16115                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16116                                (a.visible || a.state == ActivityState.RESUMED
16117                                 || a.state == ActivityState.PAUSING)) {
16118                            adj = ProcessList.FOREGROUND_APP_ADJ;
16119                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16120                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16121                            }
16122                            app.cached = false;
16123                            app.adjType = "service";
16124                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16125                                    .REASON_SERVICE_IN_USE;
16126                            app.adjSource = a;
16127                            app.adjSourceProcState = procState;
16128                            app.adjTarget = s.name;
16129                        }
16130                    }
16131                }
16132            }
16133        }
16134
16135        for (int provi = app.pubProviders.size()-1;
16136                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16137                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16138                        || procState > ActivityManager.PROCESS_STATE_TOP);
16139                provi--) {
16140            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16141            for (int i = cpr.connections.size()-1;
16142                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16143                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16144                            || procState > ActivityManager.PROCESS_STATE_TOP);
16145                    i--) {
16146                ContentProviderConnection conn = cpr.connections.get(i);
16147                ProcessRecord client = conn.client;
16148                if (client == app) {
16149                    // Being our own client is not interesting.
16150                    continue;
16151                }
16152                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16153                int clientProcState = client.curProcState;
16154                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16155                    // If the other app is cached for any reason, for purposes here
16156                    // we are going to consider it empty.
16157                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16158                }
16159                if (adj > clientAdj) {
16160                    if (app.hasShownUi && app != mHomeProcess
16161                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16162                        app.adjType = "cch-ui-provider";
16163                    } else {
16164                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16165                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16166                        app.adjType = "provider";
16167                    }
16168                    app.cached &= client.cached;
16169                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16170                            .REASON_PROVIDER_IN_USE;
16171                    app.adjSource = client;
16172                    app.adjSourceProcState = clientProcState;
16173                    app.adjTarget = cpr.name;
16174                }
16175                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16176                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16177                        // Special handling of clients who are in the top state.
16178                        // We *may* want to consider this process to be in the
16179                        // top state as well, but only if there is not another
16180                        // reason for it to be running.  Being on the top is a
16181                        // special state, meaning you are specifically running
16182                        // for the current top app.  If the process is already
16183                        // running in the background for some other reason, it
16184                        // is more important to continue considering it to be
16185                        // in the background state.
16186                        mayBeTop = true;
16187                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16188                    } else {
16189                        // Special handling for above-top states (persistent
16190                        // processes).  These should not bring the current process
16191                        // into the top state, since they are not on top.  Instead
16192                        // give them the best state after that.
16193                        clientProcState =
16194                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16195                    }
16196                }
16197                if (procState > clientProcState) {
16198                    procState = clientProcState;
16199                }
16200                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16201                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16202                }
16203            }
16204            // If the provider has external (non-framework) process
16205            // dependencies, ensure that its adjustment is at least
16206            // FOREGROUND_APP_ADJ.
16207            if (cpr.hasExternalProcessHandles()) {
16208                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16209                    adj = ProcessList.FOREGROUND_APP_ADJ;
16210                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16211                    app.cached = false;
16212                    app.adjType = "provider";
16213                    app.adjTarget = cpr.name;
16214                }
16215                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16216                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16217                }
16218            }
16219        }
16220
16221        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16222            // A client of one of our services or providers is in the top state.  We
16223            // *may* want to be in the top state, but not if we are already running in
16224            // the background for some other reason.  For the decision here, we are going
16225            // to pick out a few specific states that we want to remain in when a client
16226            // is top (states that tend to be longer-term) and otherwise allow it to go
16227            // to the top state.
16228            switch (procState) {
16229                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16230                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16231                case ActivityManager.PROCESS_STATE_SERVICE:
16232                    // These all are longer-term states, so pull them up to the top
16233                    // of the background states, but not all the way to the top state.
16234                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16235                    break;
16236                default:
16237                    // Otherwise, top is a better choice, so take it.
16238                    procState = ActivityManager.PROCESS_STATE_TOP;
16239                    break;
16240            }
16241        }
16242
16243        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16244            if (app.hasClientActivities) {
16245                // This is a cached process, but with client activities.  Mark it so.
16246                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16247                app.adjType = "cch-client-act";
16248            } else if (app.treatLikeActivity) {
16249                // This is a cached process, but somebody wants us to treat it like it has
16250                // an activity, okay!
16251                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16252                app.adjType = "cch-as-act";
16253            }
16254        }
16255
16256        if (adj == ProcessList.SERVICE_ADJ) {
16257            if (doingAll) {
16258                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16259                mNewNumServiceProcs++;
16260                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16261                if (!app.serviceb) {
16262                    // This service isn't far enough down on the LRU list to
16263                    // normally be a B service, but if we are low on RAM and it
16264                    // is large we want to force it down since we would prefer to
16265                    // keep launcher over it.
16266                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16267                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16268                        app.serviceHighRam = true;
16269                        app.serviceb = true;
16270                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16271                    } else {
16272                        mNewNumAServiceProcs++;
16273                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16274                    }
16275                } else {
16276                    app.serviceHighRam = false;
16277                }
16278            }
16279            if (app.serviceb) {
16280                adj = ProcessList.SERVICE_B_ADJ;
16281            }
16282        }
16283
16284        app.curRawAdj = adj;
16285
16286        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16287        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16288        if (adj > app.maxAdj) {
16289            adj = app.maxAdj;
16290            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16291                schedGroup = Process.THREAD_GROUP_DEFAULT;
16292            }
16293        }
16294
16295        // Do final modification to adj.  Everything we do between here and applying
16296        // the final setAdj must be done in this function, because we will also use
16297        // it when computing the final cached adj later.  Note that we don't need to
16298        // worry about this for max adj above, since max adj will always be used to
16299        // keep it out of the cached vaues.
16300        app.curAdj = app.modifyRawOomAdj(adj);
16301        app.curSchedGroup = schedGroup;
16302        app.curProcState = procState;
16303        app.foregroundActivities = foregroundActivities;
16304
16305        return app.curRawAdj;
16306    }
16307
16308    /**
16309     * Schedule PSS collection of a process.
16310     */
16311    void requestPssLocked(ProcessRecord proc, int procState) {
16312        if (mPendingPssProcesses.contains(proc)) {
16313            return;
16314        }
16315        if (mPendingPssProcesses.size() == 0) {
16316            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16317        }
16318        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16319        proc.pssProcState = procState;
16320        mPendingPssProcesses.add(proc);
16321    }
16322
16323    /**
16324     * Schedule PSS collection of all processes.
16325     */
16326    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16327        if (!always) {
16328            if (now < (mLastFullPssTime +
16329                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16330                return;
16331            }
16332        }
16333        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16334        mLastFullPssTime = now;
16335        mFullPssPending = true;
16336        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16337        mPendingPssProcesses.clear();
16338        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16339            ProcessRecord app = mLruProcesses.get(i);
16340            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16341                app.pssProcState = app.setProcState;
16342                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16343                        isSleeping(), now);
16344                mPendingPssProcesses.add(app);
16345            }
16346        }
16347        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16348    }
16349
16350    /**
16351     * Ask a given process to GC right now.
16352     */
16353    final void performAppGcLocked(ProcessRecord app) {
16354        try {
16355            app.lastRequestedGc = SystemClock.uptimeMillis();
16356            if (app.thread != null) {
16357                if (app.reportLowMemory) {
16358                    app.reportLowMemory = false;
16359                    app.thread.scheduleLowMemory();
16360                } else {
16361                    app.thread.processInBackground();
16362                }
16363            }
16364        } catch (Exception e) {
16365            // whatever.
16366        }
16367    }
16368
16369    /**
16370     * Returns true if things are idle enough to perform GCs.
16371     */
16372    private final boolean canGcNowLocked() {
16373        boolean processingBroadcasts = false;
16374        for (BroadcastQueue q : mBroadcastQueues) {
16375            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16376                processingBroadcasts = true;
16377            }
16378        }
16379        return !processingBroadcasts
16380                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16381    }
16382
16383    /**
16384     * Perform GCs on all processes that are waiting for it, but only
16385     * if things are idle.
16386     */
16387    final void performAppGcsLocked() {
16388        final int N = mProcessesToGc.size();
16389        if (N <= 0) {
16390            return;
16391        }
16392        if (canGcNowLocked()) {
16393            while (mProcessesToGc.size() > 0) {
16394                ProcessRecord proc = mProcessesToGc.remove(0);
16395                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16396                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16397                            <= SystemClock.uptimeMillis()) {
16398                        // To avoid spamming the system, we will GC processes one
16399                        // at a time, waiting a few seconds between each.
16400                        performAppGcLocked(proc);
16401                        scheduleAppGcsLocked();
16402                        return;
16403                    } else {
16404                        // It hasn't been long enough since we last GCed this
16405                        // process...  put it in the list to wait for its time.
16406                        addProcessToGcListLocked(proc);
16407                        break;
16408                    }
16409                }
16410            }
16411
16412            scheduleAppGcsLocked();
16413        }
16414    }
16415
16416    /**
16417     * If all looks good, perform GCs on all processes waiting for them.
16418     */
16419    final void performAppGcsIfAppropriateLocked() {
16420        if (canGcNowLocked()) {
16421            performAppGcsLocked();
16422            return;
16423        }
16424        // Still not idle, wait some more.
16425        scheduleAppGcsLocked();
16426    }
16427
16428    /**
16429     * Schedule the execution of all pending app GCs.
16430     */
16431    final void scheduleAppGcsLocked() {
16432        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16433
16434        if (mProcessesToGc.size() > 0) {
16435            // Schedule a GC for the time to the next process.
16436            ProcessRecord proc = mProcessesToGc.get(0);
16437            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16438
16439            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16440            long now = SystemClock.uptimeMillis();
16441            if (when < (now+GC_TIMEOUT)) {
16442                when = now + GC_TIMEOUT;
16443            }
16444            mHandler.sendMessageAtTime(msg, when);
16445        }
16446    }
16447
16448    /**
16449     * Add a process to the array of processes waiting to be GCed.  Keeps the
16450     * list in sorted order by the last GC time.  The process can't already be
16451     * on the list.
16452     */
16453    final void addProcessToGcListLocked(ProcessRecord proc) {
16454        boolean added = false;
16455        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16456            if (mProcessesToGc.get(i).lastRequestedGc <
16457                    proc.lastRequestedGc) {
16458                added = true;
16459                mProcessesToGc.add(i+1, proc);
16460                break;
16461            }
16462        }
16463        if (!added) {
16464            mProcessesToGc.add(0, proc);
16465        }
16466    }
16467
16468    /**
16469     * Set up to ask a process to GC itself.  This will either do it
16470     * immediately, or put it on the list of processes to gc the next
16471     * time things are idle.
16472     */
16473    final void scheduleAppGcLocked(ProcessRecord app) {
16474        long now = SystemClock.uptimeMillis();
16475        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16476            return;
16477        }
16478        if (!mProcessesToGc.contains(app)) {
16479            addProcessToGcListLocked(app);
16480            scheduleAppGcsLocked();
16481        }
16482    }
16483
16484    final void checkExcessivePowerUsageLocked(boolean doKills) {
16485        updateCpuStatsNow();
16486
16487        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16488        boolean doWakeKills = doKills;
16489        boolean doCpuKills = doKills;
16490        if (mLastPowerCheckRealtime == 0) {
16491            doWakeKills = false;
16492        }
16493        if (mLastPowerCheckUptime == 0) {
16494            doCpuKills = false;
16495        }
16496        if (stats.isScreenOn()) {
16497            doWakeKills = false;
16498        }
16499        final long curRealtime = SystemClock.elapsedRealtime();
16500        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16501        final long curUptime = SystemClock.uptimeMillis();
16502        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16503        mLastPowerCheckRealtime = curRealtime;
16504        mLastPowerCheckUptime = curUptime;
16505        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16506            doWakeKills = false;
16507        }
16508        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16509            doCpuKills = false;
16510        }
16511        int i = mLruProcesses.size();
16512        while (i > 0) {
16513            i--;
16514            ProcessRecord app = mLruProcesses.get(i);
16515            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16516                long wtime;
16517                synchronized (stats) {
16518                    wtime = stats.getProcessWakeTime(app.info.uid,
16519                            app.pid, curRealtime);
16520                }
16521                long wtimeUsed = wtime - app.lastWakeTime;
16522                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16523                if (DEBUG_POWER) {
16524                    StringBuilder sb = new StringBuilder(128);
16525                    sb.append("Wake for ");
16526                    app.toShortString(sb);
16527                    sb.append(": over ");
16528                    TimeUtils.formatDuration(realtimeSince, sb);
16529                    sb.append(" used ");
16530                    TimeUtils.formatDuration(wtimeUsed, sb);
16531                    sb.append(" (");
16532                    sb.append((wtimeUsed*100)/realtimeSince);
16533                    sb.append("%)");
16534                    Slog.i(TAG, sb.toString());
16535                    sb.setLength(0);
16536                    sb.append("CPU for ");
16537                    app.toShortString(sb);
16538                    sb.append(": over ");
16539                    TimeUtils.formatDuration(uptimeSince, sb);
16540                    sb.append(" used ");
16541                    TimeUtils.formatDuration(cputimeUsed, sb);
16542                    sb.append(" (");
16543                    sb.append((cputimeUsed*100)/uptimeSince);
16544                    sb.append("%)");
16545                    Slog.i(TAG, sb.toString());
16546                }
16547                // If a process has held a wake lock for more
16548                // than 50% of the time during this period,
16549                // that sounds bad.  Kill!
16550                if (doWakeKills && realtimeSince > 0
16551                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16552                    synchronized (stats) {
16553                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16554                                realtimeSince, wtimeUsed);
16555                    }
16556                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16557                            + " during " + realtimeSince);
16558                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16559                } else if (doCpuKills && uptimeSince > 0
16560                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16561                    synchronized (stats) {
16562                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16563                                uptimeSince, cputimeUsed);
16564                    }
16565                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16566                            + " during " + uptimeSince);
16567                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16568                } else {
16569                    app.lastWakeTime = wtime;
16570                    app.lastCpuTime = app.curCpuTime;
16571                }
16572            }
16573        }
16574    }
16575
16576    private final boolean applyOomAdjLocked(ProcessRecord app,
16577            ProcessRecord TOP_APP, boolean doingAll, long now) {
16578        boolean success = true;
16579
16580        if (app.curRawAdj != app.setRawAdj) {
16581            app.setRawAdj = app.curRawAdj;
16582        }
16583
16584        int changes = 0;
16585
16586        if (app.curAdj != app.setAdj) {
16587            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16588            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16589                TAG, "Set " + app.pid + " " + app.processName +
16590                " adj " + app.curAdj + ": " + app.adjType);
16591            app.setAdj = app.curAdj;
16592        }
16593
16594        if (app.setSchedGroup != app.curSchedGroup) {
16595            app.setSchedGroup = app.curSchedGroup;
16596            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16597                    "Setting process group of " + app.processName
16598                    + " to " + app.curSchedGroup);
16599            if (app.waitingToKill != null &&
16600                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16601                killUnneededProcessLocked(app, app.waitingToKill);
16602                success = false;
16603            } else {
16604                if (true) {
16605                    long oldId = Binder.clearCallingIdentity();
16606                    try {
16607                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16608                    } catch (Exception e) {
16609                        Slog.w(TAG, "Failed setting process group of " + app.pid
16610                                + " to " + app.curSchedGroup);
16611                        e.printStackTrace();
16612                    } finally {
16613                        Binder.restoreCallingIdentity(oldId);
16614                    }
16615                } else {
16616                    if (app.thread != null) {
16617                        try {
16618                            app.thread.setSchedulingGroup(app.curSchedGroup);
16619                        } catch (RemoteException e) {
16620                        }
16621                    }
16622                }
16623                Process.setSwappiness(app.pid,
16624                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16625            }
16626        }
16627        if (app.repForegroundActivities != app.foregroundActivities) {
16628            app.repForegroundActivities = app.foregroundActivities;
16629            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16630        }
16631        if (app.repProcState != app.curProcState) {
16632            app.repProcState = app.curProcState;
16633            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16634            if (app.thread != null) {
16635                try {
16636                    if (false) {
16637                        //RuntimeException h = new RuntimeException("here");
16638                        Slog.i(TAG, "Sending new process state " + app.repProcState
16639                                + " to " + app /*, h*/);
16640                    }
16641                    app.thread.setProcessState(app.repProcState);
16642                } catch (RemoteException e) {
16643                }
16644            }
16645        }
16646        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16647                app.setProcState)) {
16648            app.lastStateTime = now;
16649            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16650                    isSleeping(), now);
16651            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16652                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16653                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16654                    + (app.nextPssTime-now) + ": " + app);
16655        } else {
16656            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16657                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16658                requestPssLocked(app, app.setProcState);
16659                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16660                        isSleeping(), now);
16661            } else if (false && DEBUG_PSS) {
16662                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16663            }
16664        }
16665        if (app.setProcState != app.curProcState) {
16666            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16667                    "Proc state change of " + app.processName
16668                    + " to " + app.curProcState);
16669            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16670            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16671            if (setImportant && !curImportant) {
16672                // This app is no longer something we consider important enough to allow to
16673                // use arbitrary amounts of battery power.  Note
16674                // its current wake lock time to later know to kill it if
16675                // it is not behaving well.
16676                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16677                synchronized (stats) {
16678                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16679                            app.pid, SystemClock.elapsedRealtime());
16680                }
16681                app.lastCpuTime = app.curCpuTime;
16682
16683            }
16684            app.setProcState = app.curProcState;
16685            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16686                app.notCachedSinceIdle = false;
16687            }
16688            if (!doingAll) {
16689                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16690            } else {
16691                app.procStateChanged = true;
16692            }
16693        }
16694
16695        if (changes != 0) {
16696            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16697            int i = mPendingProcessChanges.size()-1;
16698            ProcessChangeItem item = null;
16699            while (i >= 0) {
16700                item = mPendingProcessChanges.get(i);
16701                if (item.pid == app.pid) {
16702                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16703                    break;
16704                }
16705                i--;
16706            }
16707            if (i < 0) {
16708                // No existing item in pending changes; need a new one.
16709                final int NA = mAvailProcessChanges.size();
16710                if (NA > 0) {
16711                    item = mAvailProcessChanges.remove(NA-1);
16712                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16713                } else {
16714                    item = new ProcessChangeItem();
16715                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16716                }
16717                item.changes = 0;
16718                item.pid = app.pid;
16719                item.uid = app.info.uid;
16720                if (mPendingProcessChanges.size() == 0) {
16721                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16722                            "*** Enqueueing dispatch processes changed!");
16723                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16724                }
16725                mPendingProcessChanges.add(item);
16726            }
16727            item.changes |= changes;
16728            item.processState = app.repProcState;
16729            item.foregroundActivities = app.repForegroundActivities;
16730            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16731                    + Integer.toHexString(System.identityHashCode(item))
16732                    + " " + app.toShortString() + ": changes=" + item.changes
16733                    + " procState=" + item.processState
16734                    + " foreground=" + item.foregroundActivities
16735                    + " type=" + app.adjType + " source=" + app.adjSource
16736                    + " target=" + app.adjTarget);
16737        }
16738
16739        return success;
16740    }
16741
16742    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16743        if (proc.thread != null) {
16744            if (proc.baseProcessTracker != null) {
16745                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16746            }
16747            if (proc.repProcState >= 0) {
16748                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16749                        proc.repProcState);
16750            }
16751        }
16752    }
16753
16754    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16755            ProcessRecord TOP_APP, boolean doingAll, long now) {
16756        if (app.thread == null) {
16757            return false;
16758        }
16759
16760        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16761
16762        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16763    }
16764
16765    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16766            boolean oomAdj) {
16767        if (isForeground != proc.foregroundServices) {
16768            proc.foregroundServices = isForeground;
16769            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16770                    proc.info.uid);
16771            if (isForeground) {
16772                if (curProcs == null) {
16773                    curProcs = new ArrayList<ProcessRecord>();
16774                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16775                }
16776                if (!curProcs.contains(proc)) {
16777                    curProcs.add(proc);
16778                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16779                            proc.info.packageName, proc.info.uid);
16780                }
16781            } else {
16782                if (curProcs != null) {
16783                    if (curProcs.remove(proc)) {
16784                        mBatteryStatsService.noteEvent(
16785                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16786                                proc.info.packageName, proc.info.uid);
16787                        if (curProcs.size() <= 0) {
16788                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16789                        }
16790                    }
16791                }
16792            }
16793            if (oomAdj) {
16794                updateOomAdjLocked();
16795            }
16796        }
16797    }
16798
16799    private final ActivityRecord resumedAppLocked() {
16800        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16801        String pkg;
16802        int uid;
16803        if (act != null) {
16804            pkg = act.packageName;
16805            uid = act.info.applicationInfo.uid;
16806        } else {
16807            pkg = null;
16808            uid = -1;
16809        }
16810        // Has the UID or resumed package name changed?
16811        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16812                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16813            if (mCurResumedPackage != null) {
16814                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16815                        mCurResumedPackage, mCurResumedUid);
16816            }
16817            mCurResumedPackage = pkg;
16818            mCurResumedUid = uid;
16819            if (mCurResumedPackage != null) {
16820                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16821                        mCurResumedPackage, mCurResumedUid);
16822            }
16823        }
16824        return act;
16825    }
16826
16827    final boolean updateOomAdjLocked(ProcessRecord app) {
16828        final ActivityRecord TOP_ACT = resumedAppLocked();
16829        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16830        final boolean wasCached = app.cached;
16831
16832        mAdjSeq++;
16833
16834        // This is the desired cached adjusment we want to tell it to use.
16835        // If our app is currently cached, we know it, and that is it.  Otherwise,
16836        // we don't know it yet, and it needs to now be cached we will then
16837        // need to do a complete oom adj.
16838        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16839                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16840        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16841                SystemClock.uptimeMillis());
16842        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16843            // Changed to/from cached state, so apps after it in the LRU
16844            // list may also be changed.
16845            updateOomAdjLocked();
16846        }
16847        return success;
16848    }
16849
16850    final void updateOomAdjLocked() {
16851        final ActivityRecord TOP_ACT = resumedAppLocked();
16852        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16853        final long now = SystemClock.uptimeMillis();
16854        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16855        final int N = mLruProcesses.size();
16856
16857        if (false) {
16858            RuntimeException e = new RuntimeException();
16859            e.fillInStackTrace();
16860            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16861        }
16862
16863        mAdjSeq++;
16864        mNewNumServiceProcs = 0;
16865        mNewNumAServiceProcs = 0;
16866
16867        final int emptyProcessLimit;
16868        final int cachedProcessLimit;
16869        if (mProcessLimit <= 0) {
16870            emptyProcessLimit = cachedProcessLimit = 0;
16871        } else if (mProcessLimit == 1) {
16872            emptyProcessLimit = 1;
16873            cachedProcessLimit = 0;
16874        } else {
16875            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16876            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16877        }
16878
16879        // Let's determine how many processes we have running vs.
16880        // how many slots we have for background processes; we may want
16881        // to put multiple processes in a slot of there are enough of
16882        // them.
16883        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16884                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16885        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16886        if (numEmptyProcs > cachedProcessLimit) {
16887            // If there are more empty processes than our limit on cached
16888            // processes, then use the cached process limit for the factor.
16889            // This ensures that the really old empty processes get pushed
16890            // down to the bottom, so if we are running low on memory we will
16891            // have a better chance at keeping around more cached processes
16892            // instead of a gazillion empty processes.
16893            numEmptyProcs = cachedProcessLimit;
16894        }
16895        int emptyFactor = numEmptyProcs/numSlots;
16896        if (emptyFactor < 1) emptyFactor = 1;
16897        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16898        if (cachedFactor < 1) cachedFactor = 1;
16899        int stepCached = 0;
16900        int stepEmpty = 0;
16901        int numCached = 0;
16902        int numEmpty = 0;
16903        int numTrimming = 0;
16904
16905        mNumNonCachedProcs = 0;
16906        mNumCachedHiddenProcs = 0;
16907
16908        // First update the OOM adjustment for each of the
16909        // application processes based on their current state.
16910        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16911        int nextCachedAdj = curCachedAdj+1;
16912        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16913        int nextEmptyAdj = curEmptyAdj+2;
16914        for (int i=N-1; i>=0; i--) {
16915            ProcessRecord app = mLruProcesses.get(i);
16916            if (!app.killedByAm && app.thread != null) {
16917                app.procStateChanged = false;
16918                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16919
16920                // If we haven't yet assigned the final cached adj
16921                // to the process, do that now.
16922                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16923                    switch (app.curProcState) {
16924                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16925                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16926                            // This process is a cached process holding activities...
16927                            // assign it the next cached value for that type, and then
16928                            // step that cached level.
16929                            app.curRawAdj = curCachedAdj;
16930                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16931                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16932                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16933                                    + ")");
16934                            if (curCachedAdj != nextCachedAdj) {
16935                                stepCached++;
16936                                if (stepCached >= cachedFactor) {
16937                                    stepCached = 0;
16938                                    curCachedAdj = nextCachedAdj;
16939                                    nextCachedAdj += 2;
16940                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16941                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16942                                    }
16943                                }
16944                            }
16945                            break;
16946                        default:
16947                            // For everything else, assign next empty cached process
16948                            // level and bump that up.  Note that this means that
16949                            // long-running services that have dropped down to the
16950                            // cached level will be treated as empty (since their process
16951                            // state is still as a service), which is what we want.
16952                            app.curRawAdj = curEmptyAdj;
16953                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16954                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16955                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16956                                    + ")");
16957                            if (curEmptyAdj != nextEmptyAdj) {
16958                                stepEmpty++;
16959                                if (stepEmpty >= emptyFactor) {
16960                                    stepEmpty = 0;
16961                                    curEmptyAdj = nextEmptyAdj;
16962                                    nextEmptyAdj += 2;
16963                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16964                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16965                                    }
16966                                }
16967                            }
16968                            break;
16969                    }
16970                }
16971
16972                applyOomAdjLocked(app, TOP_APP, true, now);
16973
16974                // Count the number of process types.
16975                switch (app.curProcState) {
16976                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16977                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16978                        mNumCachedHiddenProcs++;
16979                        numCached++;
16980                        if (numCached > cachedProcessLimit) {
16981                            killUnneededProcessLocked(app, "cached #" + numCached);
16982                        }
16983                        break;
16984                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16985                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16986                                && app.lastActivityTime < oldTime) {
16987                            killUnneededProcessLocked(app, "empty for "
16988                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16989                                    / 1000) + "s");
16990                        } else {
16991                            numEmpty++;
16992                            if (numEmpty > emptyProcessLimit) {
16993                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16994                            }
16995                        }
16996                        break;
16997                    default:
16998                        mNumNonCachedProcs++;
16999                        break;
17000                }
17001
17002                if (app.isolated && app.services.size() <= 0) {
17003                    // If this is an isolated process, and there are no
17004                    // services running in it, then the process is no longer
17005                    // needed.  We agressively kill these because we can by
17006                    // definition not re-use the same process again, and it is
17007                    // good to avoid having whatever code was running in them
17008                    // left sitting around after no longer needed.
17009                    killUnneededProcessLocked(app, "isolated not needed");
17010                }
17011
17012                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17013                        && !app.killedByAm) {
17014                    numTrimming++;
17015                }
17016            }
17017        }
17018
17019        mNumServiceProcs = mNewNumServiceProcs;
17020
17021        // Now determine the memory trimming level of background processes.
17022        // Unfortunately we need to start at the back of the list to do this
17023        // properly.  We only do this if the number of background apps we
17024        // are managing to keep around is less than half the maximum we desire;
17025        // if we are keeping a good number around, we'll let them use whatever
17026        // memory they want.
17027        final int numCachedAndEmpty = numCached + numEmpty;
17028        int memFactor;
17029        if (numCached <= ProcessList.TRIM_CACHED_APPS
17030                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17031            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17032                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17033            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17034                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17035            } else {
17036                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17037            }
17038        } else {
17039            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17040        }
17041        // We always allow the memory level to go up (better).  We only allow it to go
17042        // down if we are in a state where that is allowed, *and* the total number of processes
17043        // has gone down since last time.
17044        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17045                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17046                + " last=" + mLastNumProcesses);
17047        if (memFactor > mLastMemoryLevel) {
17048            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17049                memFactor = mLastMemoryLevel;
17050                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17051            }
17052        }
17053        mLastMemoryLevel = memFactor;
17054        mLastNumProcesses = mLruProcesses.size();
17055        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17056        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17057        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17058            if (mLowRamStartTime == 0) {
17059                mLowRamStartTime = now;
17060            }
17061            int step = 0;
17062            int fgTrimLevel;
17063            switch (memFactor) {
17064                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17065                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17066                    break;
17067                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17068                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17069                    break;
17070                default:
17071                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17072                    break;
17073            }
17074            int factor = numTrimming/3;
17075            int minFactor = 2;
17076            if (mHomeProcess != null) minFactor++;
17077            if (mPreviousProcess != null) minFactor++;
17078            if (factor < minFactor) factor = minFactor;
17079            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17080            for (int i=N-1; i>=0; i--) {
17081                ProcessRecord app = mLruProcesses.get(i);
17082                if (allChanged || app.procStateChanged) {
17083                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17084                    app.procStateChanged = false;
17085                }
17086                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17087                        && !app.killedByAm) {
17088                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17089                        try {
17090                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17091                                    "Trimming memory of " + app.processName
17092                                    + " to " + curLevel);
17093                            app.thread.scheduleTrimMemory(curLevel);
17094                        } catch (RemoteException e) {
17095                        }
17096                        if (false) {
17097                            // For now we won't do this; our memory trimming seems
17098                            // to be good enough at this point that destroying
17099                            // activities causes more harm than good.
17100                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17101                                    && app != mHomeProcess && app != mPreviousProcess) {
17102                                // Need to do this on its own message because the stack may not
17103                                // be in a consistent state at this point.
17104                                // For these apps we will also finish their activities
17105                                // to help them free memory.
17106                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17107                            }
17108                        }
17109                    }
17110                    app.trimMemoryLevel = curLevel;
17111                    step++;
17112                    if (step >= factor) {
17113                        step = 0;
17114                        switch (curLevel) {
17115                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17116                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17117                                break;
17118                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17119                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17120                                break;
17121                        }
17122                    }
17123                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17124                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17125                            && app.thread != null) {
17126                        try {
17127                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17128                                    "Trimming memory of heavy-weight " + app.processName
17129                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17130                            app.thread.scheduleTrimMemory(
17131                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17132                        } catch (RemoteException e) {
17133                        }
17134                    }
17135                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17136                } else {
17137                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17138                            || app.systemNoUi) && app.pendingUiClean) {
17139                        // If this application is now in the background and it
17140                        // had done UI, then give it the special trim level to
17141                        // have it free UI resources.
17142                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17143                        if (app.trimMemoryLevel < level && app.thread != null) {
17144                            try {
17145                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17146                                        "Trimming memory of bg-ui " + app.processName
17147                                        + " to " + level);
17148                                app.thread.scheduleTrimMemory(level);
17149                            } catch (RemoteException e) {
17150                            }
17151                        }
17152                        app.pendingUiClean = false;
17153                    }
17154                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17155                        try {
17156                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17157                                    "Trimming memory of fg " + app.processName
17158                                    + " to " + fgTrimLevel);
17159                            app.thread.scheduleTrimMemory(fgTrimLevel);
17160                        } catch (RemoteException e) {
17161                        }
17162                    }
17163                    app.trimMemoryLevel = fgTrimLevel;
17164                }
17165            }
17166        } else {
17167            if (mLowRamStartTime != 0) {
17168                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17169                mLowRamStartTime = 0;
17170            }
17171            for (int i=N-1; i>=0; i--) {
17172                ProcessRecord app = mLruProcesses.get(i);
17173                if (allChanged || app.procStateChanged) {
17174                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17175                    app.procStateChanged = false;
17176                }
17177                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17178                        || app.systemNoUi) && app.pendingUiClean) {
17179                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17180                            && app.thread != null) {
17181                        try {
17182                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17183                                    "Trimming memory of ui hidden " + app.processName
17184                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17185                            app.thread.scheduleTrimMemory(
17186                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17187                        } catch (RemoteException e) {
17188                        }
17189                    }
17190                    app.pendingUiClean = false;
17191                }
17192                app.trimMemoryLevel = 0;
17193            }
17194        }
17195
17196        if (mAlwaysFinishActivities) {
17197            // Need to do this on its own message because the stack may not
17198            // be in a consistent state at this point.
17199            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17200        }
17201
17202        if (allChanged) {
17203            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17204        }
17205
17206        if (mProcessStats.shouldWriteNowLocked(now)) {
17207            mHandler.post(new Runnable() {
17208                @Override public void run() {
17209                    synchronized (ActivityManagerService.this) {
17210                        mProcessStats.writeStateAsyncLocked();
17211                    }
17212                }
17213            });
17214        }
17215
17216        if (DEBUG_OOM_ADJ) {
17217            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17218        }
17219    }
17220
17221    final void trimApplications() {
17222        synchronized (this) {
17223            int i;
17224
17225            // First remove any unused application processes whose package
17226            // has been removed.
17227            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17228                final ProcessRecord app = mRemovedProcesses.get(i);
17229                if (app.activities.size() == 0
17230                        && app.curReceiver == null && app.services.size() == 0) {
17231                    Slog.i(
17232                        TAG, "Exiting empty application process "
17233                        + app.processName + " ("
17234                        + (app.thread != null ? app.thread.asBinder() : null)
17235                        + ")\n");
17236                    if (app.pid > 0 && app.pid != MY_PID) {
17237                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
17238                                app.processName, app.setAdj, "empty");
17239                        app.killedByAm = true;
17240                        Process.killProcessQuiet(app.pid);
17241                        Process.killProcessGroup(app.info.uid, app.pid);
17242                    } else {
17243                        try {
17244                            app.thread.scheduleExit();
17245                        } catch (Exception e) {
17246                            // Ignore exceptions.
17247                        }
17248                    }
17249                    cleanUpApplicationRecordLocked(app, false, true, -1);
17250                    mRemovedProcesses.remove(i);
17251
17252                    if (app.persistent) {
17253                        addAppLocked(app.info, false, null /* ABI override */);
17254                    }
17255                }
17256            }
17257
17258            // Now update the oom adj for all processes.
17259            updateOomAdjLocked();
17260        }
17261    }
17262
17263    /** This method sends the specified signal to each of the persistent apps */
17264    public void signalPersistentProcesses(int sig) throws RemoteException {
17265        if (sig != Process.SIGNAL_USR1) {
17266            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17267        }
17268
17269        synchronized (this) {
17270            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17271                    != PackageManager.PERMISSION_GRANTED) {
17272                throw new SecurityException("Requires permission "
17273                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17274            }
17275
17276            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17277                ProcessRecord r = mLruProcesses.get(i);
17278                if (r.thread != null && r.persistent) {
17279                    Process.sendSignal(r.pid, sig);
17280                }
17281            }
17282        }
17283    }
17284
17285    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17286        if (proc == null || proc == mProfileProc) {
17287            proc = mProfileProc;
17288            path = mProfileFile;
17289            profileType = mProfileType;
17290            clearProfilerLocked();
17291        }
17292        if (proc == null) {
17293            return;
17294        }
17295        try {
17296            proc.thread.profilerControl(false, path, null, profileType);
17297        } catch (RemoteException e) {
17298            throw new IllegalStateException("Process disappeared");
17299        }
17300    }
17301
17302    private void clearProfilerLocked() {
17303        if (mProfileFd != null) {
17304            try {
17305                mProfileFd.close();
17306            } catch (IOException e) {
17307            }
17308        }
17309        mProfileApp = null;
17310        mProfileProc = null;
17311        mProfileFile = null;
17312        mProfileType = 0;
17313        mAutoStopProfiler = false;
17314    }
17315
17316    public boolean profileControl(String process, int userId, boolean start,
17317            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17318
17319        try {
17320            synchronized (this) {
17321                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17322                // its own permission.
17323                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17324                        != PackageManager.PERMISSION_GRANTED) {
17325                    throw new SecurityException("Requires permission "
17326                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17327                }
17328
17329                if (start && fd == null) {
17330                    throw new IllegalArgumentException("null fd");
17331                }
17332
17333                ProcessRecord proc = null;
17334                if (process != null) {
17335                    proc = findProcessLocked(process, userId, "profileControl");
17336                }
17337
17338                if (start && (proc == null || proc.thread == null)) {
17339                    throw new IllegalArgumentException("Unknown process: " + process);
17340                }
17341
17342                if (start) {
17343                    stopProfilerLocked(null, null, 0);
17344                    setProfileApp(proc.info, proc.processName, path, fd, false);
17345                    mProfileProc = proc;
17346                    mProfileType = profileType;
17347                    try {
17348                        fd = fd.dup();
17349                    } catch (IOException e) {
17350                        fd = null;
17351                    }
17352                    proc.thread.profilerControl(start, path, fd, profileType);
17353                    fd = null;
17354                    mProfileFd = null;
17355                } else {
17356                    stopProfilerLocked(proc, path, profileType);
17357                    if (fd != null) {
17358                        try {
17359                            fd.close();
17360                        } catch (IOException e) {
17361                        }
17362                    }
17363                }
17364
17365                return true;
17366            }
17367        } catch (RemoteException e) {
17368            throw new IllegalStateException("Process disappeared");
17369        } finally {
17370            if (fd != null) {
17371                try {
17372                    fd.close();
17373                } catch (IOException e) {
17374                }
17375            }
17376        }
17377    }
17378
17379    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17380        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17381                userId, true, ALLOW_FULL_ONLY, callName, null);
17382        ProcessRecord proc = null;
17383        try {
17384            int pid = Integer.parseInt(process);
17385            synchronized (mPidsSelfLocked) {
17386                proc = mPidsSelfLocked.get(pid);
17387            }
17388        } catch (NumberFormatException e) {
17389        }
17390
17391        if (proc == null) {
17392            ArrayMap<String, SparseArray<ProcessRecord>> all
17393                    = mProcessNames.getMap();
17394            SparseArray<ProcessRecord> procs = all.get(process);
17395            if (procs != null && procs.size() > 0) {
17396                proc = procs.valueAt(0);
17397                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17398                    for (int i=1; i<procs.size(); i++) {
17399                        ProcessRecord thisProc = procs.valueAt(i);
17400                        if (thisProc.userId == userId) {
17401                            proc = thisProc;
17402                            break;
17403                        }
17404                    }
17405                }
17406            }
17407        }
17408
17409        return proc;
17410    }
17411
17412    public boolean dumpHeap(String process, int userId, boolean managed,
17413            String path, ParcelFileDescriptor fd) throws RemoteException {
17414
17415        try {
17416            synchronized (this) {
17417                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17418                // its own permission (same as profileControl).
17419                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17420                        != PackageManager.PERMISSION_GRANTED) {
17421                    throw new SecurityException("Requires permission "
17422                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17423                }
17424
17425                if (fd == null) {
17426                    throw new IllegalArgumentException("null fd");
17427                }
17428
17429                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17430                if (proc == null || proc.thread == null) {
17431                    throw new IllegalArgumentException("Unknown process: " + process);
17432                }
17433
17434                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17435                if (!isDebuggable) {
17436                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17437                        throw new SecurityException("Process not debuggable: " + proc);
17438                    }
17439                }
17440
17441                proc.thread.dumpHeap(managed, path, fd);
17442                fd = null;
17443                return true;
17444            }
17445        } catch (RemoteException e) {
17446            throw new IllegalStateException("Process disappeared");
17447        } finally {
17448            if (fd != null) {
17449                try {
17450                    fd.close();
17451                } catch (IOException e) {
17452                }
17453            }
17454        }
17455    }
17456
17457    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17458    public void monitor() {
17459        synchronized (this) { }
17460    }
17461
17462    void onCoreSettingsChange(Bundle settings) {
17463        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17464            ProcessRecord processRecord = mLruProcesses.get(i);
17465            try {
17466                if (processRecord.thread != null) {
17467                    processRecord.thread.setCoreSettings(settings);
17468                }
17469            } catch (RemoteException re) {
17470                /* ignore */
17471            }
17472        }
17473    }
17474
17475    // Multi-user methods
17476
17477    /**
17478     * Start user, if its not already running, but don't bring it to foreground.
17479     */
17480    @Override
17481    public boolean startUserInBackground(final int userId) {
17482        return startUser(userId, /* foreground */ false);
17483    }
17484
17485    /**
17486     * Start user, if its not already running, and bring it to foreground.
17487     */
17488    boolean startUserInForeground(final int userId, Dialog dlg) {
17489        boolean result = startUser(userId, /* foreground */ true);
17490        dlg.dismiss();
17491        return result;
17492    }
17493
17494    /**
17495     * Refreshes the list of users related to the current user when either a
17496     * user switch happens or when a new related user is started in the
17497     * background.
17498     */
17499    private void updateCurrentProfileIdsLocked() {
17500        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17501                mCurrentUserId, false /* enabledOnly */);
17502        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17503        for (int i = 0; i < currentProfileIds.length; i++) {
17504            currentProfileIds[i] = profiles.get(i).id;
17505        }
17506        mCurrentProfileIds = currentProfileIds;
17507
17508        synchronized (mUserProfileGroupIdsSelfLocked) {
17509            mUserProfileGroupIdsSelfLocked.clear();
17510            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17511            for (int i = 0; i < users.size(); i++) {
17512                UserInfo user = users.get(i);
17513                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17514                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17515                }
17516            }
17517        }
17518    }
17519
17520    private Set getProfileIdsLocked(int userId) {
17521        Set userIds = new HashSet<Integer>();
17522        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17523                userId, false /* enabledOnly */);
17524        for (UserInfo user : profiles) {
17525            userIds.add(Integer.valueOf(user.id));
17526        }
17527        return userIds;
17528    }
17529
17530    @Override
17531    public boolean switchUser(final int userId) {
17532        String userName;
17533        synchronized (this) {
17534            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17535            if (userInfo == null) {
17536                Slog.w(TAG, "No user info for user #" + userId);
17537                return false;
17538            }
17539            if (userInfo.isManagedProfile()) {
17540                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17541                return false;
17542            }
17543            userName = userInfo.name;
17544        }
17545        mHandler.removeMessages(START_USER_SWITCH_MSG);
17546        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17547        return true;
17548    }
17549
17550    private void showUserSwitchDialog(int userId, String userName) {
17551        // The dialog will show and then initiate the user switch by calling startUserInForeground
17552        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17553                true /* above system */);
17554        d.show();
17555    }
17556
17557    private boolean startUser(final int userId, boolean foreground) {
17558        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17559                != PackageManager.PERMISSION_GRANTED) {
17560            String msg = "Permission Denial: switchUser() from pid="
17561                    + Binder.getCallingPid()
17562                    + ", uid=" + Binder.getCallingUid()
17563                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17564            Slog.w(TAG, msg);
17565            throw new SecurityException(msg);
17566        }
17567
17568        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17569
17570        final long ident = Binder.clearCallingIdentity();
17571        try {
17572            synchronized (this) {
17573                final int oldUserId = mCurrentUserId;
17574                if (oldUserId == userId) {
17575                    return true;
17576                }
17577
17578                mStackSupervisor.setLockTaskModeLocked(null, false);
17579
17580                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17581                if (userInfo == null) {
17582                    Slog.w(TAG, "No user info for user #" + userId);
17583                    return false;
17584                }
17585                if (foreground && userInfo.isManagedProfile()) {
17586                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17587                    return false;
17588                }
17589
17590                if (foreground) {
17591                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17592                            R.anim.screen_user_enter);
17593                }
17594
17595                boolean needStart = false;
17596
17597                // If the user we are switching to is not currently started, then
17598                // we need to start it now.
17599                if (mStartedUsers.get(userId) == null) {
17600                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17601                    updateStartedUserArrayLocked();
17602                    needStart = true;
17603                }
17604
17605                final Integer userIdInt = Integer.valueOf(userId);
17606                mUserLru.remove(userIdInt);
17607                mUserLru.add(userIdInt);
17608
17609                if (foreground) {
17610                    mCurrentUserId = userId;
17611                    updateCurrentProfileIdsLocked();
17612                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17613                    // Once the internal notion of the active user has switched, we lock the device
17614                    // with the option to show the user switcher on the keyguard.
17615                    mWindowManager.lockNow(null);
17616                } else {
17617                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17618                    updateCurrentProfileIdsLocked();
17619                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17620                    mUserLru.remove(currentUserIdInt);
17621                    mUserLru.add(currentUserIdInt);
17622                }
17623
17624                final UserStartedState uss = mStartedUsers.get(userId);
17625
17626                // Make sure user is in the started state.  If it is currently
17627                // stopping, we need to knock that off.
17628                if (uss.mState == UserStartedState.STATE_STOPPING) {
17629                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17630                    // so we can just fairly silently bring the user back from
17631                    // the almost-dead.
17632                    uss.mState = UserStartedState.STATE_RUNNING;
17633                    updateStartedUserArrayLocked();
17634                    needStart = true;
17635                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17636                    // This means ACTION_SHUTDOWN has been sent, so we will
17637                    // need to treat this as a new boot of the user.
17638                    uss.mState = UserStartedState.STATE_BOOTING;
17639                    updateStartedUserArrayLocked();
17640                    needStart = true;
17641                }
17642
17643                if (uss.mState == UserStartedState.STATE_BOOTING) {
17644                    // Booting up a new user, need to tell system services about it.
17645                    // Note that this is on the same handler as scheduling of broadcasts,
17646                    // which is important because it needs to go first.
17647                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17648                }
17649
17650                if (foreground) {
17651                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17652                            oldUserId));
17653                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17654                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17655                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17656                            oldUserId, userId, uss));
17657                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17658                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17659                }
17660
17661                if (needStart) {
17662                    // Send USER_STARTED broadcast
17663                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17664                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17665                            | Intent.FLAG_RECEIVER_FOREGROUND);
17666                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17667                    broadcastIntentLocked(null, null, intent,
17668                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17669                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17670                }
17671
17672                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17673                    if (userId != UserHandle.USER_OWNER) {
17674                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17675                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17676                        broadcastIntentLocked(null, null, intent, null,
17677                                new IIntentReceiver.Stub() {
17678                                    public void performReceive(Intent intent, int resultCode,
17679                                            String data, Bundle extras, boolean ordered,
17680                                            boolean sticky, int sendingUser) {
17681                                        userInitialized(uss, userId);
17682                                    }
17683                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17684                                true, false, MY_PID, Process.SYSTEM_UID,
17685                                userId);
17686                        uss.initializing = true;
17687                    } else {
17688                        getUserManagerLocked().makeInitialized(userInfo.id);
17689                    }
17690                }
17691
17692                if (foreground) {
17693                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17694                    if (homeInFront) {
17695                        startHomeActivityLocked(userId);
17696                    } else {
17697                        mStackSupervisor.resumeTopActivitiesLocked();
17698                    }
17699                    EventLogTags.writeAmSwitchUser(userId);
17700                    getUserManagerLocked().userForeground(userId);
17701                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17702                } else {
17703                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17704                }
17705
17706                if (needStart) {
17707                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17708                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17709                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17710                    broadcastIntentLocked(null, null, intent,
17711                            null, new IIntentReceiver.Stub() {
17712                                @Override
17713                                public void performReceive(Intent intent, int resultCode, String data,
17714                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17715                                        throws RemoteException {
17716                                }
17717                            }, 0, null, null,
17718                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17719                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17720                }
17721            }
17722        } finally {
17723            Binder.restoreCallingIdentity(ident);
17724        }
17725
17726        return true;
17727    }
17728
17729    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17730        long ident = Binder.clearCallingIdentity();
17731        try {
17732            Intent intent;
17733            if (oldUserId >= 0) {
17734                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17735                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17736                int count = profiles.size();
17737                for (int i = 0; i < count; i++) {
17738                    int profileUserId = profiles.get(i).id;
17739                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17740                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17741                            | Intent.FLAG_RECEIVER_FOREGROUND);
17742                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17743                    broadcastIntentLocked(null, null, intent,
17744                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17745                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17746                }
17747            }
17748            if (newUserId >= 0) {
17749                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17750                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17751                int count = profiles.size();
17752                for (int i = 0; i < count; i++) {
17753                    int profileUserId = profiles.get(i).id;
17754                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17755                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17756                            | Intent.FLAG_RECEIVER_FOREGROUND);
17757                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17758                    broadcastIntentLocked(null, null, intent,
17759                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17760                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17761                }
17762                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17763                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17764                        | Intent.FLAG_RECEIVER_FOREGROUND);
17765                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17766                broadcastIntentLocked(null, null, intent,
17767                        null, null, 0, null, null,
17768                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17769                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17770            }
17771        } finally {
17772            Binder.restoreCallingIdentity(ident);
17773        }
17774    }
17775
17776    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17777            final int newUserId) {
17778        final int N = mUserSwitchObservers.beginBroadcast();
17779        if (N > 0) {
17780            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17781                int mCount = 0;
17782                @Override
17783                public void sendResult(Bundle data) throws RemoteException {
17784                    synchronized (ActivityManagerService.this) {
17785                        if (mCurUserSwitchCallback == this) {
17786                            mCount++;
17787                            if (mCount == N) {
17788                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17789                            }
17790                        }
17791                    }
17792                }
17793            };
17794            synchronized (this) {
17795                uss.switching = true;
17796                mCurUserSwitchCallback = callback;
17797            }
17798            for (int i=0; i<N; i++) {
17799                try {
17800                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17801                            newUserId, callback);
17802                } catch (RemoteException e) {
17803                }
17804            }
17805        } else {
17806            synchronized (this) {
17807                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17808            }
17809        }
17810        mUserSwitchObservers.finishBroadcast();
17811    }
17812
17813    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17814        synchronized (this) {
17815            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17816            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17817        }
17818    }
17819
17820    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17821        mCurUserSwitchCallback = null;
17822        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17823        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17824                oldUserId, newUserId, uss));
17825    }
17826
17827    void userInitialized(UserStartedState uss, int newUserId) {
17828        completeSwitchAndInitalize(uss, newUserId, true, false);
17829    }
17830
17831    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17832        completeSwitchAndInitalize(uss, newUserId, false, true);
17833    }
17834
17835    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17836            boolean clearInitializing, boolean clearSwitching) {
17837        boolean unfrozen = false;
17838        synchronized (this) {
17839            if (clearInitializing) {
17840                uss.initializing = false;
17841                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17842            }
17843            if (clearSwitching) {
17844                uss.switching = false;
17845            }
17846            if (!uss.switching && !uss.initializing) {
17847                mWindowManager.stopFreezingScreen();
17848                unfrozen = true;
17849            }
17850        }
17851        if (unfrozen) {
17852            final int N = mUserSwitchObservers.beginBroadcast();
17853            for (int i=0; i<N; i++) {
17854                try {
17855                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17856                } catch (RemoteException e) {
17857                }
17858            }
17859            mUserSwitchObservers.finishBroadcast();
17860        }
17861    }
17862
17863    void scheduleStartProfilesLocked() {
17864        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17865            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17866                    DateUtils.SECOND_IN_MILLIS);
17867        }
17868    }
17869
17870    void startProfilesLocked() {
17871        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17872        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17873                mCurrentUserId, false /* enabledOnly */);
17874        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17875        for (UserInfo user : profiles) {
17876            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17877                    && user.id != mCurrentUserId) {
17878                toStart.add(user);
17879            }
17880        }
17881        final int n = toStart.size();
17882        int i = 0;
17883        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17884            startUserInBackground(toStart.get(i).id);
17885        }
17886        if (i < n) {
17887            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17888        }
17889    }
17890
17891    void finishUserBoot(UserStartedState uss) {
17892        synchronized (this) {
17893            if (uss.mState == UserStartedState.STATE_BOOTING
17894                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17895                uss.mState = UserStartedState.STATE_RUNNING;
17896                final int userId = uss.mHandle.getIdentifier();
17897                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17898                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17899                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17900                broadcastIntentLocked(null, null, intent,
17901                        null, null, 0, null, null,
17902                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17903                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17904            }
17905        }
17906    }
17907
17908    void finishUserSwitch(UserStartedState uss) {
17909        synchronized (this) {
17910            finishUserBoot(uss);
17911
17912            startProfilesLocked();
17913
17914            int num = mUserLru.size();
17915            int i = 0;
17916            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17917                Integer oldUserId = mUserLru.get(i);
17918                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17919                if (oldUss == null) {
17920                    // Shouldn't happen, but be sane if it does.
17921                    mUserLru.remove(i);
17922                    num--;
17923                    continue;
17924                }
17925                if (oldUss.mState == UserStartedState.STATE_STOPPING
17926                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17927                    // This user is already stopping, doesn't count.
17928                    num--;
17929                    i++;
17930                    continue;
17931                }
17932                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17933                    // Owner and current can't be stopped, but count as running.
17934                    i++;
17935                    continue;
17936                }
17937                // This is a user to be stopped.
17938                stopUserLocked(oldUserId, null);
17939                num--;
17940                i++;
17941            }
17942        }
17943    }
17944
17945    @Override
17946    public int stopUser(final int userId, final IStopUserCallback callback) {
17947        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17948                != PackageManager.PERMISSION_GRANTED) {
17949            String msg = "Permission Denial: switchUser() from pid="
17950                    + Binder.getCallingPid()
17951                    + ", uid=" + Binder.getCallingUid()
17952                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17953            Slog.w(TAG, msg);
17954            throw new SecurityException(msg);
17955        }
17956        if (userId <= 0) {
17957            throw new IllegalArgumentException("Can't stop primary user " + userId);
17958        }
17959        synchronized (this) {
17960            return stopUserLocked(userId, callback);
17961        }
17962    }
17963
17964    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17965        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17966        if (mCurrentUserId == userId) {
17967            return ActivityManager.USER_OP_IS_CURRENT;
17968        }
17969
17970        final UserStartedState uss = mStartedUsers.get(userId);
17971        if (uss == null) {
17972            // User is not started, nothing to do...  but we do need to
17973            // callback if requested.
17974            if (callback != null) {
17975                mHandler.post(new Runnable() {
17976                    @Override
17977                    public void run() {
17978                        try {
17979                            callback.userStopped(userId);
17980                        } catch (RemoteException e) {
17981                        }
17982                    }
17983                });
17984            }
17985            return ActivityManager.USER_OP_SUCCESS;
17986        }
17987
17988        if (callback != null) {
17989            uss.mStopCallbacks.add(callback);
17990        }
17991
17992        if (uss.mState != UserStartedState.STATE_STOPPING
17993                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17994            uss.mState = UserStartedState.STATE_STOPPING;
17995            updateStartedUserArrayLocked();
17996
17997            long ident = Binder.clearCallingIdentity();
17998            try {
17999                // We are going to broadcast ACTION_USER_STOPPING and then
18000                // once that is done send a final ACTION_SHUTDOWN and then
18001                // stop the user.
18002                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18003                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18004                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18005                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18006                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18007                // This is the result receiver for the final shutdown broadcast.
18008                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18009                    @Override
18010                    public void performReceive(Intent intent, int resultCode, String data,
18011                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18012                        finishUserStop(uss);
18013                    }
18014                };
18015                // This is the result receiver for the initial stopping broadcast.
18016                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18017                    @Override
18018                    public void performReceive(Intent intent, int resultCode, String data,
18019                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18020                        // On to the next.
18021                        synchronized (ActivityManagerService.this) {
18022                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18023                                // Whoops, we are being started back up.  Abort, abort!
18024                                return;
18025                            }
18026                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18027                        }
18028                        mBatteryStatsService.noteEvent(
18029                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18030                                Integer.toString(userId), userId);
18031                        mSystemServiceManager.stopUser(userId);
18032                        broadcastIntentLocked(null, null, shutdownIntent,
18033                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18034                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18035                    }
18036                };
18037                // Kick things off.
18038                broadcastIntentLocked(null, null, stoppingIntent,
18039                        null, stoppingReceiver, 0, null, null,
18040                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18041                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18042            } finally {
18043                Binder.restoreCallingIdentity(ident);
18044            }
18045        }
18046
18047        return ActivityManager.USER_OP_SUCCESS;
18048    }
18049
18050    void finishUserStop(UserStartedState uss) {
18051        final int userId = uss.mHandle.getIdentifier();
18052        boolean stopped;
18053        ArrayList<IStopUserCallback> callbacks;
18054        synchronized (this) {
18055            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18056            if (mStartedUsers.get(userId) != uss) {
18057                stopped = false;
18058            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18059                stopped = false;
18060            } else {
18061                stopped = true;
18062                // User can no longer run.
18063                mStartedUsers.remove(userId);
18064                mUserLru.remove(Integer.valueOf(userId));
18065                updateStartedUserArrayLocked();
18066
18067                // Clean up all state and processes associated with the user.
18068                // Kill all the processes for the user.
18069                forceStopUserLocked(userId, "finish user");
18070            }
18071
18072            // Explicitly remove the old information in mRecentTasks.
18073            removeRecentTasksForUserLocked(userId);
18074        }
18075
18076        for (int i=0; i<callbacks.size(); i++) {
18077            try {
18078                if (stopped) callbacks.get(i).userStopped(userId);
18079                else callbacks.get(i).userStopAborted(userId);
18080            } catch (RemoteException e) {
18081            }
18082        }
18083
18084        if (stopped) {
18085            mSystemServiceManager.cleanupUser(userId);
18086            synchronized (this) {
18087                mStackSupervisor.removeUserLocked(userId);
18088            }
18089        }
18090    }
18091
18092    @Override
18093    public UserInfo getCurrentUser() {
18094        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18095                != PackageManager.PERMISSION_GRANTED) && (
18096                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18097                != PackageManager.PERMISSION_GRANTED)) {
18098            String msg = "Permission Denial: getCurrentUser() from pid="
18099                    + Binder.getCallingPid()
18100                    + ", uid=" + Binder.getCallingUid()
18101                    + " requires " + INTERACT_ACROSS_USERS;
18102            Slog.w(TAG, msg);
18103            throw new SecurityException(msg);
18104        }
18105        synchronized (this) {
18106            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18107        }
18108    }
18109
18110    int getCurrentUserIdLocked() {
18111        return mCurrentUserId;
18112    }
18113
18114    @Override
18115    public boolean isUserRunning(int userId, boolean orStopped) {
18116        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18117                != PackageManager.PERMISSION_GRANTED) {
18118            String msg = "Permission Denial: isUserRunning() from pid="
18119                    + Binder.getCallingPid()
18120                    + ", uid=" + Binder.getCallingUid()
18121                    + " requires " + INTERACT_ACROSS_USERS;
18122            Slog.w(TAG, msg);
18123            throw new SecurityException(msg);
18124        }
18125        synchronized (this) {
18126            return isUserRunningLocked(userId, orStopped);
18127        }
18128    }
18129
18130    boolean isUserRunningLocked(int userId, boolean orStopped) {
18131        UserStartedState state = mStartedUsers.get(userId);
18132        if (state == null) {
18133            return false;
18134        }
18135        if (orStopped) {
18136            return true;
18137        }
18138        return state.mState != UserStartedState.STATE_STOPPING
18139                && state.mState != UserStartedState.STATE_SHUTDOWN;
18140    }
18141
18142    @Override
18143    public int[] getRunningUserIds() {
18144        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18145                != PackageManager.PERMISSION_GRANTED) {
18146            String msg = "Permission Denial: isUserRunning() from pid="
18147                    + Binder.getCallingPid()
18148                    + ", uid=" + Binder.getCallingUid()
18149                    + " requires " + INTERACT_ACROSS_USERS;
18150            Slog.w(TAG, msg);
18151            throw new SecurityException(msg);
18152        }
18153        synchronized (this) {
18154            return mStartedUserArray;
18155        }
18156    }
18157
18158    private void updateStartedUserArrayLocked() {
18159        int num = 0;
18160        for (int i=0; i<mStartedUsers.size();  i++) {
18161            UserStartedState uss = mStartedUsers.valueAt(i);
18162            // This list does not include stopping users.
18163            if (uss.mState != UserStartedState.STATE_STOPPING
18164                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18165                num++;
18166            }
18167        }
18168        mStartedUserArray = new int[num];
18169        num = 0;
18170        for (int i=0; i<mStartedUsers.size();  i++) {
18171            UserStartedState uss = mStartedUsers.valueAt(i);
18172            if (uss.mState != UserStartedState.STATE_STOPPING
18173                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18174                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18175                num++;
18176            }
18177        }
18178    }
18179
18180    @Override
18181    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18182        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18183                != PackageManager.PERMISSION_GRANTED) {
18184            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18185                    + Binder.getCallingPid()
18186                    + ", uid=" + Binder.getCallingUid()
18187                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18188            Slog.w(TAG, msg);
18189            throw new SecurityException(msg);
18190        }
18191
18192        mUserSwitchObservers.register(observer);
18193    }
18194
18195    @Override
18196    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18197        mUserSwitchObservers.unregister(observer);
18198    }
18199
18200    private boolean userExists(int userId) {
18201        if (userId == 0) {
18202            return true;
18203        }
18204        UserManagerService ums = getUserManagerLocked();
18205        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18206    }
18207
18208    int[] getUsersLocked() {
18209        UserManagerService ums = getUserManagerLocked();
18210        return ums != null ? ums.getUserIds() : new int[] { 0 };
18211    }
18212
18213    UserManagerService getUserManagerLocked() {
18214        if (mUserManager == null) {
18215            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18216            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18217        }
18218        return mUserManager;
18219    }
18220
18221    private int applyUserId(int uid, int userId) {
18222        return UserHandle.getUid(userId, uid);
18223    }
18224
18225    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18226        if (info == null) return null;
18227        ApplicationInfo newInfo = new ApplicationInfo(info);
18228        newInfo.uid = applyUserId(info.uid, userId);
18229        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18230                + info.packageName;
18231        return newInfo;
18232    }
18233
18234    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18235        if (aInfo == null
18236                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18237            return aInfo;
18238        }
18239
18240        ActivityInfo info = new ActivityInfo(aInfo);
18241        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18242        return info;
18243    }
18244
18245    private final class LocalService extends ActivityManagerInternal {
18246        @Override
18247        public void goingToSleep() {
18248            ActivityManagerService.this.goingToSleep();
18249        }
18250
18251        @Override
18252        public void wakingUp() {
18253            ActivityManagerService.this.wakingUp();
18254        }
18255
18256        @Override
18257        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18258                String processName, String abiOverride, int uid, Runnable crashHandler) {
18259            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18260                    processName, abiOverride, uid, crashHandler);
18261        }
18262    }
18263
18264    /**
18265     * An implementation of IAppTask, that allows an app to manage its own tasks via
18266     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18267     * only the process that calls getAppTasks() can call the AppTask methods.
18268     */
18269    class AppTaskImpl extends IAppTask.Stub {
18270        private int mTaskId;
18271        private int mCallingUid;
18272
18273        public AppTaskImpl(int taskId, int callingUid) {
18274            mTaskId = taskId;
18275            mCallingUid = callingUid;
18276        }
18277
18278        private void checkCaller() {
18279            if (mCallingUid != Binder.getCallingUid()) {
18280                throw new SecurityException("Caller " + mCallingUid
18281                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18282            }
18283        }
18284
18285        @Override
18286        public void finishAndRemoveTask() {
18287            checkCaller();
18288
18289            synchronized (ActivityManagerService.this) {
18290                long origId = Binder.clearCallingIdentity();
18291                try {
18292                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18293                    if (tr != null) {
18294                        // Only kill the process if we are not a new document
18295                        int flags = tr.getBaseIntent().getFlags();
18296                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18297                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18298                        removeTaskByIdLocked(mTaskId,
18299                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18300                    }
18301                } finally {
18302                    Binder.restoreCallingIdentity(origId);
18303                }
18304            }
18305        }
18306
18307        @Override
18308        public ActivityManager.RecentTaskInfo getTaskInfo() {
18309            checkCaller();
18310
18311            synchronized (ActivityManagerService.this) {
18312                long origId = Binder.clearCallingIdentity();
18313                try {
18314                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18315                    if (tr != null) {
18316                        return createRecentTaskInfoFromTaskRecord(tr);
18317                    }
18318                } finally {
18319                    Binder.restoreCallingIdentity(origId);
18320                }
18321                return null;
18322            }
18323        }
18324
18325        @Override
18326        public void setExcludeFromRecents(boolean exclude) {
18327            checkCaller();
18328
18329            synchronized (ActivityManagerService.this) {
18330                long origId = Binder.clearCallingIdentity();
18331                try {
18332                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18333                    if (tr != null) {
18334                        Intent intent = tr.getBaseIntent();
18335                        if (exclude) {
18336                            intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18337                        } else {
18338                            intent.setFlags(intent.getFlags()
18339                                    & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18340                        }
18341                    }
18342                } finally {
18343                    Binder.restoreCallingIdentity(origId);
18344                }
18345            }
18346        }
18347    }
18348}
18349