ActivityManagerService.java revision 13420f2311757554c314f620c83cb55153b67612
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.content.pm.PackageManager.PERMISSION_GRANTED;
22import static com.android.internal.util.XmlUtils.readBooleanAttribute;
23import static com.android.internal.util.XmlUtils.readIntAttribute;
24import static com.android.internal.util.XmlUtils.readLongAttribute;
25import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
26import static com.android.internal.util.XmlUtils.writeIntAttribute;
27import static com.android.internal.util.XmlUtils.writeLongAttribute;
28import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
29import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
30import static org.xmlpull.v1.XmlPullParser.START_TAG;
31import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32
33import android.Manifest;
34import android.app.AppOpsManager;
35import android.app.IActivityContainer;
36import android.app.IActivityContainerCallback;
37import android.app.IAppTask;
38import android.app.admin.DevicePolicyManager;
39import android.app.usage.UsageStats;
40import android.app.usage.UsageStatsManagerInternal;
41import android.appwidget.AppWidgetManager;
42import android.graphics.Rect;
43import android.os.BatteryStats;
44import android.os.PersistableBundle;
45import android.service.voice.IVoiceInteractionSession;
46import android.util.ArrayMap;
47import android.util.ArraySet;
48
49import android.util.SparseIntArray;
50import com.android.internal.R;
51import com.android.internal.annotations.GuardedBy;
52import com.android.internal.app.IAppOpsService;
53import com.android.internal.app.IVoiceInteractor;
54import com.android.internal.app.ProcessMap;
55import com.android.internal.app.ProcessStats;
56import com.android.internal.content.PackageMonitor;
57import com.android.internal.os.BackgroundThread;
58import com.android.internal.os.BatteryStatsImpl;
59import com.android.internal.os.ProcessCpuTracker;
60import com.android.internal.os.TransferPipe;
61import com.android.internal.os.Zygote;
62import com.android.internal.util.FastPrintWriter;
63import com.android.internal.util.FastXmlSerializer;
64import com.android.internal.util.MemInfoReader;
65import com.android.internal.util.Preconditions;
66import com.android.server.AppOpsService;
67import com.android.server.AttributeCache;
68import com.android.server.IntentResolver;
69import com.android.server.LocalServices;
70import com.android.server.ServiceThread;
71import com.android.server.SystemService;
72import com.android.server.SystemServiceManager;
73import com.android.server.Watchdog;
74import com.android.server.am.ActivityStack.ActivityState;
75import com.android.server.firewall.IntentFirewall;
76import com.android.server.pm.UserManagerService;
77import com.android.server.wm.AppTransition;
78import com.android.server.wm.WindowManagerService;
79import com.google.android.collect.Lists;
80import com.google.android.collect.Maps;
81
82import libcore.io.IoUtils;
83
84import org.xmlpull.v1.XmlPullParser;
85import org.xmlpull.v1.XmlPullParserException;
86import org.xmlpull.v1.XmlSerializer;
87
88import android.app.Activity;
89import android.app.ActivityManager;
90import android.app.ActivityManager.RunningTaskInfo;
91import android.app.ActivityManager.StackInfo;
92import android.app.ActivityManagerInternal;
93import android.app.ActivityManagerNative;
94import android.app.ActivityOptions;
95import android.app.ActivityThread;
96import android.app.AlertDialog;
97import android.app.AppGlobals;
98import android.app.ApplicationErrorReport;
99import android.app.Dialog;
100import android.app.IActivityController;
101import android.app.IApplicationThread;
102import android.app.IInstrumentationWatcher;
103import android.app.INotificationManager;
104import android.app.IProcessObserver;
105import android.app.IServiceConnection;
106import android.app.IStopUserCallback;
107import android.app.IUiAutomationConnection;
108import android.app.IUserSwitchObserver;
109import android.app.Instrumentation;
110import android.app.Notification;
111import android.app.NotificationManager;
112import android.app.PendingIntent;
113import android.app.backup.IBackupManager;
114import android.content.ActivityNotFoundException;
115import android.content.BroadcastReceiver;
116import android.content.ClipData;
117import android.content.ComponentCallbacks2;
118import android.content.ComponentName;
119import android.content.ContentProvider;
120import android.content.ContentResolver;
121import android.content.Context;
122import android.content.DialogInterface;
123import android.content.IContentProvider;
124import android.content.IIntentReceiver;
125import android.content.IIntentSender;
126import android.content.Intent;
127import android.content.IntentFilter;
128import android.content.IntentSender;
129import android.content.pm.ActivityInfo;
130import android.content.pm.ApplicationInfo;
131import android.content.pm.ConfigurationInfo;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageManager;
134import android.content.pm.InstrumentationInfo;
135import android.content.pm.PackageInfo;
136import android.content.pm.PackageManager;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.UserInfo;
139import android.content.pm.PackageManager.NameNotFoundException;
140import android.content.pm.PathPermission;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.net.Proxy;
147import android.net.ProxyInfo;
148import android.net.Uri;
149import android.os.Binder;
150import android.os.Build;
151import android.os.Bundle;
152import android.os.Debug;
153import android.os.DropBoxManager;
154import android.os.Environment;
155import android.os.FactoryTest;
156import android.os.FileObserver;
157import android.os.FileUtils;
158import android.os.Handler;
159import android.os.IBinder;
160import android.os.IPermissionController;
161import android.os.IRemoteCallback;
162import android.os.IUserManager;
163import android.os.Looper;
164import android.os.Message;
165import android.os.Parcel;
166import android.os.ParcelFileDescriptor;
167import android.os.Process;
168import android.os.RemoteCallbackList;
169import android.os.RemoteException;
170import android.os.SELinux;
171import android.os.ServiceManager;
172import android.os.StrictMode;
173import android.os.SystemClock;
174import android.os.SystemProperties;
175import android.os.UpdateLock;
176import android.os.UserHandle;
177import android.provider.Settings;
178import android.text.format.DateUtils;
179import android.text.format.Time;
180import android.util.AtomicFile;
181import android.util.EventLog;
182import android.util.Log;
183import android.util.Pair;
184import android.util.PrintWriterPrinter;
185import android.util.Slog;
186import android.util.SparseArray;
187import android.util.TimeUtils;
188import android.util.Xml;
189import android.view.Gravity;
190import android.view.LayoutInflater;
191import android.view.View;
192import android.view.WindowManager;
193
194import java.io.BufferedInputStream;
195import java.io.BufferedOutputStream;
196import java.io.DataInputStream;
197import java.io.DataOutputStream;
198import java.io.File;
199import java.io.FileDescriptor;
200import java.io.FileInputStream;
201import java.io.FileNotFoundException;
202import java.io.FileOutputStream;
203import java.io.IOException;
204import java.io.InputStreamReader;
205import java.io.PrintWriter;
206import java.io.StringWriter;
207import java.lang.ref.WeakReference;
208import java.util.ArrayList;
209import java.util.Arrays;
210import java.util.Collections;
211import java.util.Comparator;
212import java.util.HashMap;
213import java.util.HashSet;
214import java.util.Iterator;
215import java.util.List;
216import java.util.Locale;
217import java.util.Map;
218import java.util.Set;
219import java.util.concurrent.atomic.AtomicBoolean;
220import java.util.concurrent.atomic.AtomicLong;
221
222public final class ActivityManagerService extends ActivityManagerNative
223        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
224    private static final String USER_DATA_DIR = "/data/user/";
225    static final String TAG = "ActivityManager";
226    static final String TAG_MU = "ActivityManagerServiceMU";
227    static final boolean DEBUG = false;
228    static final boolean localLOGV = DEBUG;
229    static final boolean DEBUG_BACKUP = localLOGV || false;
230    static final boolean DEBUG_BROADCAST = localLOGV || false;
231    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
232    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
233    static final boolean DEBUG_CLEANUP = localLOGV || false;
234    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
235    static final boolean DEBUG_FOCUS = false;
236    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
237    static final boolean DEBUG_MU = localLOGV || false;
238    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
239    static final boolean DEBUG_LRU = localLOGV || false;
240    static final boolean DEBUG_PAUSE = localLOGV || false;
241    static final boolean DEBUG_POWER = localLOGV || false;
242    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
243    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
244    static final boolean DEBUG_PROCESSES = localLOGV || false;
245    static final boolean DEBUG_PROVIDER = localLOGV || false;
246    static final boolean DEBUG_RESULTS = localLOGV || false;
247    static final boolean DEBUG_SERVICE = localLOGV || false;
248    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
249    static final boolean DEBUG_STACK = localLOGV || false;
250    static final boolean DEBUG_SWITCH = localLOGV || false;
251    static final boolean DEBUG_TASKS = localLOGV || false;
252    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
253    static final boolean DEBUG_TRANSITION = localLOGV || false;
254    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
255    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
256    static final boolean DEBUG_VISBILITY = localLOGV || false;
257    static final boolean DEBUG_PSS = localLOGV || false;
258    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
259    static final boolean VALIDATE_TOKENS = false;
260    static final boolean SHOW_ACTIVITY_START_TIME = true;
261
262    // Control over CPU and battery monitoring.
263    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
264    static final boolean MONITOR_CPU_USAGE = true;
265    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
266    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
267    static final boolean MONITOR_THREAD_CPU_USAGE = false;
268
269    // The flags that are set for all calls we make to the package manager.
270    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
271
272    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
273
274    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
275
276    // Maximum number of recent tasks that we can remember.
277    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
278
279    // Maximum number recent bitmaps to keep in memory.
280    static final int MAX_RECENT_BITMAPS = 5;
281
282    // Amount of time after a call to stopAppSwitches() during which we will
283    // prevent further untrusted switches from happening.
284    static final long APP_SWITCH_DELAY_TIME = 5*1000;
285
286    // How long we wait for a launched process to attach to the activity manager
287    // before we decide it's never going to come up for real.
288    static final int PROC_START_TIMEOUT = 10*1000;
289
290    // How long we wait for a launched process to attach to the activity manager
291    // before we decide it's never going to come up for real, when the process was
292    // started with a wrapper for instrumentation (such as Valgrind) because it
293    // could take much longer than usual.
294    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
295
296    // How long to wait after going idle before forcing apps to GC.
297    static final int GC_TIMEOUT = 5*1000;
298
299    // The minimum amount of time between successive GC requests for a process.
300    static final int GC_MIN_INTERVAL = 60*1000;
301
302    // The minimum amount of time between successive PSS requests for a process.
303    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
304
305    // The minimum amount of time between successive PSS requests for a process
306    // when the request is due to the memory state being lowered.
307    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
308
309    // The rate at which we check for apps using excessive power -- 15 mins.
310    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
311
312    // The minimum sample duration we will allow before deciding we have
313    // enough data on wake locks to start killing things.
314    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
315
316    // The minimum sample duration we will allow before deciding we have
317    // enough data on CPU usage to start killing things.
318    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
319
320    // How long we allow a receiver to run before giving up on it.
321    static final int BROADCAST_FG_TIMEOUT = 10*1000;
322    static final int BROADCAST_BG_TIMEOUT = 60*1000;
323
324    // How long we wait until we timeout on key dispatching.
325    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
326
327    // How long we wait until we timeout on key dispatching during instrumentation.
328    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
329
330    // Amount of time we wait for observers to handle a user switch before
331    // giving up on them and unfreezing the screen.
332    static final int USER_SWITCH_TIMEOUT = 2*1000;
333
334    // Maximum number of users we allow to be running at a time.
335    static final int MAX_RUNNING_USERS = 3;
336
337    // How long to wait in getAssistContextExtras for the activity and foreground services
338    // to respond with the result.
339    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
340
341    // Maximum number of persisted Uri grants a package is allowed
342    static final int MAX_PERSISTED_URI_GRANTS = 128;
343
344    static final int MY_PID = Process.myPid();
345
346    static final String[] EMPTY_STRING_ARRAY = new String[0];
347
348    // How many bytes to write into the dropbox log before truncating
349    static final int DROPBOX_MAX_SIZE = 256 * 1024;
350
351    // Access modes for handleIncomingUser.
352    static final int ALLOW_NON_FULL = 0;
353    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
354    static final int ALLOW_FULL_ONLY = 2;
355
356    /** All system services */
357    SystemServiceManager mSystemServiceManager;
358
359    /** Run all ActivityStacks through this */
360    ActivityStackSupervisor mStackSupervisor;
361
362    public IntentFirewall mIntentFirewall;
363
364    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
365    // default actuion automatically.  Important for devices without direct input
366    // devices.
367    private boolean mShowDialogs = true;
368
369    BroadcastQueue mFgBroadcastQueue;
370    BroadcastQueue mBgBroadcastQueue;
371    // Convenient for easy iteration over the queues. Foreground is first
372    // so that dispatch of foreground broadcasts gets precedence.
373    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
374
375    BroadcastQueue broadcastQueueForIntent(Intent intent) {
376        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
377        if (DEBUG_BACKGROUND_BROADCAST) {
378            Slog.i(TAG, "Broadcast intent " + intent + " on "
379                    + (isFg ? "foreground" : "background")
380                    + " queue");
381        }
382        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
383    }
384
385    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
386        for (BroadcastQueue queue : mBroadcastQueues) {
387            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
388            if (r != null) {
389                return r;
390            }
391        }
392        return null;
393    }
394
395    /**
396     * Activity we have told the window manager to have key focus.
397     */
398    ActivityRecord mFocusedActivity = null;
399
400    /**
401     * List of intents that were used to start the most recent tasks.
402     */
403    ArrayList<TaskRecord> mRecentTasks;
404    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
405
406    public class PendingAssistExtras extends Binder implements Runnable {
407        public final ActivityRecord activity;
408        public boolean haveResult = false;
409        public Bundle result = null;
410        public PendingAssistExtras(ActivityRecord _activity) {
411            activity = _activity;
412        }
413        @Override
414        public void run() {
415            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
416            synchronized (this) {
417                haveResult = true;
418                notifyAll();
419            }
420        }
421    }
422
423    final ArrayList<PendingAssistExtras> mPendingAssistExtras
424            = new ArrayList<PendingAssistExtras>();
425
426    /**
427     * Process management.
428     */
429    final ProcessList mProcessList = new ProcessList();
430
431    /**
432     * All of the applications we currently have running organized by name.
433     * The keys are strings of the application package name (as
434     * returned by the package manager), and the keys are ApplicationRecord
435     * objects.
436     */
437    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
438
439    /**
440     * Tracking long-term execution of processes to look for abuse and other
441     * bad app behavior.
442     */
443    final ProcessStatsService mProcessStats;
444
445    /**
446     * The currently running isolated processes.
447     */
448    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
449
450    /**
451     * Counter for assigning isolated process uids, to avoid frequently reusing the
452     * same ones.
453     */
454    int mNextIsolatedProcessUid = 0;
455
456    /**
457     * The currently running heavy-weight process, if any.
458     */
459    ProcessRecord mHeavyWeightProcess = null;
460
461    /**
462     * The last time that various processes have crashed.
463     */
464    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
465
466    /**
467     * Information about a process that is currently marked as bad.
468     */
469    static final class BadProcessInfo {
470        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
471            this.time = time;
472            this.shortMsg = shortMsg;
473            this.longMsg = longMsg;
474            this.stack = stack;
475        }
476
477        final long time;
478        final String shortMsg;
479        final String longMsg;
480        final String stack;
481    }
482
483    /**
484     * Set of applications that we consider to be bad, and will reject
485     * incoming broadcasts from (which the user has no control over).
486     * Processes are added to this set when they have crashed twice within
487     * a minimum amount of time; they are removed from it when they are
488     * later restarted (hopefully due to some user action).  The value is the
489     * time it was added to the list.
490     */
491    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
492
493    /**
494     * All of the processes we currently have running organized by pid.
495     * The keys are the pid running the application.
496     *
497     * <p>NOTE: This object is protected by its own lock, NOT the global
498     * activity manager lock!
499     */
500    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
501
502    /**
503     * All of the processes that have been forced to be foreground.  The key
504     * is the pid of the caller who requested it (we hold a death
505     * link on it).
506     */
507    abstract class ForegroundToken implements IBinder.DeathRecipient {
508        int pid;
509        IBinder token;
510    }
511    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
512
513    /**
514     * List of records for processes that someone had tried to start before the
515     * system was ready.  We don't start them at that point, but ensure they
516     * are started by the time booting is complete.
517     */
518    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
519
520    /**
521     * List of persistent applications that are in the process
522     * of being started.
523     */
524    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * Processes that are being forcibly torn down.
528     */
529    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
530
531    /**
532     * List of running applications, sorted by recent usage.
533     * The first entry in the list is the least recently used.
534     */
535    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
536
537    /**
538     * Where in mLruProcesses that the processes hosting activities start.
539     */
540    int mLruProcessActivityStart = 0;
541
542    /**
543     * Where in mLruProcesses that the processes hosting services start.
544     * This is after (lower index) than mLruProcessesActivityStart.
545     */
546    int mLruProcessServiceStart = 0;
547
548    /**
549     * List of processes that should gc as soon as things are idle.
550     */
551    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
552
553    /**
554     * Processes we want to collect PSS data from.
555     */
556    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
557
558    /**
559     * Last time we requested PSS data of all processes.
560     */
561    long mLastFullPssTime = SystemClock.uptimeMillis();
562
563    /**
564     * If set, the next time we collect PSS data we should do a full collection
565     * with data from native processes and the kernel.
566     */
567    boolean mFullPssPending = false;
568
569    /**
570     * This is the process holding what we currently consider to be
571     * the "home" activity.
572     */
573    ProcessRecord mHomeProcess;
574
575    /**
576     * This is the process holding the activity the user last visited that
577     * is in a different process from the one they are currently in.
578     */
579    ProcessRecord mPreviousProcess;
580
581    /**
582     * The time at which the previous process was last visible.
583     */
584    long mPreviousProcessVisibleTime;
585
586    /**
587     * Which uses have been started, so are allowed to run code.
588     */
589    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
590
591    /**
592     * LRU list of history of current users.  Most recently current is at the end.
593     */
594    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
595
596    /**
597     * Constant array of the users that are currently started.
598     */
599    int[] mStartedUserArray = new int[] { 0 };
600
601    /**
602     * Registered observers of the user switching mechanics.
603     */
604    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
605            = new RemoteCallbackList<IUserSwitchObserver>();
606
607    /**
608     * Currently active user switch.
609     */
610    Object mCurUserSwitchCallback;
611
612    /**
613     * Packages that the user has asked to have run in screen size
614     * compatibility mode instead of filling the screen.
615     */
616    final CompatModePackages mCompatModePackages;
617
618    /**
619     * Set of IntentSenderRecord objects that are currently active.
620     */
621    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
622            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
623
624    /**
625     * Fingerprints (hashCode()) of stack traces that we've
626     * already logged DropBox entries for.  Guarded by itself.  If
627     * something (rogue user app) forces this over
628     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
629     */
630    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
631    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
632
633    /**
634     * Strict Mode background batched logging state.
635     *
636     * The string buffer is guarded by itself, and its lock is also
637     * used to determine if another batched write is already
638     * in-flight.
639     */
640    private final StringBuilder mStrictModeBuffer = new StringBuilder();
641
642    /**
643     * Keeps track of all IIntentReceivers that have been registered for
644     * broadcasts.  Hash keys are the receiver IBinder, hash value is
645     * a ReceiverList.
646     */
647    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
648            new HashMap<IBinder, ReceiverList>();
649
650    /**
651     * Resolver for broadcast intents to registered receivers.
652     * Holds BroadcastFilter (subclass of IntentFilter).
653     */
654    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
655            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
656        @Override
657        protected boolean allowFilterResult(
658                BroadcastFilter filter, List<BroadcastFilter> dest) {
659            IBinder target = filter.receiverList.receiver.asBinder();
660            for (int i=dest.size()-1; i>=0; i--) {
661                if (dest.get(i).receiverList.receiver.asBinder() == target) {
662                    return false;
663                }
664            }
665            return true;
666        }
667
668        @Override
669        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
670            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
671                    || userId == filter.owningUserId) {
672                return super.newResult(filter, match, userId);
673            }
674            return null;
675        }
676
677        @Override
678        protected BroadcastFilter[] newArray(int size) {
679            return new BroadcastFilter[size];
680        }
681
682        @Override
683        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
684            return packageName.equals(filter.packageName);
685        }
686    };
687
688    /**
689     * State of all active sticky broadcasts per user.  Keys are the action of the
690     * sticky Intent, values are an ArrayList of all broadcasted intents with
691     * that action (which should usually be one).  The SparseArray is keyed
692     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
693     * for stickies that are sent to all users.
694     */
695    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
696            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
697
698    final ActiveServices mServices;
699
700    /**
701     * Backup/restore process management
702     */
703    String mBackupAppName = null;
704    BackupRecord mBackupTarget = null;
705
706    final ProviderMap mProviderMap;
707
708    /**
709     * List of content providers who have clients waiting for them.  The
710     * application is currently being launched and the provider will be
711     * removed from this list once it is published.
712     */
713    final ArrayList<ContentProviderRecord> mLaunchingProviders
714            = new ArrayList<ContentProviderRecord>();
715
716    /**
717     * File storing persisted {@link #mGrantedUriPermissions}.
718     */
719    private final AtomicFile mGrantFile;
720
721    /** XML constants used in {@link #mGrantFile} */
722    private static final String TAG_URI_GRANTS = "uri-grants";
723    private static final String TAG_URI_GRANT = "uri-grant";
724    private static final String ATTR_USER_HANDLE = "userHandle";
725    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
726    private static final String ATTR_TARGET_USER_ID = "targetUserId";
727    private static final String ATTR_SOURCE_PKG = "sourcePkg";
728    private static final String ATTR_TARGET_PKG = "targetPkg";
729    private static final String ATTR_URI = "uri";
730    private static final String ATTR_MODE_FLAGS = "modeFlags";
731    private static final String ATTR_CREATED_TIME = "createdTime";
732    private static final String ATTR_PREFIX = "prefix";
733
734    /**
735     * Global set of specific {@link Uri} permissions that have been granted.
736     * This optimized lookup structure maps from {@link UriPermission#targetUid}
737     * to {@link UriPermission#uri} to {@link UriPermission}.
738     */
739    @GuardedBy("this")
740    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
741            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
742
743    public static class GrantUri {
744        public final int sourceUserId;
745        public final Uri uri;
746        public boolean prefix;
747
748        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
749            this.sourceUserId = sourceUserId;
750            this.uri = uri;
751            this.prefix = prefix;
752        }
753
754        @Override
755        public int hashCode() {
756            return toString().hashCode();
757        }
758
759        @Override
760        public boolean equals(Object o) {
761            if (o instanceof GrantUri) {
762                GrantUri other = (GrantUri) o;
763                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
764                        && prefix == other.prefix;
765            }
766            return false;
767        }
768
769        @Override
770        public String toString() {
771            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
772            if (prefix) result += " [prefix]";
773            return result;
774        }
775
776        public String toSafeString() {
777            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
778            if (prefix) result += " [prefix]";
779            return result;
780        }
781
782        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
783            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
784                    ContentProvider.getUriWithoutUserId(uri), false);
785        }
786    }
787
788    CoreSettingsObserver mCoreSettingsObserver;
789
790    /**
791     * Thread-local storage used to carry caller permissions over through
792     * indirect content-provider access.
793     */
794    private class Identity {
795        public int pid;
796        public int uid;
797
798        Identity(int _pid, int _uid) {
799            pid = _pid;
800            uid = _uid;
801        }
802    }
803
804    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
805
806    /**
807     * All information we have collected about the runtime performance of
808     * any user id that can impact battery performance.
809     */
810    final BatteryStatsService mBatteryStatsService;
811
812    /**
813     * Information about component usage
814     */
815    UsageStatsManagerInternal mUsageStatsService;
816
817    /**
818     * Information about and control over application operations
819     */
820    final AppOpsService mAppOpsService;
821
822    /**
823     * Save recent tasks information across reboots.
824     */
825    final TaskPersister mTaskPersister;
826
827    /**
828     * Current configuration information.  HistoryRecord objects are given
829     * a reference to this object to indicate which configuration they are
830     * currently running in, so this object must be kept immutable.
831     */
832    Configuration mConfiguration = new Configuration();
833
834    /**
835     * Current sequencing integer of the configuration, for skipping old
836     * configurations.
837     */
838    int mConfigurationSeq = 0;
839
840    /**
841     * Hardware-reported OpenGLES version.
842     */
843    final int GL_ES_VERSION;
844
845    /**
846     * List of initialization arguments to pass to all processes when binding applications to them.
847     * For example, references to the commonly used services.
848     */
849    HashMap<String, IBinder> mAppBindArgs;
850
851    /**
852     * Temporary to avoid allocations.  Protected by main lock.
853     */
854    final StringBuilder mStringBuilder = new StringBuilder(256);
855
856    /**
857     * Used to control how we initialize the service.
858     */
859    ComponentName mTopComponent;
860    String mTopAction = Intent.ACTION_MAIN;
861    String mTopData;
862    boolean mProcessesReady = false;
863    boolean mSystemReady = false;
864    boolean mBooting = false;
865    boolean mWaitingUpdate = false;
866    boolean mDidUpdate = false;
867    boolean mOnBattery = false;
868    boolean mLaunchWarningShown = false;
869
870    Context mContext;
871
872    int mFactoryTest;
873
874    boolean mCheckedForSetup;
875
876    /**
877     * The time at which we will allow normal application switches again,
878     * after a call to {@link #stopAppSwitches()}.
879     */
880    long mAppSwitchesAllowedTime;
881
882    /**
883     * This is set to true after the first switch after mAppSwitchesAllowedTime
884     * is set; any switches after that will clear the time.
885     */
886    boolean mDidAppSwitch;
887
888    /**
889     * Last time (in realtime) at which we checked for power usage.
890     */
891    long mLastPowerCheckRealtime;
892
893    /**
894     * Last time (in uptime) at which we checked for power usage.
895     */
896    long mLastPowerCheckUptime;
897
898    /**
899     * Set while we are wanting to sleep, to prevent any
900     * activities from being started/resumed.
901     */
902    private boolean mSleeping = false;
903
904    /**
905     * Set while we are running a voice interaction.  This overrides
906     * sleeping while it is active.
907     */
908    private boolean mRunningVoice = false;
909
910    /**
911     * State of external calls telling us if the device is asleep.
912     */
913    private boolean mWentToSleep = false;
914
915    /**
916     * State of external call telling us if the lock screen is shown.
917     */
918    private boolean mLockScreenShown = false;
919
920    /**
921     * Set if we are shutting down the system, similar to sleeping.
922     */
923    boolean mShuttingDown = false;
924
925    /**
926     * Current sequence id for oom_adj computation traversal.
927     */
928    int mAdjSeq = 0;
929
930    /**
931     * Current sequence id for process LRU updating.
932     */
933    int mLruSeq = 0;
934
935    /**
936     * Keep track of the non-cached/empty process we last found, to help
937     * determine how to distribute cached/empty processes next time.
938     */
939    int mNumNonCachedProcs = 0;
940
941    /**
942     * Keep track of the number of cached hidden procs, to balance oom adj
943     * distribution between those and empty procs.
944     */
945    int mNumCachedHiddenProcs = 0;
946
947    /**
948     * Keep track of the number of service processes we last found, to
949     * determine on the next iteration which should be B services.
950     */
951    int mNumServiceProcs = 0;
952    int mNewNumAServiceProcs = 0;
953    int mNewNumServiceProcs = 0;
954
955    /**
956     * Allow the current computed overall memory level of the system to go down?
957     * This is set to false when we are killing processes for reasons other than
958     * memory management, so that the now smaller process list will not be taken as
959     * an indication that memory is tighter.
960     */
961    boolean mAllowLowerMemLevel = false;
962
963    /**
964     * The last computed memory level, for holding when we are in a state that
965     * processes are going away for other reasons.
966     */
967    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
968
969    /**
970     * The last total number of process we have, to determine if changes actually look
971     * like a shrinking number of process due to lower RAM.
972     */
973    int mLastNumProcesses;
974
975    /**
976     * The uptime of the last time we performed idle maintenance.
977     */
978    long mLastIdleTime = SystemClock.uptimeMillis();
979
980    /**
981     * Total time spent with RAM that has been added in the past since the last idle time.
982     */
983    long mLowRamTimeSinceLastIdle = 0;
984
985    /**
986     * If RAM is currently low, when that horrible situation started.
987     */
988    long mLowRamStartTime = 0;
989
990    /**
991     * For reporting to battery stats the current top application.
992     */
993    private String mCurResumedPackage = null;
994    private int mCurResumedUid = -1;
995
996    /**
997     * For reporting to battery stats the apps currently running foreground
998     * service.  The ProcessMap is package/uid tuples; each of these contain
999     * an array of the currently foreground processes.
1000     */
1001    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1002            = new ProcessMap<ArrayList<ProcessRecord>>();
1003
1004    /**
1005     * This is set if we had to do a delayed dexopt of an app before launching
1006     * it, to increase the ANR timeouts in that case.
1007     */
1008    boolean mDidDexOpt;
1009
1010    /**
1011     * Set if the systemServer made a call to enterSafeMode.
1012     */
1013    boolean mSafeMode;
1014
1015    String mDebugApp = null;
1016    boolean mWaitForDebugger = false;
1017    boolean mDebugTransient = false;
1018    String mOrigDebugApp = null;
1019    boolean mOrigWaitForDebugger = false;
1020    boolean mAlwaysFinishActivities = false;
1021    IActivityController mController = null;
1022    String mProfileApp = null;
1023    ProcessRecord mProfileProc = null;
1024    String mProfileFile;
1025    ParcelFileDescriptor mProfileFd;
1026    int mProfileType = 0;
1027    boolean mAutoStopProfiler = false;
1028    String mOpenGlTraceApp = null;
1029
1030    static class ProcessChangeItem {
1031        static final int CHANGE_ACTIVITIES = 1<<0;
1032        static final int CHANGE_PROCESS_STATE = 1<<1;
1033        int changes;
1034        int uid;
1035        int pid;
1036        int processState;
1037        boolean foregroundActivities;
1038    }
1039
1040    final RemoteCallbackList<IProcessObserver> mProcessObservers
1041            = new RemoteCallbackList<IProcessObserver>();
1042    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1043
1044    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1045            = new ArrayList<ProcessChangeItem>();
1046    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1047            = new ArrayList<ProcessChangeItem>();
1048
1049    /**
1050     * Runtime CPU use collection thread.  This object's lock is used to
1051     * protect all related state.
1052     */
1053    final Thread mProcessCpuThread;
1054
1055    /**
1056     * Used to collect process stats when showing not responding dialog.
1057     * Protected by mProcessCpuThread.
1058     */
1059    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1060            MONITOR_THREAD_CPU_USAGE);
1061    final AtomicLong mLastCpuTime = new AtomicLong(0);
1062    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1063
1064    long mLastWriteTime = 0;
1065
1066    /**
1067     * Used to retain an update lock when the foreground activity is in
1068     * immersive mode.
1069     */
1070    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1071
1072    /**
1073     * Set to true after the system has finished booting.
1074     */
1075    boolean mBooted = false;
1076
1077    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1078    int mProcessLimitOverride = -1;
1079
1080    WindowManagerService mWindowManager;
1081
1082    final ActivityThread mSystemThread;
1083
1084    int mCurrentUserId = 0;
1085    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1086
1087    /**
1088     * Mapping from each known user ID to the profile group ID it is associated with.
1089     */
1090    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1091
1092    private UserManagerService mUserManager;
1093
1094    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1095        final ProcessRecord mApp;
1096        final int mPid;
1097        final IApplicationThread mAppThread;
1098
1099        AppDeathRecipient(ProcessRecord app, int pid,
1100                IApplicationThread thread) {
1101            if (localLOGV) Slog.v(
1102                TAG, "New death recipient " + this
1103                + " for thread " + thread.asBinder());
1104            mApp = app;
1105            mPid = pid;
1106            mAppThread = thread;
1107        }
1108
1109        @Override
1110        public void binderDied() {
1111            if (localLOGV) Slog.v(
1112                TAG, "Death received in " + this
1113                + " for thread " + mAppThread.asBinder());
1114            synchronized(ActivityManagerService.this) {
1115                appDiedLocked(mApp, mPid, mAppThread);
1116            }
1117        }
1118    }
1119
1120    static final int SHOW_ERROR_MSG = 1;
1121    static final int SHOW_NOT_RESPONDING_MSG = 2;
1122    static final int SHOW_FACTORY_ERROR_MSG = 3;
1123    static final int UPDATE_CONFIGURATION_MSG = 4;
1124    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1125    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1126    static final int SERVICE_TIMEOUT_MSG = 12;
1127    static final int UPDATE_TIME_ZONE = 13;
1128    static final int SHOW_UID_ERROR_MSG = 14;
1129    static final int IM_FEELING_LUCKY_MSG = 15;
1130    static final int PROC_START_TIMEOUT_MSG = 20;
1131    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1132    static final int KILL_APPLICATION_MSG = 22;
1133    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1134    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1135    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1136    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1137    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1138    static final int CLEAR_DNS_CACHE_MSG = 28;
1139    static final int UPDATE_HTTP_PROXY_MSG = 29;
1140    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1141    static final int DISPATCH_PROCESSES_CHANGED = 31;
1142    static final int DISPATCH_PROCESS_DIED = 32;
1143    static final int REPORT_MEM_USAGE_MSG = 33;
1144    static final int REPORT_USER_SWITCH_MSG = 34;
1145    static final int CONTINUE_USER_SWITCH_MSG = 35;
1146    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1147    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1148    static final int PERSIST_URI_GRANTS_MSG = 38;
1149    static final int REQUEST_ALL_PSS_MSG = 39;
1150    static final int START_PROFILES_MSG = 40;
1151    static final int UPDATE_TIME = 41;
1152    static final int SYSTEM_USER_START_MSG = 42;
1153    static final int SYSTEM_USER_CURRENT_MSG = 43;
1154
1155    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1156    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1157    static final int FIRST_COMPAT_MODE_MSG = 300;
1158    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1159
1160    AlertDialog mUidAlert;
1161    CompatModeDialog mCompatModeDialog;
1162    long mLastMemUsageReportTime = 0;
1163
1164    private LockToAppRequestDialog mLockToAppRequest;
1165
1166    /**
1167     * Flag whether the current user is a "monkey", i.e. whether
1168     * the UI is driven by a UI automation tool.
1169     */
1170    private boolean mUserIsMonkey;
1171
1172    /** Flag whether the device has a recents UI */
1173    final boolean mHasRecents;
1174
1175    final ServiceThread mHandlerThread;
1176    final MainHandler mHandler;
1177
1178    final class MainHandler extends Handler {
1179        public MainHandler(Looper looper) {
1180            super(looper, null, true);
1181        }
1182
1183        @Override
1184        public void handleMessage(Message msg) {
1185            switch (msg.what) {
1186            case SHOW_ERROR_MSG: {
1187                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1188                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1189                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1190                synchronized (ActivityManagerService.this) {
1191                    ProcessRecord proc = (ProcessRecord)data.get("app");
1192                    AppErrorResult res = (AppErrorResult) data.get("result");
1193                    if (proc != null && proc.crashDialog != null) {
1194                        Slog.e(TAG, "App already has crash dialog: " + proc);
1195                        if (res != null) {
1196                            res.set(0);
1197                        }
1198                        return;
1199                    }
1200                    if (!showBackground && UserHandle.getAppId(proc.uid)
1201                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1202                            && proc.pid != MY_PID) {
1203                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1210                        Dialog d = new AppErrorDialog(mContext,
1211                                ActivityManagerService.this, res, proc);
1212                        d.show();
1213                        proc.crashDialog = d;
1214                    } else {
1215                        // The device is asleep, so just pretend that the user
1216                        // saw a crash dialog and hit "force quit".
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                    }
1221                }
1222
1223                ensureBootCompleted();
1224            } break;
1225            case SHOW_NOT_RESPONDING_MSG: {
1226                synchronized (ActivityManagerService.this) {
1227                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1228                    ProcessRecord proc = (ProcessRecord)data.get("app");
1229                    if (proc != null && proc.anrDialog != null) {
1230                        Slog.e(TAG, "App already has anr dialog: " + proc);
1231                        return;
1232                    }
1233
1234                    Intent intent = new Intent("android.intent.action.ANR");
1235                    if (!mProcessesReady) {
1236                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1237                                | Intent.FLAG_RECEIVER_FOREGROUND);
1238                    }
1239                    broadcastIntentLocked(null, null, intent,
1240                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1241                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1242
1243                    if (mShowDialogs) {
1244                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1245                                mContext, proc, (ActivityRecord)data.get("activity"),
1246                                msg.arg1 != 0);
1247                        d.show();
1248                        proc.anrDialog = d;
1249                    } else {
1250                        // Just kill the app if there is no dialog to be shown.
1251                        killAppAtUsersRequest(proc, null);
1252                    }
1253                }
1254
1255                ensureBootCompleted();
1256            } break;
1257            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1258                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1259                synchronized (ActivityManagerService.this) {
1260                    ProcessRecord proc = (ProcessRecord) data.get("app");
1261                    if (proc == null) {
1262                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1263                        break;
1264                    }
1265                    if (proc.crashDialog != null) {
1266                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1267                        return;
1268                    }
1269                    AppErrorResult res = (AppErrorResult) data.get("result");
1270                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1271                        Dialog d = new StrictModeViolationDialog(mContext,
1272                                ActivityManagerService.this, res, proc);
1273                        d.show();
1274                        proc.crashDialog = d;
1275                    } else {
1276                        // The device is asleep, so just pretend that the user
1277                        // saw a crash dialog and hit "force quit".
1278                        res.set(0);
1279                    }
1280                }
1281                ensureBootCompleted();
1282            } break;
1283            case SHOW_FACTORY_ERROR_MSG: {
1284                Dialog d = new FactoryErrorDialog(
1285                    mContext, msg.getData().getCharSequence("msg"));
1286                d.show();
1287                ensureBootCompleted();
1288            } break;
1289            case UPDATE_CONFIGURATION_MSG: {
1290                final ContentResolver resolver = mContext.getContentResolver();
1291                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1292            } break;
1293            case GC_BACKGROUND_PROCESSES_MSG: {
1294                synchronized (ActivityManagerService.this) {
1295                    performAppGcsIfAppropriateLocked();
1296                }
1297            } break;
1298            case WAIT_FOR_DEBUGGER_MSG: {
1299                synchronized (ActivityManagerService.this) {
1300                    ProcessRecord app = (ProcessRecord)msg.obj;
1301                    if (msg.arg1 != 0) {
1302                        if (!app.waitedForDebugger) {
1303                            Dialog d = new AppWaitingForDebuggerDialog(
1304                                    ActivityManagerService.this,
1305                                    mContext, app);
1306                            app.waitDialog = d;
1307                            app.waitedForDebugger = true;
1308                            d.show();
1309                        }
1310                    } else {
1311                        if (app.waitDialog != null) {
1312                            app.waitDialog.dismiss();
1313                            app.waitDialog = null;
1314                        }
1315                    }
1316                }
1317            } break;
1318            case SERVICE_TIMEOUT_MSG: {
1319                if (mDidDexOpt) {
1320                    mDidDexOpt = false;
1321                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1322                    nmsg.obj = msg.obj;
1323                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1324                    return;
1325                }
1326                mServices.serviceTimeout((ProcessRecord)msg.obj);
1327            } break;
1328            case UPDATE_TIME_ZONE: {
1329                synchronized (ActivityManagerService.this) {
1330                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1331                        ProcessRecord r = mLruProcesses.get(i);
1332                        if (r.thread != null) {
1333                            try {
1334                                r.thread.updateTimeZone();
1335                            } catch (RemoteException ex) {
1336                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1337                            }
1338                        }
1339                    }
1340                }
1341            } break;
1342            case CLEAR_DNS_CACHE_MSG: {
1343                synchronized (ActivityManagerService.this) {
1344                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1345                        ProcessRecord r = mLruProcesses.get(i);
1346                        if (r.thread != null) {
1347                            try {
1348                                r.thread.clearDnsCache();
1349                            } catch (RemoteException ex) {
1350                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1351                            }
1352                        }
1353                    }
1354                }
1355            } break;
1356            case UPDATE_HTTP_PROXY_MSG: {
1357                ProxyInfo proxy = (ProxyInfo)msg.obj;
1358                String host = "";
1359                String port = "";
1360                String exclList = "";
1361                Uri pacFileUrl = Uri.EMPTY;
1362                if (proxy != null) {
1363                    host = proxy.getHost();
1364                    port = Integer.toString(proxy.getPort());
1365                    exclList = proxy.getExclusionListAsString();
1366                    pacFileUrl = proxy.getPacFileUrl();
1367                }
1368                synchronized (ActivityManagerService.this) {
1369                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1370                        ProcessRecord r = mLruProcesses.get(i);
1371                        if (r.thread != null) {
1372                            try {
1373                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1374                            } catch (RemoteException ex) {
1375                                Slog.w(TAG, "Failed to update http proxy for: " +
1376                                        r.info.processName);
1377                            }
1378                        }
1379                    }
1380                }
1381            } break;
1382            case SHOW_UID_ERROR_MSG: {
1383                String title = "System UIDs Inconsistent";
1384                String text = "UIDs on the system are inconsistent, you need to wipe your"
1385                        + " data partition or your device will be unstable.";
1386                Log.e(TAG, title + ": " + text);
1387                if (mShowDialogs) {
1388                    // XXX This is a temporary dialog, no need to localize.
1389                    AlertDialog d = new BaseErrorDialog(mContext);
1390                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1391                    d.setCancelable(false);
1392                    d.setTitle(title);
1393                    d.setMessage(text);
1394                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1395                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1396                    mUidAlert = d;
1397                    d.show();
1398                }
1399            } break;
1400            case IM_FEELING_LUCKY_MSG: {
1401                if (mUidAlert != null) {
1402                    mUidAlert.dismiss();
1403                    mUidAlert = null;
1404                }
1405            } break;
1406            case PROC_START_TIMEOUT_MSG: {
1407                if (mDidDexOpt) {
1408                    mDidDexOpt = false;
1409                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1410                    nmsg.obj = msg.obj;
1411                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1412                    return;
1413                }
1414                ProcessRecord app = (ProcessRecord)msg.obj;
1415                synchronized (ActivityManagerService.this) {
1416                    processStartTimedOutLocked(app);
1417                }
1418            } break;
1419            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1420                synchronized (ActivityManagerService.this) {
1421                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1422                }
1423            } break;
1424            case KILL_APPLICATION_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    int appid = msg.arg1;
1427                    boolean restart = (msg.arg2 == 1);
1428                    Bundle bundle = (Bundle)msg.obj;
1429                    String pkg = bundle.getString("pkg");
1430                    String reason = bundle.getString("reason");
1431                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1432                            false, UserHandle.USER_ALL, reason);
1433                }
1434            } break;
1435            case FINALIZE_PENDING_INTENT_MSG: {
1436                ((PendingIntentRecord)msg.obj).completeFinalize();
1437            } break;
1438            case POST_HEAVY_NOTIFICATION_MSG: {
1439                INotificationManager inm = NotificationManager.getService();
1440                if (inm == null) {
1441                    return;
1442                }
1443
1444                ActivityRecord root = (ActivityRecord)msg.obj;
1445                ProcessRecord process = root.app;
1446                if (process == null) {
1447                    return;
1448                }
1449
1450                try {
1451                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1452                    String text = mContext.getString(R.string.heavy_weight_notification,
1453                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1454                    Notification notification = new Notification();
1455                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1456                    notification.when = 0;
1457                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1458                    notification.tickerText = text;
1459                    notification.defaults = 0; // please be quiet
1460                    notification.sound = null;
1461                    notification.vibrate = null;
1462                    notification.setLatestEventInfo(context, text,
1463                            mContext.getText(R.string.heavy_weight_notification_detail),
1464                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1465                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1466                                    new UserHandle(root.userId)));
1467
1468                    try {
1469                        int[] outId = new int[1];
1470                        inm.enqueueNotificationWithTag("android", "android", null,
1471                                R.string.heavy_weight_notification,
1472                                notification, outId, root.userId);
1473                    } catch (RuntimeException e) {
1474                        Slog.w(ActivityManagerService.TAG,
1475                                "Error showing notification for heavy-weight app", e);
1476                    } catch (RemoteException e) {
1477                    }
1478                } catch (NameNotFoundException e) {
1479                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1480                }
1481            } break;
1482            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1483                INotificationManager inm = NotificationManager.getService();
1484                if (inm == null) {
1485                    return;
1486                }
1487                try {
1488                    inm.cancelNotificationWithTag("android", null,
1489                            R.string.heavy_weight_notification,  msg.arg1);
1490                } catch (RuntimeException e) {
1491                    Slog.w(ActivityManagerService.TAG,
1492                            "Error canceling notification for service", e);
1493                } catch (RemoteException e) {
1494                }
1495            } break;
1496            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1497                synchronized (ActivityManagerService.this) {
1498                    checkExcessivePowerUsageLocked(true);
1499                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1500                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1501                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1502                }
1503            } break;
1504            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1505                synchronized (ActivityManagerService.this) {
1506                    ActivityRecord ar = (ActivityRecord)msg.obj;
1507                    if (mCompatModeDialog != null) {
1508                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1509                                ar.info.applicationInfo.packageName)) {
1510                            return;
1511                        }
1512                        mCompatModeDialog.dismiss();
1513                        mCompatModeDialog = null;
1514                    }
1515                    if (ar != null && false) {
1516                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1517                                ar.packageName)) {
1518                            int mode = mCompatModePackages.computeCompatModeLocked(
1519                                    ar.info.applicationInfo);
1520                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1521                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1522                                mCompatModeDialog = new CompatModeDialog(
1523                                        ActivityManagerService.this, mContext,
1524                                        ar.info.applicationInfo);
1525                                mCompatModeDialog.show();
1526                            }
1527                        }
1528                    }
1529                }
1530                break;
1531            }
1532            case DISPATCH_PROCESSES_CHANGED: {
1533                dispatchProcessesChanged();
1534                break;
1535            }
1536            case DISPATCH_PROCESS_DIED: {
1537                final int pid = msg.arg1;
1538                final int uid = msg.arg2;
1539                dispatchProcessDied(pid, uid);
1540                break;
1541            }
1542            case REPORT_MEM_USAGE_MSG: {
1543                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1544                Thread thread = new Thread() {
1545                    @Override public void run() {
1546                        final SparseArray<ProcessMemInfo> infoMap
1547                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1548                        for (int i=0, N=memInfos.size(); i<N; i++) {
1549                            ProcessMemInfo mi = memInfos.get(i);
1550                            infoMap.put(mi.pid, mi);
1551                        }
1552                        updateCpuStatsNow();
1553                        synchronized (mProcessCpuThread) {
1554                            final int N = mProcessCpuTracker.countStats();
1555                            for (int i=0; i<N; i++) {
1556                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1557                                if (st.vsize > 0) {
1558                                    long pss = Debug.getPss(st.pid, null);
1559                                    if (pss > 0) {
1560                                        if (infoMap.indexOfKey(st.pid) < 0) {
1561                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1562                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1563                                            mi.pss = pss;
1564                                            memInfos.add(mi);
1565                                        }
1566                                    }
1567                                }
1568                            }
1569                        }
1570
1571                        long totalPss = 0;
1572                        for (int i=0, N=memInfos.size(); i<N; i++) {
1573                            ProcessMemInfo mi = memInfos.get(i);
1574                            if (mi.pss == 0) {
1575                                mi.pss = Debug.getPss(mi.pid, null);
1576                            }
1577                            totalPss += mi.pss;
1578                        }
1579                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1580                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1581                                if (lhs.oomAdj != rhs.oomAdj) {
1582                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1583                                }
1584                                if (lhs.pss != rhs.pss) {
1585                                    return lhs.pss < rhs.pss ? 1 : -1;
1586                                }
1587                                return 0;
1588                            }
1589                        });
1590
1591                        StringBuilder tag = new StringBuilder(128);
1592                        StringBuilder stack = new StringBuilder(128);
1593                        tag.append("Low on memory -- ");
1594                        appendMemBucket(tag, totalPss, "total", false);
1595                        appendMemBucket(stack, totalPss, "total", true);
1596
1597                        StringBuilder logBuilder = new StringBuilder(1024);
1598                        logBuilder.append("Low on memory:\n");
1599
1600                        boolean firstLine = true;
1601                        int lastOomAdj = Integer.MIN_VALUE;
1602                        for (int i=0, N=memInfos.size(); i<N; i++) {
1603                            ProcessMemInfo mi = memInfos.get(i);
1604
1605                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1606                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1607                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1608                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1609                                if (lastOomAdj != mi.oomAdj) {
1610                                    lastOomAdj = mi.oomAdj;
1611                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1612                                        tag.append(" / ");
1613                                    }
1614                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1615                                        if (firstLine) {
1616                                            stack.append(":");
1617                                            firstLine = false;
1618                                        }
1619                                        stack.append("\n\t at ");
1620                                    } else {
1621                                        stack.append("$");
1622                                    }
1623                                } else {
1624                                    tag.append(" ");
1625                                    stack.append("$");
1626                                }
1627                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1628                                    appendMemBucket(tag, mi.pss, mi.name, false);
1629                                }
1630                                appendMemBucket(stack, mi.pss, mi.name, true);
1631                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1632                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1633                                    stack.append("(");
1634                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1635                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1636                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1637                                            stack.append(":");
1638                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1639                                        }
1640                                    }
1641                                    stack.append(")");
1642                                }
1643                            }
1644
1645                            logBuilder.append("  ");
1646                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1647                            logBuilder.append(' ');
1648                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1649                            logBuilder.append(' ');
1650                            ProcessList.appendRamKb(logBuilder, mi.pss);
1651                            logBuilder.append(" kB: ");
1652                            logBuilder.append(mi.name);
1653                            logBuilder.append(" (");
1654                            logBuilder.append(mi.pid);
1655                            logBuilder.append(") ");
1656                            logBuilder.append(mi.adjType);
1657                            logBuilder.append('\n');
1658                            if (mi.adjReason != null) {
1659                                logBuilder.append("                      ");
1660                                logBuilder.append(mi.adjReason);
1661                                logBuilder.append('\n');
1662                            }
1663                        }
1664
1665                        logBuilder.append("           ");
1666                        ProcessList.appendRamKb(logBuilder, totalPss);
1667                        logBuilder.append(" kB: TOTAL\n");
1668
1669                        long[] infos = new long[Debug.MEMINFO_COUNT];
1670                        Debug.getMemInfo(infos);
1671                        logBuilder.append("  MemInfo: ");
1672                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1673                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1674                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1675                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1676                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1677                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1678                            logBuilder.append("  ZRAM: ");
1679                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1680                            logBuilder.append(" kB RAM, ");
1681                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1682                            logBuilder.append(" kB swap total, ");
1683                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1684                            logBuilder.append(" kB swap free\n");
1685                        }
1686                        Slog.i(TAG, logBuilder.toString());
1687
1688                        StringBuilder dropBuilder = new StringBuilder(1024);
1689                        /*
1690                        StringWriter oomSw = new StringWriter();
1691                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1692                        StringWriter catSw = new StringWriter();
1693                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1694                        String[] emptyArgs = new String[] { };
1695                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1696                        oomPw.flush();
1697                        String oomString = oomSw.toString();
1698                        */
1699                        dropBuilder.append(stack);
1700                        dropBuilder.append('\n');
1701                        dropBuilder.append('\n');
1702                        dropBuilder.append(logBuilder);
1703                        dropBuilder.append('\n');
1704                        /*
1705                        dropBuilder.append(oomString);
1706                        dropBuilder.append('\n');
1707                        */
1708                        StringWriter catSw = new StringWriter();
1709                        synchronized (ActivityManagerService.this) {
1710                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1711                            String[] emptyArgs = new String[] { };
1712                            catPw.println();
1713                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1714                            catPw.println();
1715                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1716                                    false, false, null);
1717                            catPw.println();
1718                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1719                            catPw.flush();
1720                        }
1721                        dropBuilder.append(catSw.toString());
1722                        addErrorToDropBox("lowmem", null, "system_server", null,
1723                                null, tag.toString(), dropBuilder.toString(), null, null);
1724                        //Slog.i(TAG, "Sent to dropbox:");
1725                        //Slog.i(TAG, dropBuilder.toString());
1726                        synchronized (ActivityManagerService.this) {
1727                            long now = SystemClock.uptimeMillis();
1728                            if (mLastMemUsageReportTime < now) {
1729                                mLastMemUsageReportTime = now;
1730                            }
1731                        }
1732                    }
1733                };
1734                thread.start();
1735                break;
1736            }
1737            case REPORT_USER_SWITCH_MSG: {
1738                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1739                break;
1740            }
1741            case CONTINUE_USER_SWITCH_MSG: {
1742                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1743                break;
1744            }
1745            case USER_SWITCH_TIMEOUT_MSG: {
1746                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1747                break;
1748            }
1749            case IMMERSIVE_MODE_LOCK_MSG: {
1750                final boolean nextState = (msg.arg1 != 0);
1751                if (mUpdateLock.isHeld() != nextState) {
1752                    if (DEBUG_IMMERSIVE) {
1753                        final ActivityRecord r = (ActivityRecord) msg.obj;
1754                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1755                    }
1756                    if (nextState) {
1757                        mUpdateLock.acquire();
1758                    } else {
1759                        mUpdateLock.release();
1760                    }
1761                }
1762                break;
1763            }
1764            case PERSIST_URI_GRANTS_MSG: {
1765                writeGrantedUriPermissions();
1766                break;
1767            }
1768            case REQUEST_ALL_PSS_MSG: {
1769                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1770                break;
1771            }
1772            case START_PROFILES_MSG: {
1773                synchronized (ActivityManagerService.this) {
1774                    startProfilesLocked();
1775                }
1776                break;
1777            }
1778            case UPDATE_TIME: {
1779                synchronized (ActivityManagerService.this) {
1780                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1781                        ProcessRecord r = mLruProcesses.get(i);
1782                        if (r.thread != null) {
1783                            try {
1784                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1785                            } catch (RemoteException ex) {
1786                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1787                            }
1788                        }
1789                    }
1790                }
1791                break;
1792            }
1793            case SYSTEM_USER_START_MSG: {
1794                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1795                        Integer.toString(msg.arg1), msg.arg1);
1796                mSystemServiceManager.startUser(msg.arg1);
1797                break;
1798            }
1799            case SYSTEM_USER_CURRENT_MSG: {
1800                mBatteryStatsService.noteEvent(
1801                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1802                        Integer.toString(msg.arg2), msg.arg2);
1803                mBatteryStatsService.noteEvent(
1804                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1805                        Integer.toString(msg.arg1), msg.arg1);
1806                mSystemServiceManager.switchUser(msg.arg1);
1807                break;
1808            }
1809            }
1810        }
1811    };
1812
1813    static final int COLLECT_PSS_BG_MSG = 1;
1814
1815    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1816        @Override
1817        public void handleMessage(Message msg) {
1818            switch (msg.what) {
1819            case COLLECT_PSS_BG_MSG: {
1820                long start = SystemClock.uptimeMillis();
1821                MemInfoReader memInfo = null;
1822                synchronized (ActivityManagerService.this) {
1823                    if (mFullPssPending) {
1824                        mFullPssPending = false;
1825                        memInfo = new MemInfoReader();
1826                    }
1827                }
1828                if (memInfo != null) {
1829                    updateCpuStatsNow();
1830                    long nativeTotalPss = 0;
1831                    synchronized (mProcessCpuThread) {
1832                        final int N = mProcessCpuTracker.countStats();
1833                        for (int j=0; j<N; j++) {
1834                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1835                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1836                                // This is definitely an application process; skip it.
1837                                continue;
1838                            }
1839                            synchronized (mPidsSelfLocked) {
1840                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1841                                    // This is one of our own processes; skip it.
1842                                    continue;
1843                                }
1844                            }
1845                            nativeTotalPss += Debug.getPss(st.pid, null);
1846                        }
1847                    }
1848                    memInfo.readMemInfo();
1849                    synchronized (this) {
1850                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1851                                + (SystemClock.uptimeMillis()-start) + "ms");
1852                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1853                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1854                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1855                                        +memInfo.getSlabSizeKb(),
1856                                nativeTotalPss);
1857                    }
1858                }
1859
1860                int i=0, num=0;
1861                long[] tmp = new long[1];
1862                do {
1863                    ProcessRecord proc;
1864                    int procState;
1865                    int pid;
1866                    synchronized (ActivityManagerService.this) {
1867                        if (i >= mPendingPssProcesses.size()) {
1868                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1869                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1870                            mPendingPssProcesses.clear();
1871                            return;
1872                        }
1873                        proc = mPendingPssProcesses.get(i);
1874                        procState = proc.pssProcState;
1875                        if (proc.thread != null && procState == proc.setProcState) {
1876                            pid = proc.pid;
1877                        } else {
1878                            proc = null;
1879                            pid = 0;
1880                        }
1881                        i++;
1882                    }
1883                    if (proc != null) {
1884                        long pss = Debug.getPss(pid, tmp);
1885                        synchronized (ActivityManagerService.this) {
1886                            if (proc.thread != null && proc.setProcState == procState
1887                                    && proc.pid == pid) {
1888                                num++;
1889                                proc.lastPssTime = SystemClock.uptimeMillis();
1890                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1891                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1892                                        + ": " + pss + " lastPss=" + proc.lastPss
1893                                        + " state=" + ProcessList.makeProcStateString(procState));
1894                                if (proc.initialIdlePss == 0) {
1895                                    proc.initialIdlePss = pss;
1896                                }
1897                                proc.lastPss = pss;
1898                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1899                                    proc.lastCachedPss = pss;
1900                                }
1901                            }
1902                        }
1903                    }
1904                } while (true);
1905            }
1906            }
1907        }
1908    };
1909
1910    /**
1911     * Monitor for package changes and update our internal state.
1912     */
1913    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1914        @Override
1915        public void onPackageRemoved(String packageName, int uid) {
1916            // Remove all tasks with activities in the specified package from the list of recent tasks
1917            synchronized (ActivityManagerService.this) {
1918                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1919                    TaskRecord tr = mRecentTasks.get(i);
1920                    ComponentName cn = tr.intent.getComponent();
1921                    if (cn != null && cn.getPackageName().equals(packageName)) {
1922                        // If the package name matches, remove the task and kill the process
1923                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1924                    }
1925                }
1926            }
1927        }
1928
1929        @Override
1930        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1931            onPackageModified(packageName);
1932            return true;
1933        }
1934
1935        @Override
1936        public void onPackageModified(String packageName) {
1937            final PackageManager pm = mContext.getPackageManager();
1938            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1939                    new ArrayList<Pair<Intent, Integer>>();
1940            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1941            // Copy the list of recent tasks so that we don't hold onto the lock on
1942            // ActivityManagerService for long periods while checking if components exist.
1943            synchronized (ActivityManagerService.this) {
1944                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1945                    TaskRecord tr = mRecentTasks.get(i);
1946                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1947                }
1948            }
1949            // Check the recent tasks and filter out all tasks with components that no longer exist.
1950            Intent tmpI = new Intent();
1951            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1952                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1953                ComponentName cn = p.first.getComponent();
1954                if (cn != null && cn.getPackageName().equals(packageName)) {
1955                    try {
1956                        // Add the task to the list to remove if the component no longer exists
1957                        tmpI.setComponent(cn);
1958                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1959                            tasksToRemove.add(p.second);
1960                        }
1961                    } catch (Exception e) {}
1962                }
1963            }
1964            // Prune all the tasks with removed components from the list of recent tasks
1965            synchronized (ActivityManagerService.this) {
1966                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1967                    // Remove the task but don't kill the process (since other components in that
1968                    // package may still be running and in the background)
1969                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1970                }
1971            }
1972        }
1973
1974        @Override
1975        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1976            // Force stop the specified packages
1977            if (packages != null) {
1978                for (String pkg : packages) {
1979                    synchronized (ActivityManagerService.this) {
1980                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1981                                "finished booting")) {
1982                            return true;
1983                        }
1984                    }
1985                }
1986            }
1987            return false;
1988        }
1989    };
1990
1991    public void setSystemProcess() {
1992        try {
1993            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1994            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1995            ServiceManager.addService("meminfo", new MemBinder(this));
1996            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1997            ServiceManager.addService("dbinfo", new DbBinder(this));
1998            if (MONITOR_CPU_USAGE) {
1999                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2000            }
2001            ServiceManager.addService("permission", new PermissionController(this));
2002
2003            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2004                    "android", STOCK_PM_FLAGS);
2005            mSystemThread.installSystemApplicationInfo(info);
2006
2007            synchronized (this) {
2008                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2009                app.persistent = true;
2010                app.pid = MY_PID;
2011                app.maxAdj = ProcessList.SYSTEM_ADJ;
2012                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2013                mProcessNames.put(app.processName, app.uid, app);
2014                synchronized (mPidsSelfLocked) {
2015                    mPidsSelfLocked.put(app.pid, app);
2016                }
2017                updateLruProcessLocked(app, false, null);
2018                updateOomAdjLocked();
2019            }
2020        } catch (PackageManager.NameNotFoundException e) {
2021            throw new RuntimeException(
2022                    "Unable to find android system package", e);
2023        }
2024    }
2025
2026    public void setWindowManager(WindowManagerService wm) {
2027        mWindowManager = wm;
2028        mStackSupervisor.setWindowManager(wm);
2029    }
2030
2031    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2032        mUsageStatsService = usageStatsManager;
2033    }
2034
2035    public void startObservingNativeCrashes() {
2036        final NativeCrashListener ncl = new NativeCrashListener(this);
2037        ncl.start();
2038    }
2039
2040    public IAppOpsService getAppOpsService() {
2041        return mAppOpsService;
2042    }
2043
2044    static class MemBinder extends Binder {
2045        ActivityManagerService mActivityManagerService;
2046        MemBinder(ActivityManagerService activityManagerService) {
2047            mActivityManagerService = activityManagerService;
2048        }
2049
2050        @Override
2051        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2052            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2053                    != PackageManager.PERMISSION_GRANTED) {
2054                pw.println("Permission Denial: can't dump meminfo from from pid="
2055                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2056                        + " without permission " + android.Manifest.permission.DUMP);
2057                return;
2058            }
2059
2060            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2061        }
2062    }
2063
2064    static class GraphicsBinder extends Binder {
2065        ActivityManagerService mActivityManagerService;
2066        GraphicsBinder(ActivityManagerService activityManagerService) {
2067            mActivityManagerService = activityManagerService;
2068        }
2069
2070        @Override
2071        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2072            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2073                    != PackageManager.PERMISSION_GRANTED) {
2074                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2075                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2076                        + " without permission " + android.Manifest.permission.DUMP);
2077                return;
2078            }
2079
2080            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2081        }
2082    }
2083
2084    static class DbBinder extends Binder {
2085        ActivityManagerService mActivityManagerService;
2086        DbBinder(ActivityManagerService activityManagerService) {
2087            mActivityManagerService = activityManagerService;
2088        }
2089
2090        @Override
2091        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2092            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2093                    != PackageManager.PERMISSION_GRANTED) {
2094                pw.println("Permission Denial: can't dump dbinfo from from pid="
2095                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2096                        + " without permission " + android.Manifest.permission.DUMP);
2097                return;
2098            }
2099
2100            mActivityManagerService.dumpDbInfo(fd, pw, args);
2101        }
2102    }
2103
2104    static class CpuBinder extends Binder {
2105        ActivityManagerService mActivityManagerService;
2106        CpuBinder(ActivityManagerService activityManagerService) {
2107            mActivityManagerService = activityManagerService;
2108        }
2109
2110        @Override
2111        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2112            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2113                    != PackageManager.PERMISSION_GRANTED) {
2114                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2115                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2116                        + " without permission " + android.Manifest.permission.DUMP);
2117                return;
2118            }
2119
2120            synchronized (mActivityManagerService.mProcessCpuThread) {
2121                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2122                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2123                        SystemClock.uptimeMillis()));
2124            }
2125        }
2126    }
2127
2128    public static final class Lifecycle extends SystemService {
2129        private final ActivityManagerService mService;
2130
2131        public Lifecycle(Context context) {
2132            super(context);
2133            mService = new ActivityManagerService(context);
2134        }
2135
2136        @Override
2137        public void onStart() {
2138            mService.start();
2139        }
2140
2141        public ActivityManagerService getService() {
2142            return mService;
2143        }
2144    }
2145
2146    // Note: This method is invoked on the main thread but may need to attach various
2147    // handlers to other threads.  So take care to be explicit about the looper.
2148    public ActivityManagerService(Context systemContext) {
2149        mContext = systemContext;
2150        mFactoryTest = FactoryTest.getMode();
2151        mSystemThread = ActivityThread.currentActivityThread();
2152
2153        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2154
2155        mHandlerThread = new ServiceThread(TAG,
2156                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2157        mHandlerThread.start();
2158        mHandler = new MainHandler(mHandlerThread.getLooper());
2159
2160        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2161                "foreground", BROADCAST_FG_TIMEOUT, false);
2162        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2163                "background", BROADCAST_BG_TIMEOUT, true);
2164        mBroadcastQueues[0] = mFgBroadcastQueue;
2165        mBroadcastQueues[1] = mBgBroadcastQueue;
2166
2167        mServices = new ActiveServices(this);
2168        mProviderMap = new ProviderMap(this);
2169
2170        // TODO: Move creation of battery stats service outside of activity manager service.
2171        File dataDir = Environment.getDataDirectory();
2172        File systemDir = new File(dataDir, "system");
2173        systemDir.mkdirs();
2174        mBatteryStatsService = new BatteryStatsService(new File(
2175                systemDir, "batterystats.bin").toString(), mHandler);
2176        mBatteryStatsService.getActiveStatistics().readLocked();
2177        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2178        mOnBattery = DEBUG_POWER ? true
2179                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2180        mBatteryStatsService.getActiveStatistics().setCallback(this);
2181
2182        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2183
2184        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2185
2186        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2187
2188        // User 0 is the first and only user that runs at boot.
2189        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2190        mUserLru.add(Integer.valueOf(0));
2191        updateStartedUserArrayLocked();
2192
2193        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2194            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2195
2196        mConfiguration.setToDefaults();
2197        mConfiguration.setLocale(Locale.getDefault());
2198
2199        mConfigurationSeq = mConfiguration.seq = 1;
2200        mProcessCpuTracker.init();
2201
2202        mHasRecents = mContext.getResources().getBoolean(
2203                com.android.internal.R.bool.config_hasRecents);
2204
2205        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2206        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2207        mStackSupervisor = new ActivityStackSupervisor(this);
2208        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2209
2210        mProcessCpuThread = new Thread("CpuTracker") {
2211            @Override
2212            public void run() {
2213                while (true) {
2214                    try {
2215                        try {
2216                            synchronized(this) {
2217                                final long now = SystemClock.uptimeMillis();
2218                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2219                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2220                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2221                                //        + ", write delay=" + nextWriteDelay);
2222                                if (nextWriteDelay < nextCpuDelay) {
2223                                    nextCpuDelay = nextWriteDelay;
2224                                }
2225                                if (nextCpuDelay > 0) {
2226                                    mProcessCpuMutexFree.set(true);
2227                                    this.wait(nextCpuDelay);
2228                                }
2229                            }
2230                        } catch (InterruptedException e) {
2231                        }
2232                        updateCpuStatsNow();
2233                    } catch (Exception e) {
2234                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2235                    }
2236                }
2237            }
2238        };
2239
2240        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2241
2242        Watchdog.getInstance().addMonitor(this);
2243        Watchdog.getInstance().addThread(mHandler);
2244    }
2245
2246    public void setSystemServiceManager(SystemServiceManager mgr) {
2247        mSystemServiceManager = mgr;
2248    }
2249
2250    private void start() {
2251        Process.removeAllProcessGroups();
2252        mProcessCpuThread.start();
2253
2254        mBatteryStatsService.publish(mContext);
2255        mAppOpsService.publish(mContext);
2256        Slog.d("AppOps", "AppOpsService published");
2257        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2258    }
2259
2260    public void initPowerManagement() {
2261        mStackSupervisor.initPowerManagement();
2262        mBatteryStatsService.initPowerManagement();
2263    }
2264
2265    @Override
2266    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2267            throws RemoteException {
2268        if (code == SYSPROPS_TRANSACTION) {
2269            // We need to tell all apps about the system property change.
2270            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2271            synchronized(this) {
2272                final int NP = mProcessNames.getMap().size();
2273                for (int ip=0; ip<NP; ip++) {
2274                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2275                    final int NA = apps.size();
2276                    for (int ia=0; ia<NA; ia++) {
2277                        ProcessRecord app = apps.valueAt(ia);
2278                        if (app.thread != null) {
2279                            procs.add(app.thread.asBinder());
2280                        }
2281                    }
2282                }
2283            }
2284
2285            int N = procs.size();
2286            for (int i=0; i<N; i++) {
2287                Parcel data2 = Parcel.obtain();
2288                try {
2289                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2290                } catch (RemoteException e) {
2291                }
2292                data2.recycle();
2293            }
2294        }
2295        try {
2296            return super.onTransact(code, data, reply, flags);
2297        } catch (RuntimeException e) {
2298            // The activity manager only throws security exceptions, so let's
2299            // log all others.
2300            if (!(e instanceof SecurityException)) {
2301                Slog.wtf(TAG, "Activity Manager Crash", e);
2302            }
2303            throw e;
2304        }
2305    }
2306
2307    void updateCpuStats() {
2308        final long now = SystemClock.uptimeMillis();
2309        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2310            return;
2311        }
2312        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2313            synchronized (mProcessCpuThread) {
2314                mProcessCpuThread.notify();
2315            }
2316        }
2317    }
2318
2319    void updateCpuStatsNow() {
2320        synchronized (mProcessCpuThread) {
2321            mProcessCpuMutexFree.set(false);
2322            final long now = SystemClock.uptimeMillis();
2323            boolean haveNewCpuStats = false;
2324
2325            if (MONITOR_CPU_USAGE &&
2326                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2327                mLastCpuTime.set(now);
2328                haveNewCpuStats = true;
2329                mProcessCpuTracker.update();
2330                //Slog.i(TAG, mProcessCpu.printCurrentState());
2331                //Slog.i(TAG, "Total CPU usage: "
2332                //        + mProcessCpu.getTotalCpuPercent() + "%");
2333
2334                // Slog the cpu usage if the property is set.
2335                if ("true".equals(SystemProperties.get("events.cpu"))) {
2336                    int user = mProcessCpuTracker.getLastUserTime();
2337                    int system = mProcessCpuTracker.getLastSystemTime();
2338                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2339                    int irq = mProcessCpuTracker.getLastIrqTime();
2340                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2341                    int idle = mProcessCpuTracker.getLastIdleTime();
2342
2343                    int total = user + system + iowait + irq + softIrq + idle;
2344                    if (total == 0) total = 1;
2345
2346                    EventLog.writeEvent(EventLogTags.CPU,
2347                            ((user+system+iowait+irq+softIrq) * 100) / total,
2348                            (user * 100) / total,
2349                            (system * 100) / total,
2350                            (iowait * 100) / total,
2351                            (irq * 100) / total,
2352                            (softIrq * 100) / total);
2353                }
2354            }
2355
2356            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2357            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2358            synchronized(bstats) {
2359                synchronized(mPidsSelfLocked) {
2360                    if (haveNewCpuStats) {
2361                        if (mOnBattery) {
2362                            int perc = bstats.startAddingCpuLocked();
2363                            int totalUTime = 0;
2364                            int totalSTime = 0;
2365                            final int N = mProcessCpuTracker.countStats();
2366                            for (int i=0; i<N; i++) {
2367                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2368                                if (!st.working) {
2369                                    continue;
2370                                }
2371                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2372                                int otherUTime = (st.rel_utime*perc)/100;
2373                                int otherSTime = (st.rel_stime*perc)/100;
2374                                totalUTime += otherUTime;
2375                                totalSTime += otherSTime;
2376                                if (pr != null) {
2377                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2378                                    if (ps == null || !ps.isActive()) {
2379                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2380                                                pr.info.uid, pr.processName);
2381                                    }
2382                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2383                                            st.rel_stime-otherSTime);
2384                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2385                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2386                                } else {
2387                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2388                                    if (ps == null || !ps.isActive()) {
2389                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2390                                                bstats.mapUid(st.uid), st.name);
2391                                    }
2392                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2393                                            st.rel_stime-otherSTime);
2394                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2395                                }
2396                            }
2397                            bstats.finishAddingCpuLocked(perc, totalUTime,
2398                                    totalSTime, cpuSpeedTimes);
2399                        }
2400                    }
2401                }
2402
2403                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2404                    mLastWriteTime = now;
2405                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2406                }
2407            }
2408        }
2409    }
2410
2411    @Override
2412    public void batteryNeedsCpuUpdate() {
2413        updateCpuStatsNow();
2414    }
2415
2416    @Override
2417    public void batteryPowerChanged(boolean onBattery) {
2418        // When plugging in, update the CPU stats first before changing
2419        // the plug state.
2420        updateCpuStatsNow();
2421        synchronized (this) {
2422            synchronized(mPidsSelfLocked) {
2423                mOnBattery = DEBUG_POWER ? true : onBattery;
2424            }
2425        }
2426    }
2427
2428    /**
2429     * Initialize the application bind args. These are passed to each
2430     * process when the bindApplication() IPC is sent to the process. They're
2431     * lazily setup to make sure the services are running when they're asked for.
2432     */
2433    private HashMap<String, IBinder> getCommonServicesLocked() {
2434        if (mAppBindArgs == null) {
2435            mAppBindArgs = new HashMap<String, IBinder>();
2436
2437            // Setup the application init args
2438            mAppBindArgs.put("package", ServiceManager.getService("package"));
2439            mAppBindArgs.put("window", ServiceManager.getService("window"));
2440            mAppBindArgs.put(Context.ALARM_SERVICE,
2441                    ServiceManager.getService(Context.ALARM_SERVICE));
2442        }
2443        return mAppBindArgs;
2444    }
2445
2446    final void setFocusedActivityLocked(ActivityRecord r) {
2447        if (mFocusedActivity != r) {
2448            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2449            mFocusedActivity = r;
2450            if (r.task != null && r.task.voiceInteractor != null) {
2451                startRunningVoiceLocked();
2452            } else {
2453                finishRunningVoiceLocked();
2454            }
2455            mStackSupervisor.setFocusedStack(r);
2456            if (r != null) {
2457                mWindowManager.setFocusedApp(r.appToken, true);
2458            }
2459            applyUpdateLockStateLocked(r);
2460        }
2461    }
2462
2463    final void clearFocusedActivity(ActivityRecord r) {
2464        if (mFocusedActivity == r) {
2465            mFocusedActivity = null;
2466        }
2467    }
2468
2469    @Override
2470    public void setFocusedStack(int stackId) {
2471        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2472        synchronized (ActivityManagerService.this) {
2473            ActivityStack stack = mStackSupervisor.getStack(stackId);
2474            if (stack != null) {
2475                ActivityRecord r = stack.topRunningActivityLocked(null);
2476                if (r != null) {
2477                    setFocusedActivityLocked(r);
2478                }
2479            }
2480        }
2481    }
2482
2483    @Override
2484    public void notifyActivityDrawn(IBinder token) {
2485        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2486        synchronized (this) {
2487            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2488            if (r != null) {
2489                r.task.stack.notifyActivityDrawnLocked(r);
2490            }
2491        }
2492    }
2493
2494    final void applyUpdateLockStateLocked(ActivityRecord r) {
2495        // Modifications to the UpdateLock state are done on our handler, outside
2496        // the activity manager's locks.  The new state is determined based on the
2497        // state *now* of the relevant activity record.  The object is passed to
2498        // the handler solely for logging detail, not to be consulted/modified.
2499        final boolean nextState = r != null && r.immersive;
2500        mHandler.sendMessage(
2501                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2502    }
2503
2504    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2505        Message msg = Message.obtain();
2506        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2507        msg.obj = r.task.askedCompatMode ? null : r;
2508        mHandler.sendMessage(msg);
2509    }
2510
2511    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2512            String what, Object obj, ProcessRecord srcApp) {
2513        app.lastActivityTime = now;
2514
2515        if (app.activities.size() > 0) {
2516            // Don't want to touch dependent processes that are hosting activities.
2517            return index;
2518        }
2519
2520        int lrui = mLruProcesses.lastIndexOf(app);
2521        if (lrui < 0) {
2522            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2523                    + what + " " + obj + " from " + srcApp);
2524            return index;
2525        }
2526
2527        if (lrui >= index) {
2528            // Don't want to cause this to move dependent processes *back* in the
2529            // list as if they were less frequently used.
2530            return index;
2531        }
2532
2533        if (lrui >= mLruProcessActivityStart) {
2534            // Don't want to touch dependent processes that are hosting activities.
2535            return index;
2536        }
2537
2538        mLruProcesses.remove(lrui);
2539        if (index > 0) {
2540            index--;
2541        }
2542        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2543                + " in LRU list: " + app);
2544        mLruProcesses.add(index, app);
2545        return index;
2546    }
2547
2548    final void removeLruProcessLocked(ProcessRecord app) {
2549        int lrui = mLruProcesses.lastIndexOf(app);
2550        if (lrui >= 0) {
2551            if (lrui <= mLruProcessActivityStart) {
2552                mLruProcessActivityStart--;
2553            }
2554            if (lrui <= mLruProcessServiceStart) {
2555                mLruProcessServiceStart--;
2556            }
2557            mLruProcesses.remove(lrui);
2558        }
2559    }
2560
2561    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2562            ProcessRecord client) {
2563        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2564                || app.treatLikeActivity;
2565        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2566        if (!activityChange && hasActivity) {
2567            // The process has activities, so we are only allowing activity-based adjustments
2568            // to move it.  It should be kept in the front of the list with other
2569            // processes that have activities, and we don't want those to change their
2570            // order except due to activity operations.
2571            return;
2572        }
2573
2574        mLruSeq++;
2575        final long now = SystemClock.uptimeMillis();
2576        app.lastActivityTime = now;
2577
2578        // First a quick reject: if the app is already at the position we will
2579        // put it, then there is nothing to do.
2580        if (hasActivity) {
2581            final int N = mLruProcesses.size();
2582            if (N > 0 && mLruProcesses.get(N-1) == app) {
2583                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2584                return;
2585            }
2586        } else {
2587            if (mLruProcessServiceStart > 0
2588                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2589                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2590                return;
2591            }
2592        }
2593
2594        int lrui = mLruProcesses.lastIndexOf(app);
2595
2596        if (app.persistent && lrui >= 0) {
2597            // We don't care about the position of persistent processes, as long as
2598            // they are in the list.
2599            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2600            return;
2601        }
2602
2603        /* In progress: compute new position first, so we can avoid doing work
2604           if the process is not actually going to move.  Not yet working.
2605        int addIndex;
2606        int nextIndex;
2607        boolean inActivity = false, inService = false;
2608        if (hasActivity) {
2609            // Process has activities, put it at the very tipsy-top.
2610            addIndex = mLruProcesses.size();
2611            nextIndex = mLruProcessServiceStart;
2612            inActivity = true;
2613        } else if (hasService) {
2614            // Process has services, put it at the top of the service list.
2615            addIndex = mLruProcessActivityStart;
2616            nextIndex = mLruProcessServiceStart;
2617            inActivity = true;
2618            inService = true;
2619        } else  {
2620            // Process not otherwise of interest, it goes to the top of the non-service area.
2621            addIndex = mLruProcessServiceStart;
2622            if (client != null) {
2623                int clientIndex = mLruProcesses.lastIndexOf(client);
2624                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2625                        + app);
2626                if (clientIndex >= 0 && addIndex > clientIndex) {
2627                    addIndex = clientIndex;
2628                }
2629            }
2630            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2631        }
2632
2633        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2634                + mLruProcessActivityStart + "): " + app);
2635        */
2636
2637        if (lrui >= 0) {
2638            if (lrui < mLruProcessActivityStart) {
2639                mLruProcessActivityStart--;
2640            }
2641            if (lrui < mLruProcessServiceStart) {
2642                mLruProcessServiceStart--;
2643            }
2644            /*
2645            if (addIndex > lrui) {
2646                addIndex--;
2647            }
2648            if (nextIndex > lrui) {
2649                nextIndex--;
2650            }
2651            */
2652            mLruProcesses.remove(lrui);
2653        }
2654
2655        /*
2656        mLruProcesses.add(addIndex, app);
2657        if (inActivity) {
2658            mLruProcessActivityStart++;
2659        }
2660        if (inService) {
2661            mLruProcessActivityStart++;
2662        }
2663        */
2664
2665        int nextIndex;
2666        if (hasActivity) {
2667            final int N = mLruProcesses.size();
2668            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2669                // Process doesn't have activities, but has clients with
2670                // activities...  move it up, but one below the top (the top
2671                // should always have a real activity).
2672                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2673                mLruProcesses.add(N-1, app);
2674                // To keep it from spamming the LRU list (by making a bunch of clients),
2675                // we will push down any other entries owned by the app.
2676                final int uid = app.info.uid;
2677                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2678                    ProcessRecord subProc = mLruProcesses.get(i);
2679                    if (subProc.info.uid == uid) {
2680                        // We want to push this one down the list.  If the process after
2681                        // it is for the same uid, however, don't do so, because we don't
2682                        // want them internally to be re-ordered.
2683                        if (mLruProcesses.get(i-1).info.uid != uid) {
2684                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2685                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2686                            ProcessRecord tmp = mLruProcesses.get(i);
2687                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2688                            mLruProcesses.set(i-1, tmp);
2689                            i--;
2690                        }
2691                    } else {
2692                        // A gap, we can stop here.
2693                        break;
2694                    }
2695                }
2696            } else {
2697                // Process has activities, put it at the very tipsy-top.
2698                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2699                mLruProcesses.add(app);
2700            }
2701            nextIndex = mLruProcessServiceStart;
2702        } else if (hasService) {
2703            // Process has services, put it at the top of the service list.
2704            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2705            mLruProcesses.add(mLruProcessActivityStart, app);
2706            nextIndex = mLruProcessServiceStart;
2707            mLruProcessActivityStart++;
2708        } else  {
2709            // Process not otherwise of interest, it goes to the top of the non-service area.
2710            int index = mLruProcessServiceStart;
2711            if (client != null) {
2712                // If there is a client, don't allow the process to be moved up higher
2713                // in the list than that client.
2714                int clientIndex = mLruProcesses.lastIndexOf(client);
2715                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2716                        + " when updating " + app);
2717                if (clientIndex <= lrui) {
2718                    // Don't allow the client index restriction to push it down farther in the
2719                    // list than it already is.
2720                    clientIndex = lrui;
2721                }
2722                if (clientIndex >= 0 && index > clientIndex) {
2723                    index = clientIndex;
2724                }
2725            }
2726            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2727            mLruProcesses.add(index, app);
2728            nextIndex = index-1;
2729            mLruProcessActivityStart++;
2730            mLruProcessServiceStart++;
2731        }
2732
2733        // If the app is currently using a content provider or service,
2734        // bump those processes as well.
2735        for (int j=app.connections.size()-1; j>=0; j--) {
2736            ConnectionRecord cr = app.connections.valueAt(j);
2737            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2738                    && cr.binding.service.app != null
2739                    && cr.binding.service.app.lruSeq != mLruSeq
2740                    && !cr.binding.service.app.persistent) {
2741                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2742                        "service connection", cr, app);
2743            }
2744        }
2745        for (int j=app.conProviders.size()-1; j>=0; j--) {
2746            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2747            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2748                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2749                        "provider reference", cpr, app);
2750            }
2751        }
2752    }
2753
2754    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2755        if (uid == Process.SYSTEM_UID) {
2756            // The system gets to run in any process.  If there are multiple
2757            // processes with the same uid, just pick the first (this
2758            // should never happen).
2759            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2760            if (procs == null) return null;
2761            final int N = procs.size();
2762            for (int i = 0; i < N; i++) {
2763                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2764            }
2765        }
2766        ProcessRecord proc = mProcessNames.get(processName, uid);
2767        if (false && proc != null && !keepIfLarge
2768                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2769                && proc.lastCachedPss >= 4000) {
2770            // Turn this condition on to cause killing to happen regularly, for testing.
2771            if (proc.baseProcessTracker != null) {
2772                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2773            }
2774            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2775                    + "k from cached");
2776        } else if (proc != null && !keepIfLarge
2777                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2778                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2779            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2780            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2781                if (proc.baseProcessTracker != null) {
2782                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2783                }
2784                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2785                        + "k from cached");
2786            }
2787        }
2788        return proc;
2789    }
2790
2791    void ensurePackageDexOpt(String packageName) {
2792        IPackageManager pm = AppGlobals.getPackageManager();
2793        try {
2794            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2795                mDidDexOpt = true;
2796            }
2797        } catch (RemoteException e) {
2798        }
2799    }
2800
2801    boolean isNextTransitionForward() {
2802        int transit = mWindowManager.getPendingAppTransition();
2803        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2804                || transit == AppTransition.TRANSIT_TASK_OPEN
2805                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2806    }
2807
2808    final ProcessRecord startProcessLocked(String processName,
2809            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2810            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2811            boolean isolated, boolean keepIfLarge) {
2812        ProcessRecord app;
2813        if (!isolated) {
2814            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2815        } else {
2816            // If this is an isolated process, it can't re-use an existing process.
2817            app = null;
2818        }
2819        // We don't have to do anything more if:
2820        // (1) There is an existing application record; and
2821        // (2) The caller doesn't think it is dead, OR there is no thread
2822        //     object attached to it so we know it couldn't have crashed; and
2823        // (3) There is a pid assigned to it, so it is either starting or
2824        //     already running.
2825        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2826                + " app=" + app + " knownToBeDead=" + knownToBeDead
2827                + " thread=" + (app != null ? app.thread : null)
2828                + " pid=" + (app != null ? app.pid : -1));
2829        if (app != null && app.pid > 0) {
2830            if (!knownToBeDead || app.thread == null) {
2831                // We already have the app running, or are waiting for it to
2832                // come up (we have a pid but not yet its thread), so keep it.
2833                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2834                // If this is a new package in the process, add the package to the list
2835                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2836                return app;
2837            }
2838
2839            // An application record is attached to a previous process,
2840            // clean it up now.
2841            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2842            Process.killProcessGroup(app.info.uid, app.pid);
2843            handleAppDiedLocked(app, true, true);
2844        }
2845
2846        String hostingNameStr = hostingName != null
2847                ? hostingName.flattenToShortString() : null;
2848
2849        if (!isolated) {
2850            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2851                // If we are in the background, then check to see if this process
2852                // is bad.  If so, we will just silently fail.
2853                if (mBadProcesses.get(info.processName, info.uid) != null) {
2854                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2855                            + "/" + info.processName);
2856                    return null;
2857                }
2858            } else {
2859                // When the user is explicitly starting a process, then clear its
2860                // crash count so that we won't make it bad until they see at
2861                // least one crash dialog again, and make the process good again
2862                // if it had been bad.
2863                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2864                        + "/" + info.processName);
2865                mProcessCrashTimes.remove(info.processName, info.uid);
2866                if (mBadProcesses.get(info.processName, info.uid) != null) {
2867                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2868                            UserHandle.getUserId(info.uid), info.uid,
2869                            info.processName);
2870                    mBadProcesses.remove(info.processName, info.uid);
2871                    if (app != null) {
2872                        app.bad = false;
2873                    }
2874                }
2875            }
2876        }
2877
2878        if (app == null) {
2879            app = newProcessRecordLocked(info, processName, isolated);
2880            if (app == null) {
2881                Slog.w(TAG, "Failed making new process record for "
2882                        + processName + "/" + info.uid + " isolated=" + isolated);
2883                return null;
2884            }
2885            mProcessNames.put(processName, app.uid, app);
2886            if (isolated) {
2887                mIsolatedProcesses.put(app.uid, app);
2888            }
2889        } else {
2890            // If this is a new package in the process, add the package to the list
2891            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2892        }
2893
2894        // If the system is not ready yet, then hold off on starting this
2895        // process until it is.
2896        if (!mProcessesReady
2897                && !isAllowedWhileBooting(info)
2898                && !allowWhileBooting) {
2899            if (!mProcessesOnHold.contains(app)) {
2900                mProcessesOnHold.add(app);
2901            }
2902            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2903            return app;
2904        }
2905
2906        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2907        return (app.pid != 0) ? app : null;
2908    }
2909
2910    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2911        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2912    }
2913
2914    private final void startProcessLocked(ProcessRecord app,
2915            String hostingType, String hostingNameStr, String abiOverride) {
2916        if (app.pid > 0 && app.pid != MY_PID) {
2917            synchronized (mPidsSelfLocked) {
2918                mPidsSelfLocked.remove(app.pid);
2919                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2920            }
2921            app.setPid(0);
2922        }
2923
2924        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2925                "startProcessLocked removing on hold: " + app);
2926        mProcessesOnHold.remove(app);
2927
2928        updateCpuStats();
2929
2930        try {
2931            int uid = app.uid;
2932
2933            int[] gids = null;
2934            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2935            if (!app.isolated) {
2936                int[] permGids = null;
2937                try {
2938                    final PackageManager pm = mContext.getPackageManager();
2939                    permGids = pm.getPackageGids(app.info.packageName);
2940
2941                    if (Environment.isExternalStorageEmulated()) {
2942                        if (pm.checkPermission(
2943                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2944                                app.info.packageName) == PERMISSION_GRANTED) {
2945                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2946                        } else {
2947                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2948                        }
2949                    }
2950                } catch (PackageManager.NameNotFoundException e) {
2951                    Slog.w(TAG, "Unable to retrieve gids", e);
2952                }
2953
2954                /*
2955                 * Add shared application and profile GIDs so applications can share some
2956                 * resources like shared libraries and access user-wide resources
2957                 */
2958                if (permGids == null) {
2959                    gids = new int[2];
2960                } else {
2961                    gids = new int[permGids.length + 2];
2962                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2963                }
2964                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2965                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2966            }
2967            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2968                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2969                        && mTopComponent != null
2970                        && app.processName.equals(mTopComponent.getPackageName())) {
2971                    uid = 0;
2972                }
2973                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2974                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2975                    uid = 0;
2976                }
2977            }
2978            int debugFlags = 0;
2979            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2980                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2981                // Also turn on CheckJNI for debuggable apps. It's quite
2982                // awkward to turn on otherwise.
2983                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2984            }
2985            // Run the app in safe mode if its manifest requests so or the
2986            // system is booted in safe mode.
2987            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2988                mSafeMode == true) {
2989                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2990            }
2991            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2992                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2993            }
2994            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2995                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2996            }
2997            if ("1".equals(SystemProperties.get("debug.assert"))) {
2998                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2999            }
3000
3001            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3002            if (requiredAbi == null) {
3003                requiredAbi = Build.SUPPORTED_ABIS[0];
3004            }
3005
3006            // Start the process.  It will either succeed and return a result containing
3007            // the PID of the new process, or else throw a RuntimeException.
3008            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3009                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3010                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3011
3012            if (app.isolated) {
3013                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3014            }
3015            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3016
3017            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3018                    UserHandle.getUserId(uid), startResult.pid, uid,
3019                    app.processName, hostingType,
3020                    hostingNameStr != null ? hostingNameStr : "");
3021
3022            if (app.persistent) {
3023                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3024            }
3025
3026            StringBuilder buf = mStringBuilder;
3027            buf.setLength(0);
3028            buf.append("Start proc ");
3029            buf.append(app.processName);
3030            buf.append(" for ");
3031            buf.append(hostingType);
3032            if (hostingNameStr != null) {
3033                buf.append(" ");
3034                buf.append(hostingNameStr);
3035            }
3036            buf.append(": pid=");
3037            buf.append(startResult.pid);
3038            buf.append(" uid=");
3039            buf.append(uid);
3040            buf.append(" gids={");
3041            if (gids != null) {
3042                for (int gi=0; gi<gids.length; gi++) {
3043                    if (gi != 0) buf.append(", ");
3044                    buf.append(gids[gi]);
3045
3046                }
3047            }
3048            buf.append("}");
3049            if (requiredAbi != null) {
3050                buf.append(" abi=");
3051                buf.append(requiredAbi);
3052            }
3053            Slog.i(TAG, buf.toString());
3054            app.setPid(startResult.pid);
3055            app.usingWrapper = startResult.usingWrapper;
3056            app.removed = false;
3057            app.killedByAm = false;
3058            synchronized (mPidsSelfLocked) {
3059                this.mPidsSelfLocked.put(startResult.pid, app);
3060                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3061                msg.obj = app;
3062                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3063                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3064            }
3065        } catch (RuntimeException e) {
3066            // XXX do better error recovery.
3067            app.setPid(0);
3068            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3069            if (app.isolated) {
3070                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3071            }
3072            Slog.e(TAG, "Failure starting process " + app.processName, e);
3073        }
3074    }
3075
3076    void updateUsageStats(ActivityRecord component, boolean resumed) {
3077        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3078        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3079        if (resumed) {
3080            if (mUsageStatsService != null) {
3081                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3082                        UsageStats.Event.MOVE_TO_FOREGROUND);
3083            }
3084            synchronized (stats) {
3085                stats.noteActivityResumedLocked(component.app.uid);
3086            }
3087        } else {
3088            if (mUsageStatsService != null) {
3089                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3090                        UsageStats.Event.MOVE_TO_BACKGROUND);
3091            }
3092            synchronized (stats) {
3093                stats.noteActivityPausedLocked(component.app.uid);
3094            }
3095        }
3096    }
3097
3098    Intent getHomeIntent() {
3099        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3100        intent.setComponent(mTopComponent);
3101        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3102            intent.addCategory(Intent.CATEGORY_HOME);
3103        }
3104        return intent;
3105    }
3106
3107    boolean startHomeActivityLocked(int userId) {
3108        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3109                && mTopAction == null) {
3110            // We are running in factory test mode, but unable to find
3111            // the factory test app, so just sit around displaying the
3112            // error message and don't try to start anything.
3113            return false;
3114        }
3115        Intent intent = getHomeIntent();
3116        ActivityInfo aInfo =
3117            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3118        if (aInfo != null) {
3119            intent.setComponent(new ComponentName(
3120                    aInfo.applicationInfo.packageName, aInfo.name));
3121            // Don't do this if the home app is currently being
3122            // instrumented.
3123            aInfo = new ActivityInfo(aInfo);
3124            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3125            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3126                    aInfo.applicationInfo.uid, true);
3127            if (app == null || app.instrumentationClass == null) {
3128                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3129                mStackSupervisor.startHomeActivity(intent, aInfo);
3130            }
3131        }
3132
3133        return true;
3134    }
3135
3136    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3137        ActivityInfo ai = null;
3138        ComponentName comp = intent.getComponent();
3139        try {
3140            if (comp != null) {
3141                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3142            } else {
3143                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3144                        intent,
3145                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3146                            flags, userId);
3147
3148                if (info != null) {
3149                    ai = info.activityInfo;
3150                }
3151            }
3152        } catch (RemoteException e) {
3153            // ignore
3154        }
3155
3156        return ai;
3157    }
3158
3159    /**
3160     * Starts the "new version setup screen" if appropriate.
3161     */
3162    void startSetupActivityLocked() {
3163        // Only do this once per boot.
3164        if (mCheckedForSetup) {
3165            return;
3166        }
3167
3168        // We will show this screen if the current one is a different
3169        // version than the last one shown, and we are not running in
3170        // low-level factory test mode.
3171        final ContentResolver resolver = mContext.getContentResolver();
3172        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3173                Settings.Global.getInt(resolver,
3174                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3175            mCheckedForSetup = true;
3176
3177            // See if we should be showing the platform update setup UI.
3178            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3179            List<ResolveInfo> ris = mContext.getPackageManager()
3180                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3181
3182            // We don't allow third party apps to replace this.
3183            ResolveInfo ri = null;
3184            for (int i=0; ris != null && i<ris.size(); i++) {
3185                if ((ris.get(i).activityInfo.applicationInfo.flags
3186                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3187                    ri = ris.get(i);
3188                    break;
3189                }
3190            }
3191
3192            if (ri != null) {
3193                String vers = ri.activityInfo.metaData != null
3194                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3195                        : null;
3196                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3197                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3198                            Intent.METADATA_SETUP_VERSION);
3199                }
3200                String lastVers = Settings.Secure.getString(
3201                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3202                if (vers != null && !vers.equals(lastVers)) {
3203                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3204                    intent.setComponent(new ComponentName(
3205                            ri.activityInfo.packageName, ri.activityInfo.name));
3206                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3207                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3208                }
3209            }
3210        }
3211    }
3212
3213    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3214        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3215    }
3216
3217    void enforceNotIsolatedCaller(String caller) {
3218        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3219            throw new SecurityException("Isolated process not allowed to call " + caller);
3220        }
3221    }
3222
3223    @Override
3224    public int getFrontActivityScreenCompatMode() {
3225        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3226        synchronized (this) {
3227            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3228        }
3229    }
3230
3231    @Override
3232    public void setFrontActivityScreenCompatMode(int mode) {
3233        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3234                "setFrontActivityScreenCompatMode");
3235        synchronized (this) {
3236            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3237        }
3238    }
3239
3240    @Override
3241    public int getPackageScreenCompatMode(String packageName) {
3242        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3243        synchronized (this) {
3244            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3245        }
3246    }
3247
3248    @Override
3249    public void setPackageScreenCompatMode(String packageName, int mode) {
3250        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3251                "setPackageScreenCompatMode");
3252        synchronized (this) {
3253            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3254        }
3255    }
3256
3257    @Override
3258    public boolean getPackageAskScreenCompat(String packageName) {
3259        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3260        synchronized (this) {
3261            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3262        }
3263    }
3264
3265    @Override
3266    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3267        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3268                "setPackageAskScreenCompat");
3269        synchronized (this) {
3270            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3271        }
3272    }
3273
3274    private void dispatchProcessesChanged() {
3275        int N;
3276        synchronized (this) {
3277            N = mPendingProcessChanges.size();
3278            if (mActiveProcessChanges.length < N) {
3279                mActiveProcessChanges = new ProcessChangeItem[N];
3280            }
3281            mPendingProcessChanges.toArray(mActiveProcessChanges);
3282            mAvailProcessChanges.addAll(mPendingProcessChanges);
3283            mPendingProcessChanges.clear();
3284            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3285        }
3286
3287        int i = mProcessObservers.beginBroadcast();
3288        while (i > 0) {
3289            i--;
3290            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3291            if (observer != null) {
3292                try {
3293                    for (int j=0; j<N; j++) {
3294                        ProcessChangeItem item = mActiveProcessChanges[j];
3295                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3296                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3297                                    + item.pid + " uid=" + item.uid + ": "
3298                                    + item.foregroundActivities);
3299                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3300                                    item.foregroundActivities);
3301                        }
3302                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3303                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3304                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3305                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3306                        }
3307                    }
3308                } catch (RemoteException e) {
3309                }
3310            }
3311        }
3312        mProcessObservers.finishBroadcast();
3313    }
3314
3315    private void dispatchProcessDied(int pid, int uid) {
3316        int i = mProcessObservers.beginBroadcast();
3317        while (i > 0) {
3318            i--;
3319            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3320            if (observer != null) {
3321                try {
3322                    observer.onProcessDied(pid, uid);
3323                } catch (RemoteException e) {
3324                }
3325            }
3326        }
3327        mProcessObservers.finishBroadcast();
3328    }
3329
3330    @Override
3331    public final int startActivity(IApplicationThread caller, String callingPackage,
3332            Intent intent, String resolvedType, IBinder resultTo,
3333            String resultWho, int requestCode, int startFlags,
3334            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3335        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3336                resultWho, requestCode,
3337                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3338    }
3339
3340    @Override
3341    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3342            Intent intent, String resolvedType, IBinder resultTo,
3343            String resultWho, int requestCode, int startFlags,
3344            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3345        enforceNotIsolatedCaller("startActivity");
3346        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3347                false, ALLOW_FULL_ONLY, "startActivity", null);
3348        // TODO: Switch to user app stacks here.
3349        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3350                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3351                null, null, options, userId, null);
3352    }
3353
3354    @Override
3355    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3356            Intent intent, String resolvedType, IBinder resultTo,
3357            String resultWho, int requestCode, int startFlags, String profileFile,
3358            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3359        enforceNotIsolatedCaller("startActivityAndWait");
3360        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3361                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3362        WaitResult res = new WaitResult();
3363        // TODO: Switch to user app stacks here.
3364        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3365                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3366                res, null, options, userId, null);
3367        return res;
3368    }
3369
3370    @Override
3371    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3372            Intent intent, String resolvedType, IBinder resultTo,
3373            String resultWho, int requestCode, int startFlags, Configuration config,
3374            Bundle options, int userId) {
3375        enforceNotIsolatedCaller("startActivityWithConfig");
3376        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3377                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3378        // TODO: Switch to user app stacks here.
3379        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3380                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3381                null, null, null, config, options, userId, null);
3382        return ret;
3383    }
3384
3385    @Override
3386    public int startActivityIntentSender(IApplicationThread caller,
3387            IntentSender intent, Intent fillInIntent, String resolvedType,
3388            IBinder resultTo, String resultWho, int requestCode,
3389            int flagsMask, int flagsValues, Bundle options) {
3390        enforceNotIsolatedCaller("startActivityIntentSender");
3391        // Refuse possible leaked file descriptors
3392        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3393            throw new IllegalArgumentException("File descriptors passed in Intent");
3394        }
3395
3396        IIntentSender sender = intent.getTarget();
3397        if (!(sender instanceof PendingIntentRecord)) {
3398            throw new IllegalArgumentException("Bad PendingIntent object");
3399        }
3400
3401        PendingIntentRecord pir = (PendingIntentRecord)sender;
3402
3403        synchronized (this) {
3404            // If this is coming from the currently resumed activity, it is
3405            // effectively saying that app switches are allowed at this point.
3406            final ActivityStack stack = getFocusedStack();
3407            if (stack.mResumedActivity != null &&
3408                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3409                mAppSwitchesAllowedTime = 0;
3410            }
3411        }
3412        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3413                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3414        return ret;
3415    }
3416
3417    @Override
3418    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3419            Intent intent, String resolvedType, IVoiceInteractionSession session,
3420            IVoiceInteractor interactor, int startFlags, String profileFile,
3421            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3422        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3423                != PackageManager.PERMISSION_GRANTED) {
3424            String msg = "Permission Denial: startVoiceActivity() from pid="
3425                    + Binder.getCallingPid()
3426                    + ", uid=" + Binder.getCallingUid()
3427                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3428            Slog.w(TAG, msg);
3429            throw new SecurityException(msg);
3430        }
3431        if (session == null || interactor == null) {
3432            throw new NullPointerException("null session or interactor");
3433        }
3434        userId = handleIncomingUser(callingPid, callingUid, userId,
3435                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3436        // TODO: Switch to user app stacks here.
3437        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3438                resolvedType, session, interactor, null, null, 0, startFlags,
3439                profileFile, profileFd, null, null, options, userId, null);
3440    }
3441
3442    @Override
3443    public boolean startNextMatchingActivity(IBinder callingActivity,
3444            Intent intent, Bundle options) {
3445        // Refuse possible leaked file descriptors
3446        if (intent != null && intent.hasFileDescriptors() == true) {
3447            throw new IllegalArgumentException("File descriptors passed in Intent");
3448        }
3449
3450        synchronized (this) {
3451            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3452            if (r == null) {
3453                ActivityOptions.abort(options);
3454                return false;
3455            }
3456            if (r.app == null || r.app.thread == null) {
3457                // The caller is not running...  d'oh!
3458                ActivityOptions.abort(options);
3459                return false;
3460            }
3461            intent = new Intent(intent);
3462            // The caller is not allowed to change the data.
3463            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3464            // And we are resetting to find the next component...
3465            intent.setComponent(null);
3466
3467            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3468
3469            ActivityInfo aInfo = null;
3470            try {
3471                List<ResolveInfo> resolves =
3472                    AppGlobals.getPackageManager().queryIntentActivities(
3473                            intent, r.resolvedType,
3474                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3475                            UserHandle.getCallingUserId());
3476
3477                // Look for the original activity in the list...
3478                final int N = resolves != null ? resolves.size() : 0;
3479                for (int i=0; i<N; i++) {
3480                    ResolveInfo rInfo = resolves.get(i);
3481                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3482                            && rInfo.activityInfo.name.equals(r.info.name)) {
3483                        // We found the current one...  the next matching is
3484                        // after it.
3485                        i++;
3486                        if (i<N) {
3487                            aInfo = resolves.get(i).activityInfo;
3488                        }
3489                        if (debug) {
3490                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3491                                    + "/" + r.info.name);
3492                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3493                                    + "/" + aInfo.name);
3494                        }
3495                        break;
3496                    }
3497                }
3498            } catch (RemoteException e) {
3499            }
3500
3501            if (aInfo == null) {
3502                // Nobody who is next!
3503                ActivityOptions.abort(options);
3504                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3505                return false;
3506            }
3507
3508            intent.setComponent(new ComponentName(
3509                    aInfo.applicationInfo.packageName, aInfo.name));
3510            intent.setFlags(intent.getFlags()&~(
3511                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3512                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3513                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3514                    Intent.FLAG_ACTIVITY_NEW_TASK));
3515
3516            // Okay now we need to start the new activity, replacing the
3517            // currently running activity.  This is a little tricky because
3518            // we want to start the new one as if the current one is finished,
3519            // but not finish the current one first so that there is no flicker.
3520            // And thus...
3521            final boolean wasFinishing = r.finishing;
3522            r.finishing = true;
3523
3524            // Propagate reply information over to the new activity.
3525            final ActivityRecord resultTo = r.resultTo;
3526            final String resultWho = r.resultWho;
3527            final int requestCode = r.requestCode;
3528            r.resultTo = null;
3529            if (resultTo != null) {
3530                resultTo.removeResultsLocked(r, resultWho, requestCode);
3531            }
3532
3533            final long origId = Binder.clearCallingIdentity();
3534            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3535                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3536                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3537                    options, false, null, null);
3538            Binder.restoreCallingIdentity(origId);
3539
3540            r.finishing = wasFinishing;
3541            if (res != ActivityManager.START_SUCCESS) {
3542                return false;
3543            }
3544            return true;
3545        }
3546    }
3547
3548    final int startActivityInPackage(int uid, String callingPackage,
3549            Intent intent, String resolvedType, IBinder resultTo,
3550            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3551                    IActivityContainer container) {
3552
3553        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3554                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3555
3556        // TODO: Switch to user app stacks here.
3557        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3558                null, null, resultTo, resultWho, requestCode, startFlags,
3559                null, null, null, null, options, userId, container);
3560        return ret;
3561    }
3562
3563    @Override
3564    public final int startActivities(IApplicationThread caller, String callingPackage,
3565            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3566            int userId) {
3567        enforceNotIsolatedCaller("startActivities");
3568        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3569                false, ALLOW_FULL_ONLY, "startActivity", null);
3570        // TODO: Switch to user app stacks here.
3571        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3572                resolvedTypes, resultTo, options, userId);
3573        return ret;
3574    }
3575
3576    final int startActivitiesInPackage(int uid, String callingPackage,
3577            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3578            Bundle options, int userId) {
3579
3580        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3581                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3582        // TODO: Switch to user app stacks here.
3583        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3584                resultTo, options, userId);
3585        return ret;
3586    }
3587
3588    final void addRecentTaskLocked(TaskRecord task) {
3589        int N = mRecentTasks.size();
3590        // Quick case: check if the top-most recent task is the same.
3591        if (N > 0 && mRecentTasks.get(0) == task) {
3592            return;
3593        }
3594        // Another quick case: never add voice sessions.
3595        if (task.voiceSession != null) {
3596            return;
3597        }
3598        // Remove any existing entries that are the same kind of task.
3599        final Intent intent = task.intent;
3600        final boolean document = intent != null && intent.isDocument();
3601        final ComponentName comp = intent.getComponent();
3602
3603        int maxRecents = task.maxRecents - 1;
3604        for (int i=0; i<N; i++) {
3605            final TaskRecord tr = mRecentTasks.get(i);
3606            if (task != tr) {
3607                if (task.userId != tr.userId) {
3608                    continue;
3609                }
3610                if (i > MAX_RECENT_BITMAPS) {
3611                    tr.freeLastThumbnail();
3612                }
3613                final Intent trIntent = tr.intent;
3614                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3615                    (intent == null || !intent.filterEquals(trIntent))) {
3616                    continue;
3617                }
3618                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3619                if (document && trIsDocument) {
3620                    // These are the same document activity (not necessarily the same doc).
3621                    if (maxRecents > 0) {
3622                        --maxRecents;
3623                        continue;
3624                    }
3625                    // Hit the maximum number of documents for this task. Fall through
3626                    // and remove this document from recents.
3627                } else if (document || trIsDocument) {
3628                    // Only one of these is a document. Not the droid we're looking for.
3629                    continue;
3630                }
3631            }
3632
3633            // Either task and tr are the same or, their affinities match or their intents match
3634            // and neither of them is a document, or they are documents using the same activity
3635            // and their maxRecents has been reached.
3636            tr.disposeThumbnail();
3637            mRecentTasks.remove(i);
3638            if (task != tr) {
3639                tr.closeRecentsChain();
3640            }
3641            i--;
3642            N--;
3643            if (task.intent == null) {
3644                // If the new recent task we are adding is not fully
3645                // specified, then replace it with the existing recent task.
3646                task = tr;
3647            }
3648            mTaskPersister.notify(tr, false);
3649        }
3650        if (N >= MAX_RECENT_TASKS) {
3651            final TaskRecord tr = mRecentTasks.remove(N - 1);
3652            tr.disposeThumbnail();
3653            tr.closeRecentsChain();
3654        }
3655        mRecentTasks.add(0, task);
3656    }
3657
3658    @Override
3659    public void reportActivityFullyDrawn(IBinder token) {
3660        synchronized (this) {
3661            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3662            if (r == null) {
3663                return;
3664            }
3665            r.reportFullyDrawnLocked();
3666        }
3667    }
3668
3669    @Override
3670    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3671        synchronized (this) {
3672            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3673            if (r == null) {
3674                return;
3675            }
3676            final long origId = Binder.clearCallingIdentity();
3677            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3678            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3679                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3680            if (config != null) {
3681                r.frozenBeforeDestroy = true;
3682                if (!updateConfigurationLocked(config, r, false, false)) {
3683                    mStackSupervisor.resumeTopActivitiesLocked();
3684                }
3685            }
3686            Binder.restoreCallingIdentity(origId);
3687        }
3688    }
3689
3690    @Override
3691    public int getRequestedOrientation(IBinder token) {
3692        synchronized (this) {
3693            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3694            if (r == null) {
3695                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3696            }
3697            return mWindowManager.getAppOrientation(r.appToken);
3698        }
3699    }
3700
3701    /**
3702     * This is the internal entry point for handling Activity.finish().
3703     *
3704     * @param token The Binder token referencing the Activity we want to finish.
3705     * @param resultCode Result code, if any, from this Activity.
3706     * @param resultData Result data (Intent), if any, from this Activity.
3707     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3708     *            the root Activity in the task.
3709     *
3710     * @return Returns true if the activity successfully finished, or false if it is still running.
3711     */
3712    @Override
3713    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3714            boolean finishTask) {
3715        // Refuse possible leaked file descriptors
3716        if (resultData != null && resultData.hasFileDescriptors() == true) {
3717            throw new IllegalArgumentException("File descriptors passed in Intent");
3718        }
3719
3720        synchronized(this) {
3721            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3722            if (r == null) {
3723                return true;
3724            }
3725            // Keep track of the root activity of the task before we finish it
3726            TaskRecord tr = r.task;
3727            ActivityRecord rootR = tr.getRootActivity();
3728            // Do not allow task to finish in Lock Task mode.
3729            if (tr == mStackSupervisor.mLockTaskModeTask) {
3730                if (rootR == r) {
3731                    mStackSupervisor.showLockTaskToast();
3732                    return false;
3733                }
3734            }
3735            if (mController != null) {
3736                // Find the first activity that is not finishing.
3737                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3738                if (next != null) {
3739                    // ask watcher if this is allowed
3740                    boolean resumeOK = true;
3741                    try {
3742                        resumeOK = mController.activityResuming(next.packageName);
3743                    } catch (RemoteException e) {
3744                        mController = null;
3745                        Watchdog.getInstance().setActivityController(null);
3746                    }
3747
3748                    if (!resumeOK) {
3749                        return false;
3750                    }
3751                }
3752            }
3753            final long origId = Binder.clearCallingIdentity();
3754            try {
3755                boolean res;
3756                if (finishTask && r == rootR) {
3757                    // If requested, remove the task that is associated to this activity only if it
3758                    // was the root activity in the task.  The result code and data is ignored because
3759                    // we don't support returning them across task boundaries.
3760                    res = removeTaskByIdLocked(tr.taskId, 0);
3761                } else {
3762                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3763                            resultData, "app-request", true);
3764                }
3765                return res;
3766            } finally {
3767                Binder.restoreCallingIdentity(origId);
3768            }
3769        }
3770    }
3771
3772    @Override
3773    public final void finishHeavyWeightApp() {
3774        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3775                != PackageManager.PERMISSION_GRANTED) {
3776            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3777                    + Binder.getCallingPid()
3778                    + ", uid=" + Binder.getCallingUid()
3779                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3780            Slog.w(TAG, msg);
3781            throw new SecurityException(msg);
3782        }
3783
3784        synchronized(this) {
3785            if (mHeavyWeightProcess == null) {
3786                return;
3787            }
3788
3789            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3790                    mHeavyWeightProcess.activities);
3791            for (int i=0; i<activities.size(); i++) {
3792                ActivityRecord r = activities.get(i);
3793                if (!r.finishing) {
3794                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3795                            null, "finish-heavy", true);
3796                }
3797            }
3798
3799            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3800                    mHeavyWeightProcess.userId, 0));
3801            mHeavyWeightProcess = null;
3802        }
3803    }
3804
3805    @Override
3806    public void crashApplication(int uid, int initialPid, String packageName,
3807            String message) {
3808        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3809                != PackageManager.PERMISSION_GRANTED) {
3810            String msg = "Permission Denial: crashApplication() from pid="
3811                    + Binder.getCallingPid()
3812                    + ", uid=" + Binder.getCallingUid()
3813                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3814            Slog.w(TAG, msg);
3815            throw new SecurityException(msg);
3816        }
3817
3818        synchronized(this) {
3819            ProcessRecord proc = null;
3820
3821            // Figure out which process to kill.  We don't trust that initialPid
3822            // still has any relation to current pids, so must scan through the
3823            // list.
3824            synchronized (mPidsSelfLocked) {
3825                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3826                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3827                    if (p.uid != uid) {
3828                        continue;
3829                    }
3830                    if (p.pid == initialPid) {
3831                        proc = p;
3832                        break;
3833                    }
3834                    if (p.pkgList.containsKey(packageName)) {
3835                        proc = p;
3836                    }
3837                }
3838            }
3839
3840            if (proc == null) {
3841                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3842                        + " initialPid=" + initialPid
3843                        + " packageName=" + packageName);
3844                return;
3845            }
3846
3847            if (proc.thread != null) {
3848                if (proc.pid == Process.myPid()) {
3849                    Log.w(TAG, "crashApplication: trying to crash self!");
3850                    return;
3851                }
3852                long ident = Binder.clearCallingIdentity();
3853                try {
3854                    proc.thread.scheduleCrash(message);
3855                } catch (RemoteException e) {
3856                }
3857                Binder.restoreCallingIdentity(ident);
3858            }
3859        }
3860    }
3861
3862    @Override
3863    public final void finishSubActivity(IBinder token, String resultWho,
3864            int requestCode) {
3865        synchronized(this) {
3866            final long origId = Binder.clearCallingIdentity();
3867            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3868            if (r != null) {
3869                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3870            }
3871            Binder.restoreCallingIdentity(origId);
3872        }
3873    }
3874
3875    @Override
3876    public boolean finishActivityAffinity(IBinder token) {
3877        synchronized(this) {
3878            final long origId = Binder.clearCallingIdentity();
3879            try {
3880                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3881
3882                ActivityRecord rootR = r.task.getRootActivity();
3883                // Do not allow task to finish in Lock Task mode.
3884                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3885                    if (rootR == r) {
3886                        mStackSupervisor.showLockTaskToast();
3887                        return false;
3888                    }
3889                }
3890                boolean res = false;
3891                if (r != null) {
3892                    res = r.task.stack.finishActivityAffinityLocked(r);
3893                }
3894                return res;
3895            } finally {
3896                Binder.restoreCallingIdentity(origId);
3897            }
3898        }
3899    }
3900
3901    @Override
3902    public void finishVoiceTask(IVoiceInteractionSession session) {
3903        synchronized(this) {
3904            final long origId = Binder.clearCallingIdentity();
3905            try {
3906                mStackSupervisor.finishVoiceTask(session);
3907            } finally {
3908                Binder.restoreCallingIdentity(origId);
3909            }
3910        }
3911
3912    }
3913
3914    @Override
3915    public boolean willActivityBeVisible(IBinder token) {
3916        synchronized(this) {
3917            ActivityStack stack = ActivityRecord.getStackLocked(token);
3918            if (stack != null) {
3919                return stack.willActivityBeVisibleLocked(token);
3920            }
3921            return false;
3922        }
3923    }
3924
3925    @Override
3926    public void overridePendingTransition(IBinder token, String packageName,
3927            int enterAnim, int exitAnim) {
3928        synchronized(this) {
3929            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3930            if (self == null) {
3931                return;
3932            }
3933
3934            final long origId = Binder.clearCallingIdentity();
3935
3936            if (self.state == ActivityState.RESUMED
3937                    || self.state == ActivityState.PAUSING) {
3938                mWindowManager.overridePendingAppTransition(packageName,
3939                        enterAnim, exitAnim, null);
3940            }
3941
3942            Binder.restoreCallingIdentity(origId);
3943        }
3944    }
3945
3946    /**
3947     * Main function for removing an existing process from the activity manager
3948     * as a result of that process going away.  Clears out all connections
3949     * to the process.
3950     */
3951    private final void handleAppDiedLocked(ProcessRecord app,
3952            boolean restarting, boolean allowRestart) {
3953        int pid = app.pid;
3954        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3955        if (!restarting) {
3956            removeLruProcessLocked(app);
3957            if (pid > 0) {
3958                ProcessList.remove(pid);
3959            }
3960        }
3961
3962        if (mProfileProc == app) {
3963            clearProfilerLocked();
3964        }
3965
3966        // Remove this application's activities from active lists.
3967        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3968
3969        app.activities.clear();
3970
3971        if (app.instrumentationClass != null) {
3972            Slog.w(TAG, "Crash of app " + app.processName
3973                  + " running instrumentation " + app.instrumentationClass);
3974            Bundle info = new Bundle();
3975            info.putString("shortMsg", "Process crashed.");
3976            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3977        }
3978
3979        if (!restarting) {
3980            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3981                // If there was nothing to resume, and we are not already
3982                // restarting this process, but there is a visible activity that
3983                // is hosted by the process...  then make sure all visible
3984                // activities are running, taking care of restarting this
3985                // process.
3986                if (hasVisibleActivities) {
3987                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3988                }
3989            }
3990        }
3991    }
3992
3993    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3994        IBinder threadBinder = thread.asBinder();
3995        // Find the application record.
3996        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3997            ProcessRecord rec = mLruProcesses.get(i);
3998            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3999                return i;
4000            }
4001        }
4002        return -1;
4003    }
4004
4005    final ProcessRecord getRecordForAppLocked(
4006            IApplicationThread thread) {
4007        if (thread == null) {
4008            return null;
4009        }
4010
4011        int appIndex = getLRURecordIndexForAppLocked(thread);
4012        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4013    }
4014
4015    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4016        // If there are no longer any background processes running,
4017        // and the app that died was not running instrumentation,
4018        // then tell everyone we are now low on memory.
4019        boolean haveBg = false;
4020        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4021            ProcessRecord rec = mLruProcesses.get(i);
4022            if (rec.thread != null
4023                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4024                haveBg = true;
4025                break;
4026            }
4027        }
4028
4029        if (!haveBg) {
4030            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4031            if (doReport) {
4032                long now = SystemClock.uptimeMillis();
4033                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4034                    doReport = false;
4035                } else {
4036                    mLastMemUsageReportTime = now;
4037                }
4038            }
4039            final ArrayList<ProcessMemInfo> memInfos
4040                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4041            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4042            long now = SystemClock.uptimeMillis();
4043            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4044                ProcessRecord rec = mLruProcesses.get(i);
4045                if (rec == dyingProc || rec.thread == null) {
4046                    continue;
4047                }
4048                if (doReport) {
4049                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4050                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4051                }
4052                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4053                    // The low memory report is overriding any current
4054                    // state for a GC request.  Make sure to do
4055                    // heavy/important/visible/foreground processes first.
4056                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4057                        rec.lastRequestedGc = 0;
4058                    } else {
4059                        rec.lastRequestedGc = rec.lastLowMemory;
4060                    }
4061                    rec.reportLowMemory = true;
4062                    rec.lastLowMemory = now;
4063                    mProcessesToGc.remove(rec);
4064                    addProcessToGcListLocked(rec);
4065                }
4066            }
4067            if (doReport) {
4068                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4069                mHandler.sendMessage(msg);
4070            }
4071            scheduleAppGcsLocked();
4072        }
4073    }
4074
4075    final void appDiedLocked(ProcessRecord app, int pid,
4076            IApplicationThread thread) {
4077
4078        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4079        synchronized (stats) {
4080            stats.noteProcessDiedLocked(app.info.uid, pid);
4081        }
4082
4083        Process.killProcessGroup(app.info.uid, pid);
4084
4085        // Clean up already done if the process has been re-started.
4086        if (app.pid == pid && app.thread != null &&
4087                app.thread.asBinder() == thread.asBinder()) {
4088            boolean doLowMem = app.instrumentationClass == null;
4089            boolean doOomAdj = doLowMem;
4090            if (!app.killedByAm) {
4091                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4092                        + ") has died.");
4093                mAllowLowerMemLevel = true;
4094            } else {
4095                // Note that we always want to do oom adj to update our state with the
4096                // new number of procs.
4097                mAllowLowerMemLevel = false;
4098                doLowMem = false;
4099            }
4100            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4101            if (DEBUG_CLEANUP) Slog.v(
4102                TAG, "Dying app: " + app + ", pid: " + pid
4103                + ", thread: " + thread.asBinder());
4104            handleAppDiedLocked(app, false, true);
4105
4106            if (doOomAdj) {
4107                updateOomAdjLocked();
4108            }
4109            if (doLowMem) {
4110                doLowMemReportIfNeededLocked(app);
4111            }
4112        } else if (app.pid != pid) {
4113            // A new process has already been started.
4114            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4115                    + ") has died and restarted (pid " + app.pid + ").");
4116            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4117        } else if (DEBUG_PROCESSES) {
4118            Slog.d(TAG, "Received spurious death notification for thread "
4119                    + thread.asBinder());
4120        }
4121    }
4122
4123    /**
4124     * If a stack trace dump file is configured, dump process stack traces.
4125     * @param clearTraces causes the dump file to be erased prior to the new
4126     *    traces being written, if true; when false, the new traces will be
4127     *    appended to any existing file content.
4128     * @param firstPids of dalvik VM processes to dump stack traces for first
4129     * @param lastPids of dalvik VM processes to dump stack traces for last
4130     * @param nativeProcs optional list of native process names to dump stack crawls
4131     * @return file containing stack traces, or null if no dump file is configured
4132     */
4133    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4134            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4135        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4136        if (tracesPath == null || tracesPath.length() == 0) {
4137            return null;
4138        }
4139
4140        File tracesFile = new File(tracesPath);
4141        try {
4142            File tracesDir = tracesFile.getParentFile();
4143            if (!tracesDir.exists()) {
4144                tracesFile.mkdirs();
4145                if (!SELinux.restorecon(tracesDir)) {
4146                    return null;
4147                }
4148            }
4149            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4150
4151            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4152            tracesFile.createNewFile();
4153            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4154        } catch (IOException e) {
4155            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4156            return null;
4157        }
4158
4159        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4160        return tracesFile;
4161    }
4162
4163    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4164            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4165        // Use a FileObserver to detect when traces finish writing.
4166        // The order of traces is considered important to maintain for legibility.
4167        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4168            @Override
4169            public synchronized void onEvent(int event, String path) { notify(); }
4170        };
4171
4172        try {
4173            observer.startWatching();
4174
4175            // First collect all of the stacks of the most important pids.
4176            if (firstPids != null) {
4177                try {
4178                    int num = firstPids.size();
4179                    for (int i = 0; i < num; i++) {
4180                        synchronized (observer) {
4181                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4182                            observer.wait(200);  // Wait for write-close, give up after 200msec
4183                        }
4184                    }
4185                } catch (InterruptedException e) {
4186                    Log.wtf(TAG, e);
4187                }
4188            }
4189
4190            // Next collect the stacks of the native pids
4191            if (nativeProcs != null) {
4192                int[] pids = Process.getPidsForCommands(nativeProcs);
4193                if (pids != null) {
4194                    for (int pid : pids) {
4195                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4196                    }
4197                }
4198            }
4199
4200            // Lastly, measure CPU usage.
4201            if (processCpuTracker != null) {
4202                processCpuTracker.init();
4203                System.gc();
4204                processCpuTracker.update();
4205                try {
4206                    synchronized (processCpuTracker) {
4207                        processCpuTracker.wait(500); // measure over 1/2 second.
4208                    }
4209                } catch (InterruptedException e) {
4210                }
4211                processCpuTracker.update();
4212
4213                // We'll take the stack crawls of just the top apps using CPU.
4214                final int N = processCpuTracker.countWorkingStats();
4215                int numProcs = 0;
4216                for (int i=0; i<N && numProcs<5; i++) {
4217                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4218                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4219                        numProcs++;
4220                        try {
4221                            synchronized (observer) {
4222                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4223                                observer.wait(200);  // Wait for write-close, give up after 200msec
4224                            }
4225                        } catch (InterruptedException e) {
4226                            Log.wtf(TAG, e);
4227                        }
4228
4229                    }
4230                }
4231            }
4232        } finally {
4233            observer.stopWatching();
4234        }
4235    }
4236
4237    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4238        if (true || IS_USER_BUILD) {
4239            return;
4240        }
4241        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4242        if (tracesPath == null || tracesPath.length() == 0) {
4243            return;
4244        }
4245
4246        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4247        StrictMode.allowThreadDiskWrites();
4248        try {
4249            final File tracesFile = new File(tracesPath);
4250            final File tracesDir = tracesFile.getParentFile();
4251            final File tracesTmp = new File(tracesDir, "__tmp__");
4252            try {
4253                if (!tracesDir.exists()) {
4254                    tracesFile.mkdirs();
4255                    if (!SELinux.restorecon(tracesDir.getPath())) {
4256                        return;
4257                    }
4258                }
4259                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4260
4261                if (tracesFile.exists()) {
4262                    tracesTmp.delete();
4263                    tracesFile.renameTo(tracesTmp);
4264                }
4265                StringBuilder sb = new StringBuilder();
4266                Time tobj = new Time();
4267                tobj.set(System.currentTimeMillis());
4268                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4269                sb.append(": ");
4270                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4271                sb.append(" since ");
4272                sb.append(msg);
4273                FileOutputStream fos = new FileOutputStream(tracesFile);
4274                fos.write(sb.toString().getBytes());
4275                if (app == null) {
4276                    fos.write("\n*** No application process!".getBytes());
4277                }
4278                fos.close();
4279                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4280            } catch (IOException e) {
4281                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4282                return;
4283            }
4284
4285            if (app != null) {
4286                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4287                firstPids.add(app.pid);
4288                dumpStackTraces(tracesPath, firstPids, null, null, null);
4289            }
4290
4291            File lastTracesFile = null;
4292            File curTracesFile = null;
4293            for (int i=9; i>=0; i--) {
4294                String name = String.format(Locale.US, "slow%02d.txt", i);
4295                curTracesFile = new File(tracesDir, name);
4296                if (curTracesFile.exists()) {
4297                    if (lastTracesFile != null) {
4298                        curTracesFile.renameTo(lastTracesFile);
4299                    } else {
4300                        curTracesFile.delete();
4301                    }
4302                }
4303                lastTracesFile = curTracesFile;
4304            }
4305            tracesFile.renameTo(curTracesFile);
4306            if (tracesTmp.exists()) {
4307                tracesTmp.renameTo(tracesFile);
4308            }
4309        } finally {
4310            StrictMode.setThreadPolicy(oldPolicy);
4311        }
4312    }
4313
4314    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4315            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4316        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4317        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4318
4319        if (mController != null) {
4320            try {
4321                // 0 == continue, -1 = kill process immediately
4322                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4323                if (res < 0 && app.pid != MY_PID) {
4324                    Process.killProcess(app.pid);
4325                    Process.killProcessGroup(app.info.uid, app.pid);
4326                }
4327            } catch (RemoteException e) {
4328                mController = null;
4329                Watchdog.getInstance().setActivityController(null);
4330            }
4331        }
4332
4333        long anrTime = SystemClock.uptimeMillis();
4334        if (MONITOR_CPU_USAGE) {
4335            updateCpuStatsNow();
4336        }
4337
4338        synchronized (this) {
4339            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4340            if (mShuttingDown) {
4341                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4342                return;
4343            } else if (app.notResponding) {
4344                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4345                return;
4346            } else if (app.crashing) {
4347                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4348                return;
4349            }
4350
4351            // In case we come through here for the same app before completing
4352            // this one, mark as anring now so we will bail out.
4353            app.notResponding = true;
4354
4355            // Log the ANR to the event log.
4356            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4357                    app.processName, app.info.flags, annotation);
4358
4359            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4360            firstPids.add(app.pid);
4361
4362            int parentPid = app.pid;
4363            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4364            if (parentPid != app.pid) firstPids.add(parentPid);
4365
4366            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4367
4368            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4369                ProcessRecord r = mLruProcesses.get(i);
4370                if (r != null && r.thread != null) {
4371                    int pid = r.pid;
4372                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4373                        if (r.persistent) {
4374                            firstPids.add(pid);
4375                        } else {
4376                            lastPids.put(pid, Boolean.TRUE);
4377                        }
4378                    }
4379                }
4380            }
4381        }
4382
4383        // Log the ANR to the main log.
4384        StringBuilder info = new StringBuilder();
4385        info.setLength(0);
4386        info.append("ANR in ").append(app.processName);
4387        if (activity != null && activity.shortComponentName != null) {
4388            info.append(" (").append(activity.shortComponentName).append(")");
4389        }
4390        info.append("\n");
4391        info.append("PID: ").append(app.pid).append("\n");
4392        if (annotation != null) {
4393            info.append("Reason: ").append(annotation).append("\n");
4394        }
4395        if (parent != null && parent != activity) {
4396            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4397        }
4398
4399        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4400
4401        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4402                NATIVE_STACKS_OF_INTEREST);
4403
4404        String cpuInfo = null;
4405        if (MONITOR_CPU_USAGE) {
4406            updateCpuStatsNow();
4407            synchronized (mProcessCpuThread) {
4408                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4409            }
4410            info.append(processCpuTracker.printCurrentLoad());
4411            info.append(cpuInfo);
4412        }
4413
4414        info.append(processCpuTracker.printCurrentState(anrTime));
4415
4416        Slog.e(TAG, info.toString());
4417        if (tracesFile == null) {
4418            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4419            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4420        }
4421
4422        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4423                cpuInfo, tracesFile, null);
4424
4425        if (mController != null) {
4426            try {
4427                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4428                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4429                if (res != 0) {
4430                    if (res < 0 && app.pid != MY_PID) {
4431                        Process.killProcess(app.pid);
4432                        Process.killProcessGroup(app.info.uid, app.pid);
4433                    } else {
4434                        synchronized (this) {
4435                            mServices.scheduleServiceTimeoutLocked(app);
4436                        }
4437                    }
4438                    return;
4439                }
4440            } catch (RemoteException e) {
4441                mController = null;
4442                Watchdog.getInstance().setActivityController(null);
4443            }
4444        }
4445
4446        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4447        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4448                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4449
4450        synchronized (this) {
4451            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4452                killUnneededProcessLocked(app, "background ANR");
4453                return;
4454            }
4455
4456            // Set the app's notResponding state, and look up the errorReportReceiver
4457            makeAppNotRespondingLocked(app,
4458                    activity != null ? activity.shortComponentName : null,
4459                    annotation != null ? "ANR " + annotation : "ANR",
4460                    info.toString());
4461
4462            // Bring up the infamous App Not Responding dialog
4463            Message msg = Message.obtain();
4464            HashMap<String, Object> map = new HashMap<String, Object>();
4465            msg.what = SHOW_NOT_RESPONDING_MSG;
4466            msg.obj = map;
4467            msg.arg1 = aboveSystem ? 1 : 0;
4468            map.put("app", app);
4469            if (activity != null) {
4470                map.put("activity", activity);
4471            }
4472
4473            mHandler.sendMessage(msg);
4474        }
4475    }
4476
4477    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4478        if (!mLaunchWarningShown) {
4479            mLaunchWarningShown = true;
4480            mHandler.post(new Runnable() {
4481                @Override
4482                public void run() {
4483                    synchronized (ActivityManagerService.this) {
4484                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4485                        d.show();
4486                        mHandler.postDelayed(new Runnable() {
4487                            @Override
4488                            public void run() {
4489                                synchronized (ActivityManagerService.this) {
4490                                    d.dismiss();
4491                                    mLaunchWarningShown = false;
4492                                }
4493                            }
4494                        }, 4000);
4495                    }
4496                }
4497            });
4498        }
4499    }
4500
4501    @Override
4502    public boolean clearApplicationUserData(final String packageName,
4503            final IPackageDataObserver observer, int userId) {
4504        enforceNotIsolatedCaller("clearApplicationUserData");
4505        int uid = Binder.getCallingUid();
4506        int pid = Binder.getCallingPid();
4507        userId = handleIncomingUser(pid, uid,
4508                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4509        long callingId = Binder.clearCallingIdentity();
4510        try {
4511            IPackageManager pm = AppGlobals.getPackageManager();
4512            int pkgUid = -1;
4513            synchronized(this) {
4514                try {
4515                    pkgUid = pm.getPackageUid(packageName, userId);
4516                } catch (RemoteException e) {
4517                }
4518                if (pkgUid == -1) {
4519                    Slog.w(TAG, "Invalid packageName: " + packageName);
4520                    if (observer != null) {
4521                        try {
4522                            observer.onRemoveCompleted(packageName, false);
4523                        } catch (RemoteException e) {
4524                            Slog.i(TAG, "Observer no longer exists.");
4525                        }
4526                    }
4527                    return false;
4528                }
4529                if (uid == pkgUid || checkComponentPermission(
4530                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4531                        pid, uid, -1, true)
4532                        == PackageManager.PERMISSION_GRANTED) {
4533                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4534                } else {
4535                    throw new SecurityException("PID " + pid + " does not have permission "
4536                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4537                                    + " of package " + packageName);
4538                }
4539            }
4540
4541            try {
4542                // Clear application user data
4543                pm.clearApplicationUserData(packageName, observer, userId);
4544
4545                // Remove all permissions granted from/to this package
4546                removeUriPermissionsForPackageLocked(packageName, userId, true);
4547
4548                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4549                        Uri.fromParts("package", packageName, null));
4550                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4551                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4552                        null, null, 0, null, null, null, false, false, userId);
4553            } catch (RemoteException e) {
4554            }
4555        } finally {
4556            Binder.restoreCallingIdentity(callingId);
4557        }
4558        return true;
4559    }
4560
4561    @Override
4562    public void killBackgroundProcesses(final String packageName, int userId) {
4563        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4564                != PackageManager.PERMISSION_GRANTED &&
4565                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4566                        != PackageManager.PERMISSION_GRANTED) {
4567            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4568                    + Binder.getCallingPid()
4569                    + ", uid=" + Binder.getCallingUid()
4570                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4571            Slog.w(TAG, msg);
4572            throw new SecurityException(msg);
4573        }
4574
4575        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4576                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4577        long callingId = Binder.clearCallingIdentity();
4578        try {
4579            IPackageManager pm = AppGlobals.getPackageManager();
4580            synchronized(this) {
4581                int appId = -1;
4582                try {
4583                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4584                } catch (RemoteException e) {
4585                }
4586                if (appId == -1) {
4587                    Slog.w(TAG, "Invalid packageName: " + packageName);
4588                    return;
4589                }
4590                killPackageProcessesLocked(packageName, appId, userId,
4591                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4592            }
4593        } finally {
4594            Binder.restoreCallingIdentity(callingId);
4595        }
4596    }
4597
4598    @Override
4599    public void killAllBackgroundProcesses() {
4600        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4601                != PackageManager.PERMISSION_GRANTED) {
4602            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4603                    + Binder.getCallingPid()
4604                    + ", uid=" + Binder.getCallingUid()
4605                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4606            Slog.w(TAG, msg);
4607            throw new SecurityException(msg);
4608        }
4609
4610        long callingId = Binder.clearCallingIdentity();
4611        try {
4612            synchronized(this) {
4613                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4614                final int NP = mProcessNames.getMap().size();
4615                for (int ip=0; ip<NP; ip++) {
4616                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4617                    final int NA = apps.size();
4618                    for (int ia=0; ia<NA; ia++) {
4619                        ProcessRecord app = apps.valueAt(ia);
4620                        if (app.persistent) {
4621                            // we don't kill persistent processes
4622                            continue;
4623                        }
4624                        if (app.removed) {
4625                            procs.add(app);
4626                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4627                            app.removed = true;
4628                            procs.add(app);
4629                        }
4630                    }
4631                }
4632
4633                int N = procs.size();
4634                for (int i=0; i<N; i++) {
4635                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4636                }
4637                mAllowLowerMemLevel = true;
4638                updateOomAdjLocked();
4639                doLowMemReportIfNeededLocked(null);
4640            }
4641        } finally {
4642            Binder.restoreCallingIdentity(callingId);
4643        }
4644    }
4645
4646    @Override
4647    public void forceStopPackage(final String packageName, int userId) {
4648        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4649                != PackageManager.PERMISSION_GRANTED) {
4650            String msg = "Permission Denial: forceStopPackage() from pid="
4651                    + Binder.getCallingPid()
4652                    + ", uid=" + Binder.getCallingUid()
4653                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4654            Slog.w(TAG, msg);
4655            throw new SecurityException(msg);
4656        }
4657        final int callingPid = Binder.getCallingPid();
4658        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4659                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4660        long callingId = Binder.clearCallingIdentity();
4661        try {
4662            IPackageManager pm = AppGlobals.getPackageManager();
4663            synchronized(this) {
4664                int[] users = userId == UserHandle.USER_ALL
4665                        ? getUsersLocked() : new int[] { userId };
4666                for (int user : users) {
4667                    int pkgUid = -1;
4668                    try {
4669                        pkgUid = pm.getPackageUid(packageName, user);
4670                    } catch (RemoteException e) {
4671                    }
4672                    if (pkgUid == -1) {
4673                        Slog.w(TAG, "Invalid packageName: " + packageName);
4674                        continue;
4675                    }
4676                    try {
4677                        pm.setPackageStoppedState(packageName, true, user);
4678                    } catch (RemoteException e) {
4679                    } catch (IllegalArgumentException e) {
4680                        Slog.w(TAG, "Failed trying to unstop package "
4681                                + packageName + ": " + e);
4682                    }
4683                    if (isUserRunningLocked(user, false)) {
4684                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4685                    }
4686                }
4687            }
4688        } finally {
4689            Binder.restoreCallingIdentity(callingId);
4690        }
4691    }
4692
4693    @Override
4694    public void addPackageDependency(String packageName) {
4695        synchronized (this) {
4696            int callingPid = Binder.getCallingPid();
4697            if (callingPid == Process.myPid()) {
4698                //  Yeah, um, no.
4699                Slog.w(TAG, "Can't addPackageDependency on system process");
4700                return;
4701            }
4702            ProcessRecord proc;
4703            synchronized (mPidsSelfLocked) {
4704                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4705            }
4706            if (proc != null) {
4707                if (proc.pkgDeps == null) {
4708                    proc.pkgDeps = new ArraySet<String>(1);
4709                }
4710                proc.pkgDeps.add(packageName);
4711            }
4712        }
4713    }
4714
4715    /*
4716     * The pkg name and app id have to be specified.
4717     */
4718    @Override
4719    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4720        if (pkg == null) {
4721            return;
4722        }
4723        // Make sure the uid is valid.
4724        if (appid < 0) {
4725            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4726            return;
4727        }
4728        int callerUid = Binder.getCallingUid();
4729        // Only the system server can kill an application
4730        if (callerUid == Process.SYSTEM_UID) {
4731            // Post an aysnc message to kill the application
4732            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4733            msg.arg1 = appid;
4734            msg.arg2 = 0;
4735            Bundle bundle = new Bundle();
4736            bundle.putString("pkg", pkg);
4737            bundle.putString("reason", reason);
4738            msg.obj = bundle;
4739            mHandler.sendMessage(msg);
4740        } else {
4741            throw new SecurityException(callerUid + " cannot kill pkg: " +
4742                    pkg);
4743        }
4744    }
4745
4746    @Override
4747    public void closeSystemDialogs(String reason) {
4748        enforceNotIsolatedCaller("closeSystemDialogs");
4749
4750        final int pid = Binder.getCallingPid();
4751        final int uid = Binder.getCallingUid();
4752        final long origId = Binder.clearCallingIdentity();
4753        try {
4754            synchronized (this) {
4755                // Only allow this from foreground processes, so that background
4756                // applications can't abuse it to prevent system UI from being shown.
4757                if (uid >= Process.FIRST_APPLICATION_UID) {
4758                    ProcessRecord proc;
4759                    synchronized (mPidsSelfLocked) {
4760                        proc = mPidsSelfLocked.get(pid);
4761                    }
4762                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4763                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4764                                + " from background process " + proc);
4765                        return;
4766                    }
4767                }
4768                closeSystemDialogsLocked(reason);
4769            }
4770        } finally {
4771            Binder.restoreCallingIdentity(origId);
4772        }
4773    }
4774
4775    void closeSystemDialogsLocked(String reason) {
4776        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4777        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4778                | Intent.FLAG_RECEIVER_FOREGROUND);
4779        if (reason != null) {
4780            intent.putExtra("reason", reason);
4781        }
4782        mWindowManager.closeSystemDialogs(reason);
4783
4784        mStackSupervisor.closeSystemDialogsLocked();
4785
4786        broadcastIntentLocked(null, null, intent, null,
4787                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4788                Process.SYSTEM_UID, UserHandle.USER_ALL);
4789    }
4790
4791    @Override
4792    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4793        enforceNotIsolatedCaller("getProcessMemoryInfo");
4794        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4795        for (int i=pids.length-1; i>=0; i--) {
4796            ProcessRecord proc;
4797            int oomAdj;
4798            synchronized (this) {
4799                synchronized (mPidsSelfLocked) {
4800                    proc = mPidsSelfLocked.get(pids[i]);
4801                    oomAdj = proc != null ? proc.setAdj : 0;
4802                }
4803            }
4804            infos[i] = new Debug.MemoryInfo();
4805            Debug.getMemoryInfo(pids[i], infos[i]);
4806            if (proc != null) {
4807                synchronized (this) {
4808                    if (proc.thread != null && proc.setAdj == oomAdj) {
4809                        // Record this for posterity if the process has been stable.
4810                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4811                                infos[i].getTotalUss(), false, proc.pkgList);
4812                    }
4813                }
4814            }
4815        }
4816        return infos;
4817    }
4818
4819    @Override
4820    public long[] getProcessPss(int[] pids) {
4821        enforceNotIsolatedCaller("getProcessPss");
4822        long[] pss = new long[pids.length];
4823        for (int i=pids.length-1; i>=0; i--) {
4824            ProcessRecord proc;
4825            int oomAdj;
4826            synchronized (this) {
4827                synchronized (mPidsSelfLocked) {
4828                    proc = mPidsSelfLocked.get(pids[i]);
4829                    oomAdj = proc != null ? proc.setAdj : 0;
4830                }
4831            }
4832            long[] tmpUss = new long[1];
4833            pss[i] = Debug.getPss(pids[i], tmpUss);
4834            if (proc != null) {
4835                synchronized (this) {
4836                    if (proc.thread != null && proc.setAdj == oomAdj) {
4837                        // Record this for posterity if the process has been stable.
4838                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4839                    }
4840                }
4841            }
4842        }
4843        return pss;
4844    }
4845
4846    @Override
4847    public void killApplicationProcess(String processName, int uid) {
4848        if (processName == null) {
4849            return;
4850        }
4851
4852        int callerUid = Binder.getCallingUid();
4853        // Only the system server can kill an application
4854        if (callerUid == Process.SYSTEM_UID) {
4855            synchronized (this) {
4856                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4857                if (app != null && app.thread != null) {
4858                    try {
4859                        app.thread.scheduleSuicide();
4860                    } catch (RemoteException e) {
4861                        // If the other end already died, then our work here is done.
4862                    }
4863                } else {
4864                    Slog.w(TAG, "Process/uid not found attempting kill of "
4865                            + processName + " / " + uid);
4866                }
4867            }
4868        } else {
4869            throw new SecurityException(callerUid + " cannot kill app process: " +
4870                    processName);
4871        }
4872    }
4873
4874    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4875        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4876                false, true, false, false, UserHandle.getUserId(uid), reason);
4877        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4878                Uri.fromParts("package", packageName, null));
4879        if (!mProcessesReady) {
4880            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4881                    | Intent.FLAG_RECEIVER_FOREGROUND);
4882        }
4883        intent.putExtra(Intent.EXTRA_UID, uid);
4884        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4885        broadcastIntentLocked(null, null, intent,
4886                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4887                false, false,
4888                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4889    }
4890
4891    private void forceStopUserLocked(int userId, String reason) {
4892        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4893        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4894        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4895                | Intent.FLAG_RECEIVER_FOREGROUND);
4896        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4897        broadcastIntentLocked(null, null, intent,
4898                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4899                false, false,
4900                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4901    }
4902
4903    private final boolean killPackageProcessesLocked(String packageName, int appId,
4904            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4905            boolean doit, boolean evenPersistent, String reason) {
4906        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4907
4908        // Remove all processes this package may have touched: all with the
4909        // same UID (except for the system or root user), and all whose name
4910        // matches the package name.
4911        final int NP = mProcessNames.getMap().size();
4912        for (int ip=0; ip<NP; ip++) {
4913            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4914            final int NA = apps.size();
4915            for (int ia=0; ia<NA; ia++) {
4916                ProcessRecord app = apps.valueAt(ia);
4917                if (app.persistent && !evenPersistent) {
4918                    // we don't kill persistent processes
4919                    continue;
4920                }
4921                if (app.removed) {
4922                    if (doit) {
4923                        procs.add(app);
4924                    }
4925                    continue;
4926                }
4927
4928                // Skip process if it doesn't meet our oom adj requirement.
4929                if (app.setAdj < minOomAdj) {
4930                    continue;
4931                }
4932
4933                // If no package is specified, we call all processes under the
4934                // give user id.
4935                if (packageName == null) {
4936                    if (app.userId != userId) {
4937                        continue;
4938                    }
4939                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4940                        continue;
4941                    }
4942                // Package has been specified, we want to hit all processes
4943                // that match it.  We need to qualify this by the processes
4944                // that are running under the specified app and user ID.
4945                } else {
4946                    final boolean isDep = app.pkgDeps != null
4947                            && app.pkgDeps.contains(packageName);
4948                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
4949                        continue;
4950                    }
4951                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4952                        continue;
4953                    }
4954                    if (!app.pkgList.containsKey(packageName) && !isDep) {
4955                        continue;
4956                    }
4957                }
4958
4959                // Process has passed all conditions, kill it!
4960                if (!doit) {
4961                    return true;
4962                }
4963                app.removed = true;
4964                procs.add(app);
4965            }
4966        }
4967
4968        int N = procs.size();
4969        for (int i=0; i<N; i++) {
4970            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4971        }
4972        updateOomAdjLocked();
4973        return N > 0;
4974    }
4975
4976    private final boolean forceStopPackageLocked(String name, int appId,
4977            boolean callerWillRestart, boolean purgeCache, boolean doit,
4978            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4979        int i;
4980        int N;
4981
4982        if (userId == UserHandle.USER_ALL && name == null) {
4983            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4984        }
4985
4986        if (appId < 0 && name != null) {
4987            try {
4988                appId = UserHandle.getAppId(
4989                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4990            } catch (RemoteException e) {
4991            }
4992        }
4993
4994        if (doit) {
4995            if (name != null) {
4996                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4997                        + " user=" + userId + ": " + reason);
4998            } else {
4999                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5000            }
5001
5002            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5003            for (int ip=pmap.size()-1; ip>=0; ip--) {
5004                SparseArray<Long> ba = pmap.valueAt(ip);
5005                for (i=ba.size()-1; i>=0; i--) {
5006                    boolean remove = false;
5007                    final int entUid = ba.keyAt(i);
5008                    if (name != null) {
5009                        if (userId == UserHandle.USER_ALL) {
5010                            if (UserHandle.getAppId(entUid) == appId) {
5011                                remove = true;
5012                            }
5013                        } else {
5014                            if (entUid == UserHandle.getUid(userId, appId)) {
5015                                remove = true;
5016                            }
5017                        }
5018                    } else if (UserHandle.getUserId(entUid) == userId) {
5019                        remove = true;
5020                    }
5021                    if (remove) {
5022                        ba.removeAt(i);
5023                    }
5024                }
5025                if (ba.size() == 0) {
5026                    pmap.removeAt(ip);
5027                }
5028            }
5029        }
5030
5031        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5032                -100, callerWillRestart, true, doit, evenPersistent,
5033                name == null ? ("stop user " + userId) : ("stop " + name));
5034
5035        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5036            if (!doit) {
5037                return true;
5038            }
5039            didSomething = true;
5040        }
5041
5042        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5043            if (!doit) {
5044                return true;
5045            }
5046            didSomething = true;
5047        }
5048
5049        if (name == null) {
5050            // Remove all sticky broadcasts from this user.
5051            mStickyBroadcasts.remove(userId);
5052        }
5053
5054        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5055        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5056                userId, providers)) {
5057            if (!doit) {
5058                return true;
5059            }
5060            didSomething = true;
5061        }
5062        N = providers.size();
5063        for (i=0; i<N; i++) {
5064            removeDyingProviderLocked(null, providers.get(i), true);
5065        }
5066
5067        // Remove transient permissions granted from/to this package/user
5068        removeUriPermissionsForPackageLocked(name, userId, false);
5069
5070        if (name == null || uninstalling) {
5071            // Remove pending intents.  For now we only do this when force
5072            // stopping users, because we have some problems when doing this
5073            // for packages -- app widgets are not currently cleaned up for
5074            // such packages, so they can be left with bad pending intents.
5075            if (mIntentSenderRecords.size() > 0) {
5076                Iterator<WeakReference<PendingIntentRecord>> it
5077                        = mIntentSenderRecords.values().iterator();
5078                while (it.hasNext()) {
5079                    WeakReference<PendingIntentRecord> wpir = it.next();
5080                    if (wpir == null) {
5081                        it.remove();
5082                        continue;
5083                    }
5084                    PendingIntentRecord pir = wpir.get();
5085                    if (pir == null) {
5086                        it.remove();
5087                        continue;
5088                    }
5089                    if (name == null) {
5090                        // Stopping user, remove all objects for the user.
5091                        if (pir.key.userId != userId) {
5092                            // Not the same user, skip it.
5093                            continue;
5094                        }
5095                    } else {
5096                        if (UserHandle.getAppId(pir.uid) != appId) {
5097                            // Different app id, skip it.
5098                            continue;
5099                        }
5100                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5101                            // Different user, skip it.
5102                            continue;
5103                        }
5104                        if (!pir.key.packageName.equals(name)) {
5105                            // Different package, skip it.
5106                            continue;
5107                        }
5108                    }
5109                    if (!doit) {
5110                        return true;
5111                    }
5112                    didSomething = true;
5113                    it.remove();
5114                    pir.canceled = true;
5115                    if (pir.key.activity != null) {
5116                        pir.key.activity.pendingResults.remove(pir.ref);
5117                    }
5118                }
5119            }
5120        }
5121
5122        if (doit) {
5123            if (purgeCache && name != null) {
5124                AttributeCache ac = AttributeCache.instance();
5125                if (ac != null) {
5126                    ac.removePackage(name);
5127                }
5128            }
5129            if (mBooted) {
5130                mStackSupervisor.resumeTopActivitiesLocked();
5131                mStackSupervisor.scheduleIdleLocked();
5132            }
5133        }
5134
5135        return didSomething;
5136    }
5137
5138    private final boolean removeProcessLocked(ProcessRecord app,
5139            boolean callerWillRestart, boolean allowRestart, String reason) {
5140        final String name = app.processName;
5141        final int uid = app.uid;
5142        if (DEBUG_PROCESSES) Slog.d(
5143            TAG, "Force removing proc " + app.toShortString() + " (" + name
5144            + "/" + uid + ")");
5145
5146        mProcessNames.remove(name, uid);
5147        mIsolatedProcesses.remove(app.uid);
5148        if (mHeavyWeightProcess == app) {
5149            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5150                    mHeavyWeightProcess.userId, 0));
5151            mHeavyWeightProcess = null;
5152        }
5153        boolean needRestart = false;
5154        if (app.pid > 0 && app.pid != MY_PID) {
5155            int pid = app.pid;
5156            synchronized (mPidsSelfLocked) {
5157                mPidsSelfLocked.remove(pid);
5158                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5159            }
5160            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5161            if (app.isolated) {
5162                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5163            }
5164            killUnneededProcessLocked(app, reason);
5165            Process.killProcessGroup(app.info.uid, app.pid);
5166            handleAppDiedLocked(app, true, allowRestart);
5167            removeLruProcessLocked(app);
5168
5169            if (app.persistent && !app.isolated) {
5170                if (!callerWillRestart) {
5171                    addAppLocked(app.info, false, null /* ABI override */);
5172                } else {
5173                    needRestart = true;
5174                }
5175            }
5176        } else {
5177            mRemovedProcesses.add(app);
5178        }
5179
5180        return needRestart;
5181    }
5182
5183    private final void processStartTimedOutLocked(ProcessRecord app) {
5184        final int pid = app.pid;
5185        boolean gone = false;
5186        synchronized (mPidsSelfLocked) {
5187            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5188            if (knownApp != null && knownApp.thread == null) {
5189                mPidsSelfLocked.remove(pid);
5190                gone = true;
5191            }
5192        }
5193
5194        if (gone) {
5195            Slog.w(TAG, "Process " + app + " failed to attach");
5196            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5197                    pid, app.uid, app.processName);
5198            mProcessNames.remove(app.processName, app.uid);
5199            mIsolatedProcesses.remove(app.uid);
5200            if (mHeavyWeightProcess == app) {
5201                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5202                        mHeavyWeightProcess.userId, 0));
5203                mHeavyWeightProcess = null;
5204            }
5205            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5206            if (app.isolated) {
5207                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5208            }
5209            // Take care of any launching providers waiting for this process.
5210            checkAppInLaunchingProvidersLocked(app, true);
5211            // Take care of any services that are waiting for the process.
5212            mServices.processStartTimedOutLocked(app);
5213            killUnneededProcessLocked(app, "start timeout");
5214            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5215                Slog.w(TAG, "Unattached app died before backup, skipping");
5216                try {
5217                    IBackupManager bm = IBackupManager.Stub.asInterface(
5218                            ServiceManager.getService(Context.BACKUP_SERVICE));
5219                    bm.agentDisconnected(app.info.packageName);
5220                } catch (RemoteException e) {
5221                    // Can't happen; the backup manager is local
5222                }
5223            }
5224            if (isPendingBroadcastProcessLocked(pid)) {
5225                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5226                skipPendingBroadcastLocked(pid);
5227            }
5228        } else {
5229            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5230        }
5231    }
5232
5233    private final boolean attachApplicationLocked(IApplicationThread thread,
5234            int pid) {
5235
5236        // Find the application record that is being attached...  either via
5237        // the pid if we are running in multiple processes, or just pull the
5238        // next app record if we are emulating process with anonymous threads.
5239        ProcessRecord app;
5240        if (pid != MY_PID && pid >= 0) {
5241            synchronized (mPidsSelfLocked) {
5242                app = mPidsSelfLocked.get(pid);
5243            }
5244        } else {
5245            app = null;
5246        }
5247
5248        if (app == null) {
5249            Slog.w(TAG, "No pending application record for pid " + pid
5250                    + " (IApplicationThread " + thread + "); dropping process");
5251            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5252            if (pid > 0 && pid != MY_PID) {
5253                Process.killProcessQuiet(pid);
5254                //TODO: Process.killProcessGroup(app.info.uid, pid);
5255            } else {
5256                try {
5257                    thread.scheduleExit();
5258                } catch (Exception e) {
5259                    // Ignore exceptions.
5260                }
5261            }
5262            return false;
5263        }
5264
5265        // If this application record is still attached to a previous
5266        // process, clean it up now.
5267        if (app.thread != null) {
5268            handleAppDiedLocked(app, true, true);
5269        }
5270
5271        // Tell the process all about itself.
5272
5273        if (localLOGV) Slog.v(
5274                TAG, "Binding process pid " + pid + " to record " + app);
5275
5276        final String processName = app.processName;
5277        try {
5278            AppDeathRecipient adr = new AppDeathRecipient(
5279                    app, pid, thread);
5280            thread.asBinder().linkToDeath(adr, 0);
5281            app.deathRecipient = adr;
5282        } catch (RemoteException e) {
5283            app.resetPackageList(mProcessStats);
5284            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5285            return false;
5286        }
5287
5288        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5289
5290        app.makeActive(thread, mProcessStats);
5291        app.curAdj = app.setAdj = -100;
5292        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5293        app.forcingToForeground = null;
5294        updateProcessForegroundLocked(app, false, false);
5295        app.hasShownUi = false;
5296        app.debugging = false;
5297        app.cached = false;
5298
5299        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5300
5301        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5302        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5303
5304        if (!normalMode) {
5305            Slog.i(TAG, "Launching preboot mode app: " + app);
5306        }
5307
5308        if (localLOGV) Slog.v(
5309            TAG, "New app record " + app
5310            + " thread=" + thread.asBinder() + " pid=" + pid);
5311        try {
5312            int testMode = IApplicationThread.DEBUG_OFF;
5313            if (mDebugApp != null && mDebugApp.equals(processName)) {
5314                testMode = mWaitForDebugger
5315                    ? IApplicationThread.DEBUG_WAIT
5316                    : IApplicationThread.DEBUG_ON;
5317                app.debugging = true;
5318                if (mDebugTransient) {
5319                    mDebugApp = mOrigDebugApp;
5320                    mWaitForDebugger = mOrigWaitForDebugger;
5321                }
5322            }
5323            String profileFile = app.instrumentationProfileFile;
5324            ParcelFileDescriptor profileFd = null;
5325            boolean profileAutoStop = false;
5326            if (mProfileApp != null && mProfileApp.equals(processName)) {
5327                mProfileProc = app;
5328                profileFile = mProfileFile;
5329                profileFd = mProfileFd;
5330                profileAutoStop = mAutoStopProfiler;
5331            }
5332            boolean enableOpenGlTrace = false;
5333            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5334                enableOpenGlTrace = true;
5335                mOpenGlTraceApp = null;
5336            }
5337
5338            // If the app is being launched for restore or full backup, set it up specially
5339            boolean isRestrictedBackupMode = false;
5340            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5341                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5342                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5343                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5344            }
5345
5346            ensurePackageDexOpt(app.instrumentationInfo != null
5347                    ? app.instrumentationInfo.packageName
5348                    : app.info.packageName);
5349            if (app.instrumentationClass != null) {
5350                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5351            }
5352            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5353                    + processName + " with config " + mConfiguration);
5354            ApplicationInfo appInfo = app.instrumentationInfo != null
5355                    ? app.instrumentationInfo : app.info;
5356            app.compat = compatibilityInfoForPackageLocked(appInfo);
5357            if (profileFd != null) {
5358                profileFd = profileFd.dup();
5359            }
5360            thread.bindApplication(processName, appInfo, providers,
5361                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5362                    app.instrumentationArguments, app.instrumentationWatcher,
5363                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5364                    isRestrictedBackupMode || !normalMode, app.persistent,
5365                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5366                    mCoreSettingsObserver.getCoreSettingsLocked());
5367            updateLruProcessLocked(app, false, null);
5368            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5369        } catch (Exception e) {
5370            // todo: Yikes!  What should we do?  For now we will try to
5371            // start another process, but that could easily get us in
5372            // an infinite loop of restarting processes...
5373            Slog.w(TAG, "Exception thrown during bind!", e);
5374
5375            app.resetPackageList(mProcessStats);
5376            app.unlinkDeathRecipient();
5377            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5378            return false;
5379        }
5380
5381        // Remove this record from the list of starting applications.
5382        mPersistentStartingProcesses.remove(app);
5383        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5384                "Attach application locked removing on hold: " + app);
5385        mProcessesOnHold.remove(app);
5386
5387        boolean badApp = false;
5388        boolean didSomething = false;
5389
5390        // See if the top visible activity is waiting to run in this process...
5391        if (normalMode) {
5392            try {
5393                if (mStackSupervisor.attachApplicationLocked(app)) {
5394                    didSomething = true;
5395                }
5396            } catch (Exception e) {
5397                badApp = true;
5398            }
5399        }
5400
5401        // Find any services that should be running in this process...
5402        if (!badApp) {
5403            try {
5404                didSomething |= mServices.attachApplicationLocked(app, processName);
5405            } catch (Exception e) {
5406                badApp = true;
5407            }
5408        }
5409
5410        // Check if a next-broadcast receiver is in this process...
5411        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5412            try {
5413                didSomething |= sendPendingBroadcastsLocked(app);
5414            } catch (Exception e) {
5415                // If the app died trying to launch the receiver we declare it 'bad'
5416                badApp = true;
5417            }
5418        }
5419
5420        // Check whether the next backup agent is in this process...
5421        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5422            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5423            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5424            try {
5425                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5426                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5427                        mBackupTarget.backupMode);
5428            } catch (Exception e) {
5429                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5430                e.printStackTrace();
5431            }
5432        }
5433
5434        if (badApp) {
5435            // todo: Also need to kill application to deal with all
5436            // kinds of exceptions.
5437            handleAppDiedLocked(app, false, true);
5438            return false;
5439        }
5440
5441        if (!didSomething) {
5442            updateOomAdjLocked();
5443        }
5444
5445        return true;
5446    }
5447
5448    @Override
5449    public final void attachApplication(IApplicationThread thread) {
5450        synchronized (this) {
5451            int callingPid = Binder.getCallingPid();
5452            final long origId = Binder.clearCallingIdentity();
5453            attachApplicationLocked(thread, callingPid);
5454            Binder.restoreCallingIdentity(origId);
5455        }
5456    }
5457
5458    @Override
5459    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5460        final long origId = Binder.clearCallingIdentity();
5461        synchronized (this) {
5462            ActivityStack stack = ActivityRecord.getStackLocked(token);
5463            if (stack != null) {
5464                ActivityRecord r =
5465                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5466                if (stopProfiling) {
5467                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5468                        try {
5469                            mProfileFd.close();
5470                        } catch (IOException e) {
5471                        }
5472                        clearProfilerLocked();
5473                    }
5474                }
5475            }
5476        }
5477        Binder.restoreCallingIdentity(origId);
5478    }
5479
5480    void enableScreenAfterBoot() {
5481        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5482                SystemClock.uptimeMillis());
5483        mWindowManager.enableScreenAfterBoot();
5484
5485        synchronized (this) {
5486            updateEventDispatchingLocked();
5487        }
5488    }
5489
5490    @Override
5491    public void showBootMessage(final CharSequence msg, final boolean always) {
5492        enforceNotIsolatedCaller("showBootMessage");
5493        mWindowManager.showBootMessage(msg, always);
5494    }
5495
5496    @Override
5497    public void dismissKeyguardOnNextActivity() {
5498        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5499        final long token = Binder.clearCallingIdentity();
5500        try {
5501            synchronized (this) {
5502                if (DEBUG_LOCKSCREEN) logLockScreen("");
5503                if (mLockScreenShown) {
5504                    mLockScreenShown = false;
5505                    comeOutOfSleepIfNeededLocked();
5506                }
5507                mStackSupervisor.setDismissKeyguard(true);
5508            }
5509        } finally {
5510            Binder.restoreCallingIdentity(token);
5511        }
5512    }
5513
5514    final void finishBooting() {
5515        // Register receivers to handle package update events
5516        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5517
5518        synchronized (this) {
5519            // Ensure that any processes we had put on hold are now started
5520            // up.
5521            final int NP = mProcessesOnHold.size();
5522            if (NP > 0) {
5523                ArrayList<ProcessRecord> procs =
5524                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5525                for (int ip=0; ip<NP; ip++) {
5526                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5527                            + procs.get(ip));
5528                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5529                }
5530            }
5531
5532            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5533                // Start looking for apps that are abusing wake locks.
5534                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5535                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5536                // Tell anyone interested that we are done booting!
5537                SystemProperties.set("sys.boot_completed", "1");
5538                SystemProperties.set("dev.bootcomplete", "1");
5539                for (int i=0; i<mStartedUsers.size(); i++) {
5540                    UserStartedState uss = mStartedUsers.valueAt(i);
5541                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5542                        uss.mState = UserStartedState.STATE_RUNNING;
5543                        final int userId = mStartedUsers.keyAt(i);
5544                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5545                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5546                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5547                        broadcastIntentLocked(null, null, intent, null,
5548                                new IIntentReceiver.Stub() {
5549                                    @Override
5550                                    public void performReceive(Intent intent, int resultCode,
5551                                            String data, Bundle extras, boolean ordered,
5552                                            boolean sticky, int sendingUser) {
5553                                        synchronized (ActivityManagerService.this) {
5554                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5555                                                    true, false);
5556                                        }
5557                                    }
5558                                },
5559                                0, null, null,
5560                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5561                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5562                                userId);
5563                    }
5564                }
5565                scheduleStartProfilesLocked();
5566            }
5567        }
5568    }
5569
5570    final void ensureBootCompleted() {
5571        boolean booting;
5572        boolean enableScreen;
5573        synchronized (this) {
5574            booting = mBooting;
5575            mBooting = false;
5576            enableScreen = !mBooted;
5577            mBooted = true;
5578        }
5579
5580        if (booting) {
5581            finishBooting();
5582        }
5583
5584        if (enableScreen) {
5585            enableScreenAfterBoot();
5586        }
5587    }
5588
5589    @Override
5590    public final void activityResumed(IBinder token) {
5591        final long origId = Binder.clearCallingIdentity();
5592        synchronized(this) {
5593            ActivityStack stack = ActivityRecord.getStackLocked(token);
5594            if (stack != null) {
5595                ActivityRecord.activityResumedLocked(token);
5596            }
5597        }
5598        Binder.restoreCallingIdentity(origId);
5599    }
5600
5601    @Override
5602    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5603        final long origId = Binder.clearCallingIdentity();
5604        synchronized(this) {
5605            ActivityStack stack = ActivityRecord.getStackLocked(token);
5606            if (stack != null) {
5607                stack.activityPausedLocked(token, false, persistentState);
5608            }
5609        }
5610        Binder.restoreCallingIdentity(origId);
5611    }
5612
5613    @Override
5614    public final void activityStopped(IBinder token, Bundle icicle,
5615            PersistableBundle persistentState, CharSequence description) {
5616        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5617
5618        // Refuse possible leaked file descriptors
5619        if (icicle != null && icicle.hasFileDescriptors()) {
5620            throw new IllegalArgumentException("File descriptors passed in Bundle");
5621        }
5622
5623        final long origId = Binder.clearCallingIdentity();
5624
5625        synchronized (this) {
5626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5627            if (r != null) {
5628                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5629            }
5630        }
5631
5632        trimApplications();
5633
5634        Binder.restoreCallingIdentity(origId);
5635    }
5636
5637    @Override
5638    public final void activityDestroyed(IBinder token) {
5639        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5640        synchronized (this) {
5641            ActivityStack stack = ActivityRecord.getStackLocked(token);
5642            if (stack != null) {
5643                stack.activityDestroyedLocked(token);
5644            }
5645        }
5646    }
5647
5648    @Override
5649    public final void mediaResourcesReleased(IBinder token) {
5650        final long origId = Binder.clearCallingIdentity();
5651        try {
5652            synchronized (this) {
5653                ActivityStack stack = ActivityRecord.getStackLocked(token);
5654                if (stack != null) {
5655                    stack.mediaResourcesReleased(token);
5656                }
5657            }
5658        } finally {
5659            Binder.restoreCallingIdentity(origId);
5660        }
5661    }
5662
5663    @Override
5664    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5665        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5666    }
5667
5668    @Override
5669    public String getCallingPackage(IBinder token) {
5670        synchronized (this) {
5671            ActivityRecord r = getCallingRecordLocked(token);
5672            return r != null ? r.info.packageName : null;
5673        }
5674    }
5675
5676    @Override
5677    public ComponentName getCallingActivity(IBinder token) {
5678        synchronized (this) {
5679            ActivityRecord r = getCallingRecordLocked(token);
5680            return r != null ? r.intent.getComponent() : null;
5681        }
5682    }
5683
5684    private ActivityRecord getCallingRecordLocked(IBinder token) {
5685        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5686        if (r == null) {
5687            return null;
5688        }
5689        return r.resultTo;
5690    }
5691
5692    @Override
5693    public ComponentName getActivityClassForToken(IBinder token) {
5694        synchronized(this) {
5695            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5696            if (r == null) {
5697                return null;
5698            }
5699            return r.intent.getComponent();
5700        }
5701    }
5702
5703    @Override
5704    public String getPackageForToken(IBinder token) {
5705        synchronized(this) {
5706            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5707            if (r == null) {
5708                return null;
5709            }
5710            return r.packageName;
5711        }
5712    }
5713
5714    @Override
5715    public IIntentSender getIntentSender(int type,
5716            String packageName, IBinder token, String resultWho,
5717            int requestCode, Intent[] intents, String[] resolvedTypes,
5718            int flags, Bundle options, int userId) {
5719        enforceNotIsolatedCaller("getIntentSender");
5720        // Refuse possible leaked file descriptors
5721        if (intents != null) {
5722            if (intents.length < 1) {
5723                throw new IllegalArgumentException("Intents array length must be >= 1");
5724            }
5725            for (int i=0; i<intents.length; i++) {
5726                Intent intent = intents[i];
5727                if (intent != null) {
5728                    if (intent.hasFileDescriptors()) {
5729                        throw new IllegalArgumentException("File descriptors passed in Intent");
5730                    }
5731                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5732                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5733                        throw new IllegalArgumentException(
5734                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5735                    }
5736                    intents[i] = new Intent(intent);
5737                }
5738            }
5739            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5740                throw new IllegalArgumentException(
5741                        "Intent array length does not match resolvedTypes length");
5742            }
5743        }
5744        if (options != null) {
5745            if (options.hasFileDescriptors()) {
5746                throw new IllegalArgumentException("File descriptors passed in options");
5747            }
5748        }
5749
5750        synchronized(this) {
5751            int callingUid = Binder.getCallingUid();
5752            int origUserId = userId;
5753            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5754                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5755                    ALLOW_NON_FULL, "getIntentSender", null);
5756            if (origUserId == UserHandle.USER_CURRENT) {
5757                // We don't want to evaluate this until the pending intent is
5758                // actually executed.  However, we do want to always do the
5759                // security checking for it above.
5760                userId = UserHandle.USER_CURRENT;
5761            }
5762            try {
5763                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5764                    int uid = AppGlobals.getPackageManager()
5765                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5766                    if (!UserHandle.isSameApp(callingUid, uid)) {
5767                        String msg = "Permission Denial: getIntentSender() from pid="
5768                            + Binder.getCallingPid()
5769                            + ", uid=" + Binder.getCallingUid()
5770                            + ", (need uid=" + uid + ")"
5771                            + " is not allowed to send as package " + packageName;
5772                        Slog.w(TAG, msg);
5773                        throw new SecurityException(msg);
5774                    }
5775                }
5776
5777                return getIntentSenderLocked(type, packageName, callingUid, userId,
5778                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5779
5780            } catch (RemoteException e) {
5781                throw new SecurityException(e);
5782            }
5783        }
5784    }
5785
5786    IIntentSender getIntentSenderLocked(int type, String packageName,
5787            int callingUid, int userId, IBinder token, String resultWho,
5788            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5789            Bundle options) {
5790        if (DEBUG_MU)
5791            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5792        ActivityRecord activity = null;
5793        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5794            activity = ActivityRecord.isInStackLocked(token);
5795            if (activity == null) {
5796                return null;
5797            }
5798            if (activity.finishing) {
5799                return null;
5800            }
5801        }
5802
5803        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5804        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5805        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5806        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5807                |PendingIntent.FLAG_UPDATE_CURRENT);
5808
5809        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5810                type, packageName, activity, resultWho,
5811                requestCode, intents, resolvedTypes, flags, options, userId);
5812        WeakReference<PendingIntentRecord> ref;
5813        ref = mIntentSenderRecords.get(key);
5814        PendingIntentRecord rec = ref != null ? ref.get() : null;
5815        if (rec != null) {
5816            if (!cancelCurrent) {
5817                if (updateCurrent) {
5818                    if (rec.key.requestIntent != null) {
5819                        rec.key.requestIntent.replaceExtras(intents != null ?
5820                                intents[intents.length - 1] : null);
5821                    }
5822                    if (intents != null) {
5823                        intents[intents.length-1] = rec.key.requestIntent;
5824                        rec.key.allIntents = intents;
5825                        rec.key.allResolvedTypes = resolvedTypes;
5826                    } else {
5827                        rec.key.allIntents = null;
5828                        rec.key.allResolvedTypes = null;
5829                    }
5830                }
5831                return rec;
5832            }
5833            rec.canceled = true;
5834            mIntentSenderRecords.remove(key);
5835        }
5836        if (noCreate) {
5837            return rec;
5838        }
5839        rec = new PendingIntentRecord(this, key, callingUid);
5840        mIntentSenderRecords.put(key, rec.ref);
5841        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5842            if (activity.pendingResults == null) {
5843                activity.pendingResults
5844                        = new HashSet<WeakReference<PendingIntentRecord>>();
5845            }
5846            activity.pendingResults.add(rec.ref);
5847        }
5848        return rec;
5849    }
5850
5851    @Override
5852    public void cancelIntentSender(IIntentSender sender) {
5853        if (!(sender instanceof PendingIntentRecord)) {
5854            return;
5855        }
5856        synchronized(this) {
5857            PendingIntentRecord rec = (PendingIntentRecord)sender;
5858            try {
5859                int uid = AppGlobals.getPackageManager()
5860                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5861                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5862                    String msg = "Permission Denial: cancelIntentSender() from pid="
5863                        + Binder.getCallingPid()
5864                        + ", uid=" + Binder.getCallingUid()
5865                        + " is not allowed to cancel packges "
5866                        + rec.key.packageName;
5867                    Slog.w(TAG, msg);
5868                    throw new SecurityException(msg);
5869                }
5870            } catch (RemoteException e) {
5871                throw new SecurityException(e);
5872            }
5873            cancelIntentSenderLocked(rec, true);
5874        }
5875    }
5876
5877    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5878        rec.canceled = true;
5879        mIntentSenderRecords.remove(rec.key);
5880        if (cleanActivity && rec.key.activity != null) {
5881            rec.key.activity.pendingResults.remove(rec.ref);
5882        }
5883    }
5884
5885    @Override
5886    public String getPackageForIntentSender(IIntentSender pendingResult) {
5887        if (!(pendingResult instanceof PendingIntentRecord)) {
5888            return null;
5889        }
5890        try {
5891            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5892            return res.key.packageName;
5893        } catch (ClassCastException e) {
5894        }
5895        return null;
5896    }
5897
5898    @Override
5899    public int getUidForIntentSender(IIntentSender sender) {
5900        if (sender instanceof PendingIntentRecord) {
5901            try {
5902                PendingIntentRecord res = (PendingIntentRecord)sender;
5903                return res.uid;
5904            } catch (ClassCastException e) {
5905            }
5906        }
5907        return -1;
5908    }
5909
5910    @Override
5911    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5912        if (!(pendingResult instanceof PendingIntentRecord)) {
5913            return false;
5914        }
5915        try {
5916            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5917            if (res.key.allIntents == null) {
5918                return false;
5919            }
5920            for (int i=0; i<res.key.allIntents.length; i++) {
5921                Intent intent = res.key.allIntents[i];
5922                if (intent.getPackage() != null && intent.getComponent() != null) {
5923                    return false;
5924                }
5925            }
5926            return true;
5927        } catch (ClassCastException e) {
5928        }
5929        return false;
5930    }
5931
5932    @Override
5933    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5934        if (!(pendingResult instanceof PendingIntentRecord)) {
5935            return false;
5936        }
5937        try {
5938            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5939            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5940                return true;
5941            }
5942            return false;
5943        } catch (ClassCastException e) {
5944        }
5945        return false;
5946    }
5947
5948    @Override
5949    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5950        if (!(pendingResult instanceof PendingIntentRecord)) {
5951            return null;
5952        }
5953        try {
5954            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5955            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5956        } catch (ClassCastException e) {
5957        }
5958        return null;
5959    }
5960
5961    @Override
5962    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5963        if (!(pendingResult instanceof PendingIntentRecord)) {
5964            return null;
5965        }
5966        try {
5967            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5968            Intent intent = res.key.requestIntent;
5969            if (intent != null) {
5970                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5971                        || res.lastTagPrefix.equals(prefix))) {
5972                    return res.lastTag;
5973                }
5974                res.lastTagPrefix = prefix;
5975                StringBuilder sb = new StringBuilder(128);
5976                if (prefix != null) {
5977                    sb.append(prefix);
5978                }
5979                if (intent.getAction() != null) {
5980                    sb.append(intent.getAction());
5981                } else if (intent.getComponent() != null) {
5982                    intent.getComponent().appendShortString(sb);
5983                } else {
5984                    sb.append("?");
5985                }
5986                return res.lastTag = sb.toString();
5987            }
5988        } catch (ClassCastException e) {
5989        }
5990        return null;
5991    }
5992
5993    @Override
5994    public void setProcessLimit(int max) {
5995        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5996                "setProcessLimit()");
5997        synchronized (this) {
5998            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5999            mProcessLimitOverride = max;
6000        }
6001        trimApplications();
6002    }
6003
6004    @Override
6005    public int getProcessLimit() {
6006        synchronized (this) {
6007            return mProcessLimitOverride;
6008        }
6009    }
6010
6011    void foregroundTokenDied(ForegroundToken token) {
6012        synchronized (ActivityManagerService.this) {
6013            synchronized (mPidsSelfLocked) {
6014                ForegroundToken cur
6015                    = mForegroundProcesses.get(token.pid);
6016                if (cur != token) {
6017                    return;
6018                }
6019                mForegroundProcesses.remove(token.pid);
6020                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6021                if (pr == null) {
6022                    return;
6023                }
6024                pr.forcingToForeground = null;
6025                updateProcessForegroundLocked(pr, false, false);
6026            }
6027            updateOomAdjLocked();
6028        }
6029    }
6030
6031    @Override
6032    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6033        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6034                "setProcessForeground()");
6035        synchronized(this) {
6036            boolean changed = false;
6037
6038            synchronized (mPidsSelfLocked) {
6039                ProcessRecord pr = mPidsSelfLocked.get(pid);
6040                if (pr == null && isForeground) {
6041                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6042                    return;
6043                }
6044                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6045                if (oldToken != null) {
6046                    oldToken.token.unlinkToDeath(oldToken, 0);
6047                    mForegroundProcesses.remove(pid);
6048                    if (pr != null) {
6049                        pr.forcingToForeground = null;
6050                    }
6051                    changed = true;
6052                }
6053                if (isForeground && token != null) {
6054                    ForegroundToken newToken = new ForegroundToken() {
6055                        @Override
6056                        public void binderDied() {
6057                            foregroundTokenDied(this);
6058                        }
6059                    };
6060                    newToken.pid = pid;
6061                    newToken.token = token;
6062                    try {
6063                        token.linkToDeath(newToken, 0);
6064                        mForegroundProcesses.put(pid, newToken);
6065                        pr.forcingToForeground = token;
6066                        changed = true;
6067                    } catch (RemoteException e) {
6068                        // If the process died while doing this, we will later
6069                        // do the cleanup with the process death link.
6070                    }
6071                }
6072            }
6073
6074            if (changed) {
6075                updateOomAdjLocked();
6076            }
6077        }
6078    }
6079
6080    // =========================================================
6081    // PERMISSIONS
6082    // =========================================================
6083
6084    static class PermissionController extends IPermissionController.Stub {
6085        ActivityManagerService mActivityManagerService;
6086        PermissionController(ActivityManagerService activityManagerService) {
6087            mActivityManagerService = activityManagerService;
6088        }
6089
6090        @Override
6091        public boolean checkPermission(String permission, int pid, int uid) {
6092            return mActivityManagerService.checkPermission(permission, pid,
6093                    uid) == PackageManager.PERMISSION_GRANTED;
6094        }
6095    }
6096
6097    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6098        @Override
6099        public int checkComponentPermission(String permission, int pid, int uid,
6100                int owningUid, boolean exported) {
6101            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6102                    owningUid, exported);
6103        }
6104
6105        @Override
6106        public Object getAMSLock() {
6107            return ActivityManagerService.this;
6108        }
6109    }
6110
6111    /**
6112     * This can be called with or without the global lock held.
6113     */
6114    int checkComponentPermission(String permission, int pid, int uid,
6115            int owningUid, boolean exported) {
6116        // We might be performing an operation on behalf of an indirect binder
6117        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6118        // client identity accordingly before proceeding.
6119        Identity tlsIdentity = sCallerIdentity.get();
6120        if (tlsIdentity != null) {
6121            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6122                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6123            uid = tlsIdentity.uid;
6124            pid = tlsIdentity.pid;
6125        }
6126
6127        if (pid == MY_PID) {
6128            return PackageManager.PERMISSION_GRANTED;
6129        }
6130
6131        return ActivityManager.checkComponentPermission(permission, uid,
6132                owningUid, exported);
6133    }
6134
6135    /**
6136     * As the only public entry point for permissions checking, this method
6137     * can enforce the semantic that requesting a check on a null global
6138     * permission is automatically denied.  (Internally a null permission
6139     * string is used when calling {@link #checkComponentPermission} in cases
6140     * when only uid-based security is needed.)
6141     *
6142     * This can be called with or without the global lock held.
6143     */
6144    @Override
6145    public int checkPermission(String permission, int pid, int uid) {
6146        if (permission == null) {
6147            return PackageManager.PERMISSION_DENIED;
6148        }
6149        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6150    }
6151
6152    /**
6153     * Binder IPC calls go through the public entry point.
6154     * This can be called with or without the global lock held.
6155     */
6156    int checkCallingPermission(String permission) {
6157        return checkPermission(permission,
6158                Binder.getCallingPid(),
6159                UserHandle.getAppId(Binder.getCallingUid()));
6160    }
6161
6162    /**
6163     * This can be called with or without the global lock held.
6164     */
6165    void enforceCallingPermission(String permission, String func) {
6166        if (checkCallingPermission(permission)
6167                == PackageManager.PERMISSION_GRANTED) {
6168            return;
6169        }
6170
6171        String msg = "Permission Denial: " + func + " from pid="
6172                + Binder.getCallingPid()
6173                + ", uid=" + Binder.getCallingUid()
6174                + " requires " + permission;
6175        Slog.w(TAG, msg);
6176        throw new SecurityException(msg);
6177    }
6178
6179    /**
6180     * Determine if UID is holding permissions required to access {@link Uri} in
6181     * the given {@link ProviderInfo}. Final permission checking is always done
6182     * in {@link ContentProvider}.
6183     */
6184    private final boolean checkHoldingPermissionsLocked(
6185            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6186        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6187                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6188        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6189            return false;
6190        }
6191        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6192    }
6193
6194    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6195            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6196        if (pi.applicationInfo.uid == uid) {
6197            return true;
6198        } else if (!pi.exported) {
6199            return false;
6200        }
6201
6202        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6203        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6204        try {
6205            // check if target holds top-level <provider> permissions
6206            if (!readMet && pi.readPermission != null && considerUidPermissions
6207                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6208                readMet = true;
6209            }
6210            if (!writeMet && pi.writePermission != null && considerUidPermissions
6211                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6212                writeMet = true;
6213            }
6214
6215            // track if unprotected read/write is allowed; any denied
6216            // <path-permission> below removes this ability
6217            boolean allowDefaultRead = pi.readPermission == null;
6218            boolean allowDefaultWrite = pi.writePermission == null;
6219
6220            // check if target holds any <path-permission> that match uri
6221            final PathPermission[] pps = pi.pathPermissions;
6222            if (pps != null) {
6223                final String path = grantUri.uri.getPath();
6224                int i = pps.length;
6225                while (i > 0 && (!readMet || !writeMet)) {
6226                    i--;
6227                    PathPermission pp = pps[i];
6228                    if (pp.match(path)) {
6229                        if (!readMet) {
6230                            final String pprperm = pp.getReadPermission();
6231                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6232                                    + pprperm + " for " + pp.getPath()
6233                                    + ": match=" + pp.match(path)
6234                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6235                            if (pprperm != null) {
6236                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6237                                        == PERMISSION_GRANTED) {
6238                                    readMet = true;
6239                                } else {
6240                                    allowDefaultRead = false;
6241                                }
6242                            }
6243                        }
6244                        if (!writeMet) {
6245                            final String ppwperm = pp.getWritePermission();
6246                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6247                                    + ppwperm + " for " + pp.getPath()
6248                                    + ": match=" + pp.match(path)
6249                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6250                            if (ppwperm != null) {
6251                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6252                                        == PERMISSION_GRANTED) {
6253                                    writeMet = true;
6254                                } else {
6255                                    allowDefaultWrite = false;
6256                                }
6257                            }
6258                        }
6259                    }
6260                }
6261            }
6262
6263            // grant unprotected <provider> read/write, if not blocked by
6264            // <path-permission> above
6265            if (allowDefaultRead) readMet = true;
6266            if (allowDefaultWrite) writeMet = true;
6267
6268        } catch (RemoteException e) {
6269            return false;
6270        }
6271
6272        return readMet && writeMet;
6273    }
6274
6275    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6276        ProviderInfo pi = null;
6277        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6278        if (cpr != null) {
6279            pi = cpr.info;
6280        } else {
6281            try {
6282                pi = AppGlobals.getPackageManager().resolveContentProvider(
6283                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6284            } catch (RemoteException ex) {
6285            }
6286        }
6287        return pi;
6288    }
6289
6290    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6291        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6292        if (targetUris != null) {
6293            return targetUris.get(grantUri);
6294        }
6295        return null;
6296    }
6297
6298    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6299            String targetPkg, int targetUid, GrantUri grantUri) {
6300        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6301        if (targetUris == null) {
6302            targetUris = Maps.newArrayMap();
6303            mGrantedUriPermissions.put(targetUid, targetUris);
6304        }
6305
6306        UriPermission perm = targetUris.get(grantUri);
6307        if (perm == null) {
6308            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6309            targetUris.put(grantUri, perm);
6310        }
6311
6312        return perm;
6313    }
6314
6315    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6316            final int modeFlags) {
6317        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6318        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6319                : UriPermission.STRENGTH_OWNED;
6320
6321        // Root gets to do everything.
6322        if (uid == 0) {
6323            return true;
6324        }
6325
6326        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6327        if (perms == null) return false;
6328
6329        // First look for exact match
6330        final UriPermission exactPerm = perms.get(grantUri);
6331        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6332            return true;
6333        }
6334
6335        // No exact match, look for prefixes
6336        final int N = perms.size();
6337        for (int i = 0; i < N; i++) {
6338            final UriPermission perm = perms.valueAt(i);
6339            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6340                    && perm.getStrength(modeFlags) >= minStrength) {
6341                return true;
6342            }
6343        }
6344
6345        return false;
6346    }
6347
6348    @Override
6349    public int checkUriPermission(Uri uri, int pid, int uid,
6350            final int modeFlags, int userId) {
6351        enforceNotIsolatedCaller("checkUriPermission");
6352
6353        // Another redirected-binder-call permissions check as in
6354        // {@link checkComponentPermission}.
6355        Identity tlsIdentity = sCallerIdentity.get();
6356        if (tlsIdentity != null) {
6357            uid = tlsIdentity.uid;
6358            pid = tlsIdentity.pid;
6359        }
6360
6361        // Our own process gets to do everything.
6362        if (pid == MY_PID) {
6363            return PackageManager.PERMISSION_GRANTED;
6364        }
6365        synchronized (this) {
6366            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6367                    ? PackageManager.PERMISSION_GRANTED
6368                    : PackageManager.PERMISSION_DENIED;
6369        }
6370    }
6371
6372    /**
6373     * Check if the targetPkg can be granted permission to access uri by
6374     * the callingUid using the given modeFlags.  Throws a security exception
6375     * if callingUid is not allowed to do this.  Returns the uid of the target
6376     * if the URI permission grant should be performed; returns -1 if it is not
6377     * needed (for example targetPkg already has permission to access the URI).
6378     * If you already know the uid of the target, you can supply it in
6379     * lastTargetUid else set that to -1.
6380     */
6381    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6382            final int modeFlags, int lastTargetUid) {
6383        if (!Intent.isAccessUriMode(modeFlags)) {
6384            return -1;
6385        }
6386
6387        if (targetPkg != null) {
6388            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6389                    "Checking grant " + targetPkg + " permission to " + grantUri);
6390        }
6391
6392        final IPackageManager pm = AppGlobals.getPackageManager();
6393
6394        // If this is not a content: uri, we can't do anything with it.
6395        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6396            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6397                    "Can't grant URI permission for non-content URI: " + grantUri);
6398            return -1;
6399        }
6400
6401        final String authority = grantUri.uri.getAuthority();
6402        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6403        if (pi == null) {
6404            Slog.w(TAG, "No content provider found for permission check: " +
6405                    grantUri.uri.toSafeString());
6406            return -1;
6407        }
6408
6409        int targetUid = lastTargetUid;
6410        if (targetUid < 0 && targetPkg != null) {
6411            try {
6412                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6413                if (targetUid < 0) {
6414                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6415                            "Can't grant URI permission no uid for: " + targetPkg);
6416                    return -1;
6417                }
6418            } catch (RemoteException ex) {
6419                return -1;
6420            }
6421        }
6422
6423        if (targetUid >= 0) {
6424            // First...  does the target actually need this permission?
6425            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6426                // No need to grant the target this permission.
6427                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6428                        "Target " + targetPkg + " already has full permission to " + grantUri);
6429                return -1;
6430            }
6431        } else {
6432            // First...  there is no target package, so can anyone access it?
6433            boolean allowed = pi.exported;
6434            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6435                if (pi.readPermission != null) {
6436                    allowed = false;
6437                }
6438            }
6439            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6440                if (pi.writePermission != null) {
6441                    allowed = false;
6442                }
6443            }
6444            if (allowed) {
6445                return -1;
6446            }
6447        }
6448
6449        /* There is a special cross user grant if:
6450         * - The target is on another user.
6451         * - Apps on the current user can access the uri without any uid permissions.
6452         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6453         * grant uri permissions.
6454         */
6455        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6456                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6457                modeFlags, false /*without considering the uid permissions*/);
6458
6459        // Second...  is the provider allowing granting of URI permissions?
6460        if (!specialCrossUserGrant) {
6461            if (!pi.grantUriPermissions) {
6462                throw new SecurityException("Provider " + pi.packageName
6463                        + "/" + pi.name
6464                        + " does not allow granting of Uri permissions (uri "
6465                        + grantUri + ")");
6466            }
6467            if (pi.uriPermissionPatterns != null) {
6468                final int N = pi.uriPermissionPatterns.length;
6469                boolean allowed = false;
6470                for (int i=0; i<N; i++) {
6471                    if (pi.uriPermissionPatterns[i] != null
6472                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6473                        allowed = true;
6474                        break;
6475                    }
6476                }
6477                if (!allowed) {
6478                    throw new SecurityException("Provider " + pi.packageName
6479                            + "/" + pi.name
6480                            + " does not allow granting of permission to path of Uri "
6481                            + grantUri);
6482                }
6483            }
6484        }
6485
6486        // Third...  does the caller itself have permission to access
6487        // this uri?
6488        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6489            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6490                // Require they hold a strong enough Uri permission
6491                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6492                    throw new SecurityException("Uid " + callingUid
6493                            + " does not have permission to uri " + grantUri);
6494                }
6495            }
6496        }
6497        return targetUid;
6498    }
6499
6500    @Override
6501    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6502            final int modeFlags, int userId) {
6503        enforceNotIsolatedCaller("checkGrantUriPermission");
6504        synchronized(this) {
6505            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6506                    new GrantUri(userId, uri, false), modeFlags, -1);
6507        }
6508    }
6509
6510    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6511            final int modeFlags, UriPermissionOwner owner) {
6512        if (!Intent.isAccessUriMode(modeFlags)) {
6513            return;
6514        }
6515
6516        // So here we are: the caller has the assumed permission
6517        // to the uri, and the target doesn't.  Let's now give this to
6518        // the target.
6519
6520        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6521                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6522
6523        final String authority = grantUri.uri.getAuthority();
6524        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6525        if (pi == null) {
6526            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6527            return;
6528        }
6529
6530        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6531            grantUri.prefix = true;
6532        }
6533        final UriPermission perm = findOrCreateUriPermissionLocked(
6534                pi.packageName, targetPkg, targetUid, grantUri);
6535        perm.grantModes(modeFlags, owner);
6536    }
6537
6538    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6539            final int modeFlags, UriPermissionOwner owner) {
6540        if (targetPkg == null) {
6541            throw new NullPointerException("targetPkg");
6542        }
6543
6544        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6545                -1);
6546        if (targetUid < 0) {
6547            return;
6548        }
6549
6550        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6551                owner);
6552    }
6553
6554    static class NeededUriGrants extends ArrayList<GrantUri> {
6555        final String targetPkg;
6556        final int targetUid;
6557        final int flags;
6558
6559        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6560            this.targetPkg = targetPkg;
6561            this.targetUid = targetUid;
6562            this.flags = flags;
6563        }
6564    }
6565
6566    /**
6567     * Like checkGrantUriPermissionLocked, but takes an Intent.
6568     */
6569    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6570            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6571        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6572                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6573                + " clip=" + (intent != null ? intent.getClipData() : null)
6574                + " from " + intent + "; flags=0x"
6575                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6576
6577        if (targetPkg == null) {
6578            throw new NullPointerException("targetPkg");
6579        }
6580
6581        if (intent == null) {
6582            return null;
6583        }
6584        Uri data = intent.getData();
6585        ClipData clip = intent.getClipData();
6586        if (data == null && clip == null) {
6587            return null;
6588        }
6589        final IPackageManager pm = AppGlobals.getPackageManager();
6590        int targetUid;
6591        if (needed != null) {
6592            targetUid = needed.targetUid;
6593        } else {
6594            try {
6595                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6596            } catch (RemoteException ex) {
6597                return null;
6598            }
6599            if (targetUid < 0) {
6600                if (DEBUG_URI_PERMISSION) {
6601                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6602                            + " on user " + targetUserId);
6603                }
6604                return null;
6605            }
6606        }
6607        if (data != null) {
6608            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6609            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6610                    targetUid);
6611            if (targetUid > 0) {
6612                if (needed == null) {
6613                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6614                }
6615                needed.add(grantUri);
6616            }
6617        }
6618        if (clip != null) {
6619            for (int i=0; i<clip.getItemCount(); i++) {
6620                Uri uri = clip.getItemAt(i).getUri();
6621                if (uri != null) {
6622                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6623                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6624                            targetUid);
6625                    if (targetUid > 0) {
6626                        if (needed == null) {
6627                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6628                        }
6629                        needed.add(grantUri);
6630                    }
6631                } else {
6632                    Intent clipIntent = clip.getItemAt(i).getIntent();
6633                    if (clipIntent != null) {
6634                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6635                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6636                        if (newNeeded != null) {
6637                            needed = newNeeded;
6638                        }
6639                    }
6640                }
6641            }
6642        }
6643
6644        return needed;
6645    }
6646
6647    /**
6648     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6649     */
6650    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6651            UriPermissionOwner owner) {
6652        if (needed != null) {
6653            for (int i=0; i<needed.size(); i++) {
6654                GrantUri grantUri = needed.get(i);
6655                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6656                        grantUri, needed.flags, owner);
6657            }
6658        }
6659    }
6660
6661    void grantUriPermissionFromIntentLocked(int callingUid,
6662            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6663        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6664                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6665        if (needed == null) {
6666            return;
6667        }
6668
6669        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6670    }
6671
6672    @Override
6673    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6674            final int modeFlags, int userId) {
6675        enforceNotIsolatedCaller("grantUriPermission");
6676        GrantUri grantUri = new GrantUri(userId, uri, false);
6677        synchronized(this) {
6678            final ProcessRecord r = getRecordForAppLocked(caller);
6679            if (r == null) {
6680                throw new SecurityException("Unable to find app for caller "
6681                        + caller
6682                        + " when granting permission to uri " + grantUri);
6683            }
6684            if (targetPkg == null) {
6685                throw new IllegalArgumentException("null target");
6686            }
6687            if (grantUri == null) {
6688                throw new IllegalArgumentException("null uri");
6689            }
6690
6691            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6692                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6693                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6694                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6695
6696            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6697        }
6698    }
6699
6700    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6701        if (perm.modeFlags == 0) {
6702            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6703                    perm.targetUid);
6704            if (perms != null) {
6705                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6706                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6707
6708                perms.remove(perm.uri);
6709                if (perms.isEmpty()) {
6710                    mGrantedUriPermissions.remove(perm.targetUid);
6711                }
6712            }
6713        }
6714    }
6715
6716    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6717        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6718
6719        final IPackageManager pm = AppGlobals.getPackageManager();
6720        final String authority = grantUri.uri.getAuthority();
6721        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6722        if (pi == null) {
6723            Slog.w(TAG, "No content provider found for permission revoke: "
6724                    + grantUri.toSafeString());
6725            return;
6726        }
6727
6728        // Does the caller have this permission on the URI?
6729        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6730            // Right now, if you are not the original owner of the permission,
6731            // you are not allowed to revoke it.
6732            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6733                throw new SecurityException("Uid " + callingUid
6734                        + " does not have permission to uri " + grantUri);
6735            //}
6736        }
6737
6738        boolean persistChanged = false;
6739
6740        // Go through all of the permissions and remove any that match.
6741        int N = mGrantedUriPermissions.size();
6742        for (int i = 0; i < N; i++) {
6743            final int targetUid = mGrantedUriPermissions.keyAt(i);
6744            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6745
6746            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6747                final UriPermission perm = it.next();
6748                if (perm.uri.sourceUserId == grantUri.sourceUserId
6749                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6750                    if (DEBUG_URI_PERMISSION)
6751                        Slog.v(TAG,
6752                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6753                    persistChanged |= perm.revokeModes(
6754                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6755                    if (perm.modeFlags == 0) {
6756                        it.remove();
6757                    }
6758                }
6759            }
6760
6761            if (perms.isEmpty()) {
6762                mGrantedUriPermissions.remove(targetUid);
6763                N--;
6764                i--;
6765            }
6766        }
6767
6768        if (persistChanged) {
6769            schedulePersistUriGrants();
6770        }
6771    }
6772
6773    @Override
6774    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6775            int userId) {
6776        enforceNotIsolatedCaller("revokeUriPermission");
6777        synchronized(this) {
6778            final ProcessRecord r = getRecordForAppLocked(caller);
6779            if (r == null) {
6780                throw new SecurityException("Unable to find app for caller "
6781                        + caller
6782                        + " when revoking permission to uri " + uri);
6783            }
6784            if (uri == null) {
6785                Slog.w(TAG, "revokeUriPermission: null uri");
6786                return;
6787            }
6788
6789            if (!Intent.isAccessUriMode(modeFlags)) {
6790                return;
6791            }
6792
6793            final IPackageManager pm = AppGlobals.getPackageManager();
6794            final String authority = uri.getAuthority();
6795            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6796            if (pi == null) {
6797                Slog.w(TAG, "No content provider found for permission revoke: "
6798                        + uri.toSafeString());
6799                return;
6800            }
6801
6802            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6803        }
6804    }
6805
6806    /**
6807     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6808     * given package.
6809     *
6810     * @param packageName Package name to match, or {@code null} to apply to all
6811     *            packages.
6812     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6813     *            to all users.
6814     * @param persistable If persistable grants should be removed.
6815     */
6816    private void removeUriPermissionsForPackageLocked(
6817            String packageName, int userHandle, boolean persistable) {
6818        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6819            throw new IllegalArgumentException("Must narrow by either package or user");
6820        }
6821
6822        boolean persistChanged = false;
6823
6824        int N = mGrantedUriPermissions.size();
6825        for (int i = 0; i < N; i++) {
6826            final int targetUid = mGrantedUriPermissions.keyAt(i);
6827            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6828
6829            // Only inspect grants matching user
6830            if (userHandle == UserHandle.USER_ALL
6831                    || userHandle == UserHandle.getUserId(targetUid)) {
6832                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6833                    final UriPermission perm = it.next();
6834
6835                    // Only inspect grants matching package
6836                    if (packageName == null || perm.sourcePkg.equals(packageName)
6837                            || perm.targetPkg.equals(packageName)) {
6838                        persistChanged |= perm.revokeModes(
6839                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6840
6841                        // Only remove when no modes remain; any persisted grants
6842                        // will keep this alive.
6843                        if (perm.modeFlags == 0) {
6844                            it.remove();
6845                        }
6846                    }
6847                }
6848
6849                if (perms.isEmpty()) {
6850                    mGrantedUriPermissions.remove(targetUid);
6851                    N--;
6852                    i--;
6853                }
6854            }
6855        }
6856
6857        if (persistChanged) {
6858            schedulePersistUriGrants();
6859        }
6860    }
6861
6862    @Override
6863    public IBinder newUriPermissionOwner(String name) {
6864        enforceNotIsolatedCaller("newUriPermissionOwner");
6865        synchronized(this) {
6866            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6867            return owner.getExternalTokenLocked();
6868        }
6869    }
6870
6871    @Override
6872    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6873            final int modeFlags, int userId) {
6874        synchronized(this) {
6875            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6876            if (owner == null) {
6877                throw new IllegalArgumentException("Unknown owner: " + token);
6878            }
6879            if (fromUid != Binder.getCallingUid()) {
6880                if (Binder.getCallingUid() != Process.myUid()) {
6881                    // Only system code can grant URI permissions on behalf
6882                    // of other users.
6883                    throw new SecurityException("nice try");
6884                }
6885            }
6886            if (targetPkg == null) {
6887                throw new IllegalArgumentException("null target");
6888            }
6889            if (uri == null) {
6890                throw new IllegalArgumentException("null uri");
6891            }
6892
6893            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6894                    modeFlags, owner);
6895        }
6896    }
6897
6898    @Override
6899    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6900        synchronized(this) {
6901            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6902            if (owner == null) {
6903                throw new IllegalArgumentException("Unknown owner: " + token);
6904            }
6905
6906            if (uri == null) {
6907                owner.removeUriPermissionsLocked(mode);
6908            } else {
6909                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6910            }
6911        }
6912    }
6913
6914    private void schedulePersistUriGrants() {
6915        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6916            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6917                    10 * DateUtils.SECOND_IN_MILLIS);
6918        }
6919    }
6920
6921    private void writeGrantedUriPermissions() {
6922        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6923
6924        // Snapshot permissions so we can persist without lock
6925        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6926        synchronized (this) {
6927            final int size = mGrantedUriPermissions.size();
6928            for (int i = 0; i < size; i++) {
6929                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6930                for (UriPermission perm : perms.values()) {
6931                    if (perm.persistedModeFlags != 0) {
6932                        persist.add(perm.snapshot());
6933                    }
6934                }
6935            }
6936        }
6937
6938        FileOutputStream fos = null;
6939        try {
6940            fos = mGrantFile.startWrite();
6941
6942            XmlSerializer out = new FastXmlSerializer();
6943            out.setOutput(fos, "utf-8");
6944            out.startDocument(null, true);
6945            out.startTag(null, TAG_URI_GRANTS);
6946            for (UriPermission.Snapshot perm : persist) {
6947                out.startTag(null, TAG_URI_GRANT);
6948                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6949                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6950                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6951                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6952                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6953                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6954                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6955                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6956                out.endTag(null, TAG_URI_GRANT);
6957            }
6958            out.endTag(null, TAG_URI_GRANTS);
6959            out.endDocument();
6960
6961            mGrantFile.finishWrite(fos);
6962        } catch (IOException e) {
6963            if (fos != null) {
6964                mGrantFile.failWrite(fos);
6965            }
6966        }
6967    }
6968
6969    private void readGrantedUriPermissionsLocked() {
6970        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6971
6972        final long now = System.currentTimeMillis();
6973
6974        FileInputStream fis = null;
6975        try {
6976            fis = mGrantFile.openRead();
6977            final XmlPullParser in = Xml.newPullParser();
6978            in.setInput(fis, null);
6979
6980            int type;
6981            while ((type = in.next()) != END_DOCUMENT) {
6982                final String tag = in.getName();
6983                if (type == START_TAG) {
6984                    if (TAG_URI_GRANT.equals(tag)) {
6985                        final int sourceUserId;
6986                        final int targetUserId;
6987                        final int userHandle = readIntAttribute(in,
6988                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6989                        if (userHandle != UserHandle.USER_NULL) {
6990                            // For backwards compatibility.
6991                            sourceUserId = userHandle;
6992                            targetUserId = userHandle;
6993                        } else {
6994                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6995                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6996                        }
6997                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6998                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6999                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7000                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7001                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7002                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7003
7004                        // Sanity check that provider still belongs to source package
7005                        final ProviderInfo pi = getProviderInfoLocked(
7006                                uri.getAuthority(), sourceUserId);
7007                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7008                            int targetUid = -1;
7009                            try {
7010                                targetUid = AppGlobals.getPackageManager()
7011                                        .getPackageUid(targetPkg, targetUserId);
7012                            } catch (RemoteException e) {
7013                            }
7014                            if (targetUid != -1) {
7015                                final UriPermission perm = findOrCreateUriPermissionLocked(
7016                                        sourcePkg, targetPkg, targetUid,
7017                                        new GrantUri(sourceUserId, uri, prefix));
7018                                perm.initPersistedModes(modeFlags, createdTime);
7019                            }
7020                        } else {
7021                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7022                                    + " but instead found " + pi);
7023                        }
7024                    }
7025                }
7026            }
7027        } catch (FileNotFoundException e) {
7028            // Missing grants is okay
7029        } catch (IOException e) {
7030            Log.wtf(TAG, "Failed reading Uri grants", e);
7031        } catch (XmlPullParserException e) {
7032            Log.wtf(TAG, "Failed reading Uri grants", e);
7033        } finally {
7034            IoUtils.closeQuietly(fis);
7035        }
7036    }
7037
7038    @Override
7039    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7040        enforceNotIsolatedCaller("takePersistableUriPermission");
7041
7042        Preconditions.checkFlagsArgument(modeFlags,
7043                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7044
7045        synchronized (this) {
7046            final int callingUid = Binder.getCallingUid();
7047            boolean persistChanged = false;
7048            GrantUri grantUri = new GrantUri(userId, uri, false);
7049
7050            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7051                    new GrantUri(userId, uri, false));
7052            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7053                    new GrantUri(userId, uri, true));
7054
7055            final boolean exactValid = (exactPerm != null)
7056                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7057            final boolean prefixValid = (prefixPerm != null)
7058                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7059
7060            if (!(exactValid || prefixValid)) {
7061                throw new SecurityException("No persistable permission grants found for UID "
7062                        + callingUid + " and Uri " + grantUri.toSafeString());
7063            }
7064
7065            if (exactValid) {
7066                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7067            }
7068            if (prefixValid) {
7069                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7070            }
7071
7072            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7073
7074            if (persistChanged) {
7075                schedulePersistUriGrants();
7076            }
7077        }
7078    }
7079
7080    @Override
7081    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7082        enforceNotIsolatedCaller("releasePersistableUriPermission");
7083
7084        Preconditions.checkFlagsArgument(modeFlags,
7085                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7086
7087        synchronized (this) {
7088            final int callingUid = Binder.getCallingUid();
7089            boolean persistChanged = false;
7090
7091            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7092                    new GrantUri(userId, uri, false));
7093            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7094                    new GrantUri(userId, uri, true));
7095            if (exactPerm == null && prefixPerm == null) {
7096                throw new SecurityException("No permission grants found for UID " + callingUid
7097                        + " and Uri " + uri.toSafeString());
7098            }
7099
7100            if (exactPerm != null) {
7101                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7102                removeUriPermissionIfNeededLocked(exactPerm);
7103            }
7104            if (prefixPerm != null) {
7105                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7106                removeUriPermissionIfNeededLocked(prefixPerm);
7107            }
7108
7109            if (persistChanged) {
7110                schedulePersistUriGrants();
7111            }
7112        }
7113    }
7114
7115    /**
7116     * Prune any older {@link UriPermission} for the given UID until outstanding
7117     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7118     *
7119     * @return if any mutations occured that require persisting.
7120     */
7121    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7122        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7123        if (perms == null) return false;
7124        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7125
7126        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7127        for (UriPermission perm : perms.values()) {
7128            if (perm.persistedModeFlags != 0) {
7129                persisted.add(perm);
7130            }
7131        }
7132
7133        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7134        if (trimCount <= 0) return false;
7135
7136        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7137        for (int i = 0; i < trimCount; i++) {
7138            final UriPermission perm = persisted.get(i);
7139
7140            if (DEBUG_URI_PERMISSION) {
7141                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7142            }
7143
7144            perm.releasePersistableModes(~0);
7145            removeUriPermissionIfNeededLocked(perm);
7146        }
7147
7148        return true;
7149    }
7150
7151    @Override
7152    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7153            String packageName, boolean incoming) {
7154        enforceNotIsolatedCaller("getPersistedUriPermissions");
7155        Preconditions.checkNotNull(packageName, "packageName");
7156
7157        final int callingUid = Binder.getCallingUid();
7158        final IPackageManager pm = AppGlobals.getPackageManager();
7159        try {
7160            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7161            if (packageUid != callingUid) {
7162                throw new SecurityException(
7163                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7164            }
7165        } catch (RemoteException e) {
7166            throw new SecurityException("Failed to verify package name ownership");
7167        }
7168
7169        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7170        synchronized (this) {
7171            if (incoming) {
7172                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7173                        callingUid);
7174                if (perms == null) {
7175                    Slog.w(TAG, "No permission grants found for " + packageName);
7176                } else {
7177                    for (UriPermission perm : perms.values()) {
7178                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7179                            result.add(perm.buildPersistedPublicApiObject());
7180                        }
7181                    }
7182                }
7183            } else {
7184                final int size = mGrantedUriPermissions.size();
7185                for (int i = 0; i < size; i++) {
7186                    final ArrayMap<GrantUri, UriPermission> perms =
7187                            mGrantedUriPermissions.valueAt(i);
7188                    for (UriPermission perm : perms.values()) {
7189                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7190                            result.add(perm.buildPersistedPublicApiObject());
7191                        }
7192                    }
7193                }
7194            }
7195        }
7196        return new ParceledListSlice<android.content.UriPermission>(result);
7197    }
7198
7199    @Override
7200    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7201        synchronized (this) {
7202            ProcessRecord app =
7203                who != null ? getRecordForAppLocked(who) : null;
7204            if (app == null) return;
7205
7206            Message msg = Message.obtain();
7207            msg.what = WAIT_FOR_DEBUGGER_MSG;
7208            msg.obj = app;
7209            msg.arg1 = waiting ? 1 : 0;
7210            mHandler.sendMessage(msg);
7211        }
7212    }
7213
7214    @Override
7215    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7216        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7217        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7218        outInfo.availMem = Process.getFreeMemory();
7219        outInfo.totalMem = Process.getTotalMemory();
7220        outInfo.threshold = homeAppMem;
7221        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7222        outInfo.hiddenAppThreshold = cachedAppMem;
7223        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7224                ProcessList.SERVICE_ADJ);
7225        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7226                ProcessList.VISIBLE_APP_ADJ);
7227        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7228                ProcessList.FOREGROUND_APP_ADJ);
7229    }
7230
7231    // =========================================================
7232    // TASK MANAGEMENT
7233    // =========================================================
7234
7235    @Override
7236    public List<IAppTask> getAppTasks() {
7237        final PackageManager pm = mContext.getPackageManager();
7238        int callingUid = Binder.getCallingUid();
7239        long ident = Binder.clearCallingIdentity();
7240
7241        // Compose the list of packages for this id to test against
7242        HashSet<String> packages = new HashSet<String>();
7243        String[] uidPackages = pm.getPackagesForUid(callingUid);
7244        for (int i = 0; i < uidPackages.length; i++) {
7245            packages.add(uidPackages[i]);
7246        }
7247
7248        synchronized(this) {
7249            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7250            try {
7251                if (localLOGV) Slog.v(TAG, "getAppTasks");
7252
7253                final int N = mRecentTasks.size();
7254                for (int i = 0; i < N; i++) {
7255                    TaskRecord tr = mRecentTasks.get(i);
7256                    // Skip tasks that are not created by the caller
7257                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7258                        ActivityManager.RecentTaskInfo taskInfo =
7259                                createRecentTaskInfoFromTaskRecord(tr);
7260                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7261                        list.add(taskImpl);
7262                    }
7263                }
7264            } finally {
7265                Binder.restoreCallingIdentity(ident);
7266            }
7267            return list;
7268        }
7269    }
7270
7271    @Override
7272    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7273        final int callingUid = Binder.getCallingUid();
7274        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7275
7276        synchronized(this) {
7277            if (localLOGV) Slog.v(
7278                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7279
7280            final boolean allowed = checkCallingPermission(
7281                    android.Manifest.permission.GET_TASKS)
7282                    == PackageManager.PERMISSION_GRANTED;
7283            if (!allowed) {
7284                Slog.w(TAG, "getTasks: caller " + callingUid
7285                        + " does not hold GET_TASKS; limiting output");
7286            }
7287
7288            // TODO: Improve with MRU list from all ActivityStacks.
7289            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7290        }
7291
7292        return list;
7293    }
7294
7295    TaskRecord getMostRecentTask() {
7296        return mRecentTasks.get(0);
7297    }
7298
7299    /**
7300     * Creates a new RecentTaskInfo from a TaskRecord.
7301     */
7302    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7303        // Update the task description to reflect any changes in the task stack
7304        tr.updateTaskDescription();
7305
7306        // Compose the recent task info
7307        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7308        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7309        rti.persistentId = tr.taskId;
7310        rti.baseIntent = new Intent(tr.getBaseIntent());
7311        rti.origActivity = tr.origActivity;
7312        rti.description = tr.lastDescription;
7313        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7314        rti.userId = tr.userId;
7315        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7316        rti.firstActiveTime = tr.firstActiveTime;
7317        rti.lastActiveTime = tr.lastActiveTime;
7318        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7319        return rti;
7320    }
7321
7322    @Override
7323    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7324        final int callingUid = Binder.getCallingUid();
7325        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7326                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7327
7328        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7329        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7330        synchronized (this) {
7331            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7332                    == PackageManager.PERMISSION_GRANTED;
7333            if (!allowed) {
7334                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7335                        + " does not hold GET_TASKS; limiting output");
7336            }
7337            final boolean detailed = checkCallingPermission(
7338                    android.Manifest.permission.GET_DETAILED_TASKS)
7339                    == PackageManager.PERMISSION_GRANTED;
7340
7341            IPackageManager pm = AppGlobals.getPackageManager();
7342
7343            final int N = mRecentTasks.size();
7344            ArrayList<ActivityManager.RecentTaskInfo> res
7345                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7346                            maxNum < N ? maxNum : N);
7347
7348            final Set<Integer> includedUsers;
7349            if (includeProfiles) {
7350                includedUsers = getProfileIdsLocked(userId);
7351            } else {
7352                includedUsers = new HashSet<Integer>();
7353            }
7354            includedUsers.add(Integer.valueOf(userId));
7355
7356            // Regroup affiliated tasks together.
7357            for (int i = 0; i < N; ) {
7358                TaskRecord task = mRecentTasks.remove(i);
7359                if (mTmpRecents.contains(task)) {
7360                    continue;
7361                }
7362                int affiliatedTaskId = task.mAffiliatedTaskId;
7363                while (true) {
7364                    TaskRecord next = task.mNextAffiliate;
7365                    if (next == null) {
7366                        break;
7367                    }
7368                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7369                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7370                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7371                        task.setNextAffiliate(null);
7372                        if (next.mPrevAffiliate == task) {
7373                            next.setPrevAffiliate(null);
7374                        }
7375                        break;
7376                    }
7377                    if (next.mPrevAffiliate != task) {
7378                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7379                                next.mPrevAffiliate + " task=" + task);
7380                        next.setPrevAffiliate(null);
7381                        break;
7382                    }
7383                    if (!mRecentTasks.contains(next)) {
7384                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7385                        task.setNextAffiliate(null);
7386                        if (next.mPrevAffiliate == task) {
7387                            next.setPrevAffiliate(null);
7388                        }
7389                        break;
7390                    }
7391                    task = next;
7392                }
7393                // task is now the end of the list
7394                do {
7395                    mRecentTasks.remove(task);
7396                    mRecentTasks.add(i++, task);
7397                    mTmpRecents.add(task);
7398                } while ((task = task.mPrevAffiliate) != null);
7399            }
7400            mTmpRecents.clear();
7401            // mRecentTasks is now in sorted, affiliated order.
7402
7403            for (int i=0; i<N && maxNum > 0; i++) {
7404                TaskRecord tr = mRecentTasks.get(i);
7405                // Only add calling user or related users recent tasks
7406                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7407
7408                // Return the entry if desired by the caller.  We always return
7409                // the first entry, because callers always expect this to be the
7410                // foreground app.  We may filter others if the caller has
7411                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7412                // we should exclude the entry.
7413
7414                if (i == 0
7415                        || withExcluded
7416                        || (tr.intent == null)
7417                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7418                                == 0)) {
7419                    if (!allowed) {
7420                        // If the caller doesn't have the GET_TASKS permission, then only
7421                        // allow them to see a small subset of tasks -- their own and home.
7422                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7423                            continue;
7424                        }
7425                    }
7426                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7427                        // Don't include auto remove tasks that are finished or finishing.
7428                        continue;
7429                    }
7430
7431                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7432                    if (!detailed) {
7433                        rti.baseIntent.replaceExtras((Bundle)null);
7434                    }
7435
7436                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7437                        // Check whether this activity is currently available.
7438                        try {
7439                            if (rti.origActivity != null) {
7440                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7441                                        == null) {
7442                                    continue;
7443                                }
7444                            } else if (rti.baseIntent != null) {
7445                                if (pm.queryIntentActivities(rti.baseIntent,
7446                                        null, 0, userId) == null) {
7447                                    continue;
7448                                }
7449                            }
7450                        } catch (RemoteException e) {
7451                            // Will never happen.
7452                        }
7453                    }
7454
7455                    res.add(rti);
7456                    maxNum--;
7457                }
7458            }
7459            return res;
7460        }
7461    }
7462
7463    private TaskRecord recentTaskForIdLocked(int id) {
7464        final int N = mRecentTasks.size();
7465            for (int i=0; i<N; i++) {
7466                TaskRecord tr = mRecentTasks.get(i);
7467                if (tr.taskId == id) {
7468                    return tr;
7469                }
7470            }
7471            return null;
7472    }
7473
7474    @Override
7475    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7476        synchronized (this) {
7477            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7478                    "getTaskThumbnail()");
7479            TaskRecord tr = recentTaskForIdLocked(id);
7480            if (tr != null) {
7481                return tr.getTaskThumbnailLocked();
7482            }
7483        }
7484        return null;
7485    }
7486
7487    @Override
7488    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7489        synchronized (this) {
7490            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7491            if (r != null) {
7492                r.taskDescription = td;
7493                r.task.updateTaskDescription();
7494            }
7495        }
7496    }
7497
7498    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7499        if (!pr.killedByAm) {
7500            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7501            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7502                    pr.processName, pr.setAdj, reason);
7503            pr.killedByAm = true;
7504            Process.killProcessQuiet(pr.pid);
7505            Process.killProcessGroup(pr.info.uid, pr.pid);
7506        }
7507    }
7508
7509    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7510        tr.disposeThumbnail();
7511        mRecentTasks.remove(tr);
7512        tr.closeRecentsChain();
7513        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7514        Intent baseIntent = new Intent(
7515                tr.intent != null ? tr.intent : tr.affinityIntent);
7516        ComponentName component = baseIntent.getComponent();
7517        if (component == null) {
7518            Slog.w(TAG, "Now component for base intent of task: " + tr);
7519            return;
7520        }
7521
7522        // Find any running services associated with this app.
7523        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7524
7525        if (killProcesses) {
7526            // Find any running processes associated with this app.
7527            final String pkg = component.getPackageName();
7528            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7529            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7530            for (int i=0; i<pmap.size(); i++) {
7531                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7532                for (int j=0; j<uids.size(); j++) {
7533                    ProcessRecord proc = uids.valueAt(j);
7534                    if (proc.userId != tr.userId) {
7535                        continue;
7536                    }
7537                    if (!proc.pkgList.containsKey(pkg)) {
7538                        continue;
7539                    }
7540                    procs.add(proc);
7541                }
7542            }
7543
7544            // Kill the running processes.
7545            for (int i=0; i<procs.size(); i++) {
7546                ProcessRecord pr = procs.get(i);
7547                if (pr == mHomeProcess) {
7548                    // Don't kill the home process along with tasks from the same package.
7549                    continue;
7550                }
7551                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7552                    killUnneededProcessLocked(pr, "remove task");
7553                } else {
7554                    pr.waitingToKill = "remove task";
7555                }
7556            }
7557        }
7558    }
7559
7560    /**
7561     * Removes the task with the specified task id.
7562     *
7563     * @param taskId Identifier of the task to be removed.
7564     * @param flags Additional operational flags.  May be 0 or
7565     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7566     * @return Returns true if the given task was found and removed.
7567     */
7568    private boolean removeTaskByIdLocked(int taskId, int flags) {
7569        TaskRecord tr = recentTaskForIdLocked(taskId);
7570        if (tr != null) {
7571            tr.removeTaskActivitiesLocked();
7572            cleanUpRemovedTaskLocked(tr, flags);
7573            if (tr.isPersistable) {
7574                notifyTaskPersisterLocked(tr, true);
7575            }
7576            return true;
7577        }
7578        return false;
7579    }
7580
7581    @Override
7582    public boolean removeTask(int taskId, int flags) {
7583        synchronized (this) {
7584            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7585                    "removeTask()");
7586            long ident = Binder.clearCallingIdentity();
7587            try {
7588                return removeTaskByIdLocked(taskId, flags);
7589            } finally {
7590                Binder.restoreCallingIdentity(ident);
7591            }
7592        }
7593    }
7594
7595    /**
7596     * TODO: Add mController hook
7597     */
7598    @Override
7599    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7600        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7601                "moveTaskToFront()");
7602
7603        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7604        synchronized(this) {
7605            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7606                    Binder.getCallingUid(), "Task to front")) {
7607                ActivityOptions.abort(options);
7608                return;
7609            }
7610            final long origId = Binder.clearCallingIdentity();
7611            try {
7612                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7613                if (task == null) {
7614                    return;
7615                }
7616                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7617                    mStackSupervisor.showLockTaskToast();
7618                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7619                    return;
7620                }
7621                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7622                if (prev != null && prev.isRecentsActivity()) {
7623                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7624                }
7625                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7626            } finally {
7627                Binder.restoreCallingIdentity(origId);
7628            }
7629            ActivityOptions.abort(options);
7630        }
7631    }
7632
7633    @Override
7634    public void moveTaskToBack(int taskId) {
7635        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7636                "moveTaskToBack()");
7637
7638        synchronized(this) {
7639            TaskRecord tr = recentTaskForIdLocked(taskId);
7640            if (tr != null) {
7641                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7642                ActivityStack stack = tr.stack;
7643                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7644                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7645                            Binder.getCallingUid(), "Task to back")) {
7646                        return;
7647                    }
7648                }
7649                final long origId = Binder.clearCallingIdentity();
7650                try {
7651                    stack.moveTaskToBackLocked(taskId, null);
7652                } finally {
7653                    Binder.restoreCallingIdentity(origId);
7654                }
7655            }
7656        }
7657    }
7658
7659    /**
7660     * Moves an activity, and all of the other activities within the same task, to the bottom
7661     * of the history stack.  The activity's order within the task is unchanged.
7662     *
7663     * @param token A reference to the activity we wish to move
7664     * @param nonRoot If false then this only works if the activity is the root
7665     *                of a task; if true it will work for any activity in a task.
7666     * @return Returns true if the move completed, false if not.
7667     */
7668    @Override
7669    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7670        enforceNotIsolatedCaller("moveActivityTaskToBack");
7671        synchronized(this) {
7672            final long origId = Binder.clearCallingIdentity();
7673            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7674            if (taskId >= 0) {
7675                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7676            }
7677            Binder.restoreCallingIdentity(origId);
7678        }
7679        return false;
7680    }
7681
7682    @Override
7683    public void moveTaskBackwards(int task) {
7684        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7685                "moveTaskBackwards()");
7686
7687        synchronized(this) {
7688            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7689                    Binder.getCallingUid(), "Task backwards")) {
7690                return;
7691            }
7692            final long origId = Binder.clearCallingIdentity();
7693            moveTaskBackwardsLocked(task);
7694            Binder.restoreCallingIdentity(origId);
7695        }
7696    }
7697
7698    private final void moveTaskBackwardsLocked(int task) {
7699        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7700    }
7701
7702    @Override
7703    public IBinder getHomeActivityToken() throws RemoteException {
7704        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7705                "getHomeActivityToken()");
7706        synchronized (this) {
7707            return mStackSupervisor.getHomeActivityToken();
7708        }
7709    }
7710
7711    @Override
7712    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7713            IActivityContainerCallback callback) throws RemoteException {
7714        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7715                "createActivityContainer()");
7716        synchronized (this) {
7717            if (parentActivityToken == null) {
7718                throw new IllegalArgumentException("parent token must not be null");
7719            }
7720            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7721            if (r == null) {
7722                return null;
7723            }
7724            if (callback == null) {
7725                throw new IllegalArgumentException("callback must not be null");
7726            }
7727            return mStackSupervisor.createActivityContainer(r, callback);
7728        }
7729    }
7730
7731    @Override
7732    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7733        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7734                "deleteActivityContainer()");
7735        synchronized (this) {
7736            mStackSupervisor.deleteActivityContainer(container);
7737        }
7738    }
7739
7740    @Override
7741    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7742            throws RemoteException {
7743        synchronized (this) {
7744            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7745            if (stack != null) {
7746                return stack.mActivityContainer;
7747            }
7748            return null;
7749        }
7750    }
7751
7752    @Override
7753    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7754        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7755                "moveTaskToStack()");
7756        if (stackId == HOME_STACK_ID) {
7757            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7758                    new RuntimeException("here").fillInStackTrace());
7759        }
7760        synchronized (this) {
7761            long ident = Binder.clearCallingIdentity();
7762            try {
7763                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7764                        + stackId + " toTop=" + toTop);
7765                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7766            } finally {
7767                Binder.restoreCallingIdentity(ident);
7768            }
7769        }
7770    }
7771
7772    @Override
7773    public void resizeStack(int stackBoxId, Rect bounds) {
7774        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7775                "resizeStackBox()");
7776        long ident = Binder.clearCallingIdentity();
7777        try {
7778            mWindowManager.resizeStack(stackBoxId, bounds);
7779        } finally {
7780            Binder.restoreCallingIdentity(ident);
7781        }
7782    }
7783
7784    @Override
7785    public List<StackInfo> getAllStackInfos() {
7786        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7787                "getAllStackInfos()");
7788        long ident = Binder.clearCallingIdentity();
7789        try {
7790            synchronized (this) {
7791                return mStackSupervisor.getAllStackInfosLocked();
7792            }
7793        } finally {
7794            Binder.restoreCallingIdentity(ident);
7795        }
7796    }
7797
7798    @Override
7799    public StackInfo getStackInfo(int stackId) {
7800        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7801                "getStackInfo()");
7802        long ident = Binder.clearCallingIdentity();
7803        try {
7804            synchronized (this) {
7805                return mStackSupervisor.getStackInfoLocked(stackId);
7806            }
7807        } finally {
7808            Binder.restoreCallingIdentity(ident);
7809        }
7810    }
7811
7812    @Override
7813    public boolean isInHomeStack(int taskId) {
7814        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7815                "getStackInfo()");
7816        long ident = Binder.clearCallingIdentity();
7817        try {
7818            synchronized (this) {
7819                TaskRecord tr = recentTaskForIdLocked(taskId);
7820                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7821            }
7822        } finally {
7823            Binder.restoreCallingIdentity(ident);
7824        }
7825    }
7826
7827    @Override
7828    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7829        synchronized(this) {
7830            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7831        }
7832    }
7833
7834    private boolean isLockTaskAuthorized(String pkg) {
7835        final DevicePolicyManager dpm = (DevicePolicyManager)
7836                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7837        try {
7838            int uid = mContext.getPackageManager().getPackageUid(pkg,
7839                    Binder.getCallingUserHandle().getIdentifier());
7840            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7841        } catch (NameNotFoundException e) {
7842            return false;
7843        }
7844    }
7845
7846    void startLockTaskMode(TaskRecord task) {
7847        final String pkg;
7848        synchronized (this) {
7849            pkg = task.intent.getComponent().getPackageName();
7850        }
7851        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7852        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7853            final TaskRecord taskRecord = task;
7854            mHandler.post(new Runnable() {
7855                @Override
7856                public void run() {
7857                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7858                }
7859            });
7860            return;
7861        }
7862        long ident = Binder.clearCallingIdentity();
7863        try {
7864            synchronized (this) {
7865                // Since we lost lock on task, make sure it is still there.
7866                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7867                if (task != null) {
7868                    if (!isSystemInitiated
7869                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7870                        throw new IllegalArgumentException("Invalid task, not in foreground");
7871                    }
7872                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7873                }
7874            }
7875        } finally {
7876            Binder.restoreCallingIdentity(ident);
7877        }
7878    }
7879
7880    @Override
7881    public void startLockTaskMode(int taskId) {
7882        final TaskRecord task;
7883        long ident = Binder.clearCallingIdentity();
7884        try {
7885            synchronized (this) {
7886                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7887            }
7888        } finally {
7889            Binder.restoreCallingIdentity(ident);
7890        }
7891        if (task != null) {
7892            startLockTaskMode(task);
7893        }
7894    }
7895
7896    @Override
7897    public void startLockTaskMode(IBinder token) {
7898        final TaskRecord task;
7899        long ident = Binder.clearCallingIdentity();
7900        try {
7901            synchronized (this) {
7902                final ActivityRecord r = ActivityRecord.forToken(token);
7903                if (r == null) {
7904                    return;
7905                }
7906                task = r.task;
7907            }
7908        } finally {
7909            Binder.restoreCallingIdentity(ident);
7910        }
7911        if (task != null) {
7912            startLockTaskMode(task);
7913        }
7914    }
7915
7916    @Override
7917    public void startLockTaskModeOnCurrent() throws RemoteException {
7918        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7919        ActivityRecord r = null;
7920        synchronized (this) {
7921            r = mStackSupervisor.topRunningActivityLocked();
7922        }
7923        startLockTaskMode(r.task);
7924    }
7925
7926    @Override
7927    public void stopLockTaskMode() {
7928        // Verify that the user matches the package of the intent for the TaskRecord
7929        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7930        // and stopLockTaskMode.
7931        final int callingUid = Binder.getCallingUid();
7932        if (callingUid != Process.SYSTEM_UID) {
7933            try {
7934                String pkg =
7935                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7936                int uid = mContext.getPackageManager().getPackageUid(pkg,
7937                        Binder.getCallingUserHandle().getIdentifier());
7938                if (uid != callingUid) {
7939                    throw new SecurityException("Invalid uid, expected " + uid);
7940                }
7941            } catch (NameNotFoundException e) {
7942                Log.d(TAG, "stopLockTaskMode " + e);
7943                return;
7944            }
7945        }
7946        long ident = Binder.clearCallingIdentity();
7947        try {
7948            Log.d(TAG, "stopLockTaskMode");
7949            // Stop lock task
7950            synchronized (this) {
7951                mStackSupervisor.setLockTaskModeLocked(null, false);
7952            }
7953        } finally {
7954            Binder.restoreCallingIdentity(ident);
7955        }
7956    }
7957
7958    @Override
7959    public void stopLockTaskModeOnCurrent() throws RemoteException {
7960        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7961        long ident = Binder.clearCallingIdentity();
7962        try {
7963            stopLockTaskMode();
7964        } finally {
7965            Binder.restoreCallingIdentity(ident);
7966        }
7967    }
7968
7969    @Override
7970    public boolean isInLockTaskMode() {
7971        synchronized (this) {
7972            return mStackSupervisor.isInLockTaskMode();
7973        }
7974    }
7975
7976    // =========================================================
7977    // CONTENT PROVIDERS
7978    // =========================================================
7979
7980    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7981        List<ProviderInfo> providers = null;
7982        try {
7983            providers = AppGlobals.getPackageManager().
7984                queryContentProviders(app.processName, app.uid,
7985                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7986        } catch (RemoteException ex) {
7987        }
7988        if (DEBUG_MU)
7989            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7990        int userId = app.userId;
7991        if (providers != null) {
7992            int N = providers.size();
7993            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7994            for (int i=0; i<N; i++) {
7995                ProviderInfo cpi =
7996                    (ProviderInfo)providers.get(i);
7997                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7998                        cpi.name, cpi.flags);
7999                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8000                    // This is a singleton provider, but a user besides the
8001                    // default user is asking to initialize a process it runs
8002                    // in...  well, no, it doesn't actually run in this process,
8003                    // it runs in the process of the default user.  Get rid of it.
8004                    providers.remove(i);
8005                    N--;
8006                    i--;
8007                    continue;
8008                }
8009
8010                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8011                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8012                if (cpr == null) {
8013                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8014                    mProviderMap.putProviderByClass(comp, cpr);
8015                }
8016                if (DEBUG_MU)
8017                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8018                app.pubProviders.put(cpi.name, cpr);
8019                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8020                    // Don't add this if it is a platform component that is marked
8021                    // to run in multiple processes, because this is actually
8022                    // part of the framework so doesn't make sense to track as a
8023                    // separate apk in the process.
8024                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8025                            mProcessStats);
8026                }
8027                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8028            }
8029        }
8030        return providers;
8031    }
8032
8033    /**
8034     * Check if {@link ProcessRecord} has a possible chance at accessing the
8035     * given {@link ProviderInfo}. Final permission checking is always done
8036     * in {@link ContentProvider}.
8037     */
8038    private final String checkContentProviderPermissionLocked(
8039            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8040        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8041        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8042        boolean checkedGrants = false;
8043        if (checkUser) {
8044            // Looking for cross-user grants before enforcing the typical cross-users permissions
8045            int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid));
8046            if (tmpTargetUserId != userId) {
8047                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8048                    return null;
8049                }
8050                checkedGrants = true;
8051            }
8052            userId = handleIncomingUser(callingPid, callingUid, userId,
8053                    false, ALLOW_NON_FULL,
8054                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8055            if (userId != tmpTargetUserId) {
8056                // When we actually went to determine the final targer user ID, this ended
8057                // up different than our initial check for the authority.  This is because
8058                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8059                // SELF.  So we need to re-check the grants again.
8060                checkedGrants = false;
8061            }
8062        }
8063        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8064                cpi.applicationInfo.uid, cpi.exported)
8065                == PackageManager.PERMISSION_GRANTED) {
8066            return null;
8067        }
8068        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8069                cpi.applicationInfo.uid, cpi.exported)
8070                == PackageManager.PERMISSION_GRANTED) {
8071            return null;
8072        }
8073
8074        PathPermission[] pps = cpi.pathPermissions;
8075        if (pps != null) {
8076            int i = pps.length;
8077            while (i > 0) {
8078                i--;
8079                PathPermission pp = pps[i];
8080                String pprperm = pp.getReadPermission();
8081                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8082                        cpi.applicationInfo.uid, cpi.exported)
8083                        == PackageManager.PERMISSION_GRANTED) {
8084                    return null;
8085                }
8086                String ppwperm = pp.getWritePermission();
8087                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8088                        cpi.applicationInfo.uid, cpi.exported)
8089                        == PackageManager.PERMISSION_GRANTED) {
8090                    return null;
8091                }
8092            }
8093        }
8094        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8095            return null;
8096        }
8097
8098        String msg;
8099        if (!cpi.exported) {
8100            msg = "Permission Denial: opening provider " + cpi.name
8101                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8102                    + ", uid=" + callingUid + ") that is not exported from uid "
8103                    + cpi.applicationInfo.uid;
8104        } else {
8105            msg = "Permission Denial: opening provider " + cpi.name
8106                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8107                    + ", uid=" + callingUid + ") requires "
8108                    + cpi.readPermission + " or " + cpi.writePermission;
8109        }
8110        Slog.w(TAG, msg);
8111        return msg;
8112    }
8113
8114    /**
8115     * Returns if the ContentProvider has granted a uri to callingUid
8116     */
8117    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8118        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8119        if (perms != null) {
8120            for (int i=perms.size()-1; i>=0; i--) {
8121                GrantUri grantUri = perms.keyAt(i);
8122                if (grantUri.sourceUserId == userId || !checkUser) {
8123                    if (matchesProvider(grantUri.uri, cpi)) {
8124                        return true;
8125                    }
8126                }
8127            }
8128        }
8129        return false;
8130    }
8131
8132    /**
8133     * Returns true if the uri authority is one of the authorities specified in the provider.
8134     */
8135    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8136        String uriAuth = uri.getAuthority();
8137        String cpiAuth = cpi.authority;
8138        if (cpiAuth.indexOf(';') == -1) {
8139            return cpiAuth.equals(uriAuth);
8140        }
8141        String[] cpiAuths = cpiAuth.split(";");
8142        int length = cpiAuths.length;
8143        for (int i = 0; i < length; i++) {
8144            if (cpiAuths[i].equals(uriAuth)) return true;
8145        }
8146        return false;
8147    }
8148
8149    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8150            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8151        if (r != null) {
8152            for (int i=0; i<r.conProviders.size(); i++) {
8153                ContentProviderConnection conn = r.conProviders.get(i);
8154                if (conn.provider == cpr) {
8155                    if (DEBUG_PROVIDER) Slog.v(TAG,
8156                            "Adding provider requested by "
8157                            + r.processName + " from process "
8158                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8159                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8160                    if (stable) {
8161                        conn.stableCount++;
8162                        conn.numStableIncs++;
8163                    } else {
8164                        conn.unstableCount++;
8165                        conn.numUnstableIncs++;
8166                    }
8167                    return conn;
8168                }
8169            }
8170            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8171            if (stable) {
8172                conn.stableCount = 1;
8173                conn.numStableIncs = 1;
8174            } else {
8175                conn.unstableCount = 1;
8176                conn.numUnstableIncs = 1;
8177            }
8178            cpr.connections.add(conn);
8179            r.conProviders.add(conn);
8180            return conn;
8181        }
8182        cpr.addExternalProcessHandleLocked(externalProcessToken);
8183        return null;
8184    }
8185
8186    boolean decProviderCountLocked(ContentProviderConnection conn,
8187            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8188        if (conn != null) {
8189            cpr = conn.provider;
8190            if (DEBUG_PROVIDER) Slog.v(TAG,
8191                    "Removing provider requested by "
8192                    + conn.client.processName + " from process "
8193                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8194                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8195            if (stable) {
8196                conn.stableCount--;
8197            } else {
8198                conn.unstableCount--;
8199            }
8200            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8201                cpr.connections.remove(conn);
8202                conn.client.conProviders.remove(conn);
8203                return true;
8204            }
8205            return false;
8206        }
8207        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8208        return false;
8209    }
8210
8211    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8212            String name, IBinder token, boolean stable, int userId) {
8213        ContentProviderRecord cpr;
8214        ContentProviderConnection conn = null;
8215        ProviderInfo cpi = null;
8216
8217        synchronized(this) {
8218            ProcessRecord r = null;
8219            if (caller != null) {
8220                r = getRecordForAppLocked(caller);
8221                if (r == null) {
8222                    throw new SecurityException(
8223                            "Unable to find app for caller " + caller
8224                          + " (pid=" + Binder.getCallingPid()
8225                          + ") when getting content provider " + name);
8226                }
8227            }
8228
8229            boolean checkCrossUser = true;
8230
8231            // First check if this content provider has been published...
8232            cpr = mProviderMap.getProviderByName(name, userId);
8233            // If that didn't work, check if it exists for user 0 and then
8234            // verify that it's a singleton provider before using it.
8235            if (cpr == null && userId != UserHandle.USER_OWNER) {
8236                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8237                if (cpr != null) {
8238                    cpi = cpr.info;
8239                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8240                            cpi.name, cpi.flags)
8241                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8242                        userId = UserHandle.USER_OWNER;
8243                        checkCrossUser = false;
8244                    } else {
8245                        cpr = null;
8246                        cpi = null;
8247                    }
8248                }
8249            }
8250
8251            boolean providerRunning = cpr != null;
8252            if (providerRunning) {
8253                cpi = cpr.info;
8254                String msg;
8255                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8256                        != null) {
8257                    throw new SecurityException(msg);
8258                }
8259
8260                if (r != null && cpr.canRunHere(r)) {
8261                    // This provider has been published or is in the process
8262                    // of being published...  but it is also allowed to run
8263                    // in the caller's process, so don't make a connection
8264                    // and just let the caller instantiate its own instance.
8265                    ContentProviderHolder holder = cpr.newHolder(null);
8266                    // don't give caller the provider object, it needs
8267                    // to make its own.
8268                    holder.provider = null;
8269                    return holder;
8270                }
8271
8272                final long origId = Binder.clearCallingIdentity();
8273
8274                // In this case the provider instance already exists, so we can
8275                // return it right away.
8276                conn = incProviderCountLocked(r, cpr, token, stable);
8277                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8278                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8279                        // If this is a perceptible app accessing the provider,
8280                        // make sure to count it as being accessed and thus
8281                        // back up on the LRU list.  This is good because
8282                        // content providers are often expensive to start.
8283                        updateLruProcessLocked(cpr.proc, false, null);
8284                    }
8285                }
8286
8287                if (cpr.proc != null) {
8288                    if (false) {
8289                        if (cpr.name.flattenToShortString().equals(
8290                                "com.android.providers.calendar/.CalendarProvider2")) {
8291                            Slog.v(TAG, "****************** KILLING "
8292                                + cpr.name.flattenToShortString());
8293                            Process.killProcess(cpr.proc.pid);
8294                        }
8295                    }
8296                    boolean success = updateOomAdjLocked(cpr.proc);
8297                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8298                    // NOTE: there is still a race here where a signal could be
8299                    // pending on the process even though we managed to update its
8300                    // adj level.  Not sure what to do about this, but at least
8301                    // the race is now smaller.
8302                    if (!success) {
8303                        // Uh oh...  it looks like the provider's process
8304                        // has been killed on us.  We need to wait for a new
8305                        // process to be started, and make sure its death
8306                        // doesn't kill our process.
8307                        Slog.i(TAG,
8308                                "Existing provider " + cpr.name.flattenToShortString()
8309                                + " is crashing; detaching " + r);
8310                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8311                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8312                        if (!lastRef) {
8313                            // This wasn't the last ref our process had on
8314                            // the provider...  we have now been killed, bail.
8315                            return null;
8316                        }
8317                        providerRunning = false;
8318                        conn = null;
8319                    }
8320                }
8321
8322                Binder.restoreCallingIdentity(origId);
8323            }
8324
8325            boolean singleton;
8326            if (!providerRunning) {
8327                try {
8328                    cpi = AppGlobals.getPackageManager().
8329                        resolveContentProvider(name,
8330                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8331                } catch (RemoteException ex) {
8332                }
8333                if (cpi == null) {
8334                    return null;
8335                }
8336                // If the provider is a singleton AND
8337                // (it's a call within the same user || the provider is a
8338                // privileged app)
8339                // Then allow connecting to the singleton provider
8340                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8341                        cpi.name, cpi.flags)
8342                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8343                if (singleton) {
8344                    userId = UserHandle.USER_OWNER;
8345                }
8346                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8347
8348                String msg;
8349                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8350                        != null) {
8351                    throw new SecurityException(msg);
8352                }
8353
8354                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8355                        && !cpi.processName.equals("system")) {
8356                    // If this content provider does not run in the system
8357                    // process, and the system is not yet ready to run other
8358                    // processes, then fail fast instead of hanging.
8359                    throw new IllegalArgumentException(
8360                            "Attempt to launch content provider before system ready");
8361                }
8362
8363                // Make sure that the user who owns this provider is started.  If not,
8364                // we don't want to allow it to run.
8365                if (mStartedUsers.get(userId) == null) {
8366                    Slog.w(TAG, "Unable to launch app "
8367                            + cpi.applicationInfo.packageName + "/"
8368                            + cpi.applicationInfo.uid + " for provider "
8369                            + name + ": user " + userId + " is stopped");
8370                    return null;
8371                }
8372
8373                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8374                cpr = mProviderMap.getProviderByClass(comp, userId);
8375                final boolean firstClass = cpr == null;
8376                if (firstClass) {
8377                    try {
8378                        ApplicationInfo ai =
8379                            AppGlobals.getPackageManager().
8380                                getApplicationInfo(
8381                                        cpi.applicationInfo.packageName,
8382                                        STOCK_PM_FLAGS, userId);
8383                        if (ai == null) {
8384                            Slog.w(TAG, "No package info for content provider "
8385                                    + cpi.name);
8386                            return null;
8387                        }
8388                        ai = getAppInfoForUser(ai, userId);
8389                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8390                    } catch (RemoteException ex) {
8391                        // pm is in same process, this will never happen.
8392                    }
8393                }
8394
8395                if (r != null && cpr.canRunHere(r)) {
8396                    // If this is a multiprocess provider, then just return its
8397                    // info and allow the caller to instantiate it.  Only do
8398                    // this if the provider is the same user as the caller's
8399                    // process, or can run as root (so can be in any process).
8400                    return cpr.newHolder(null);
8401                }
8402
8403                if (DEBUG_PROVIDER) {
8404                    RuntimeException e = new RuntimeException("here");
8405                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8406                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8407                }
8408
8409                // This is single process, and our app is now connecting to it.
8410                // See if we are already in the process of launching this
8411                // provider.
8412                final int N = mLaunchingProviders.size();
8413                int i;
8414                for (i=0; i<N; i++) {
8415                    if (mLaunchingProviders.get(i) == cpr) {
8416                        break;
8417                    }
8418                }
8419
8420                // If the provider is not already being launched, then get it
8421                // started.
8422                if (i >= N) {
8423                    final long origId = Binder.clearCallingIdentity();
8424
8425                    try {
8426                        // Content provider is now in use, its package can't be stopped.
8427                        try {
8428                            AppGlobals.getPackageManager().setPackageStoppedState(
8429                                    cpr.appInfo.packageName, false, userId);
8430                        } catch (RemoteException e) {
8431                        } catch (IllegalArgumentException e) {
8432                            Slog.w(TAG, "Failed trying to unstop package "
8433                                    + cpr.appInfo.packageName + ": " + e);
8434                        }
8435
8436                        // Use existing process if already started
8437                        ProcessRecord proc = getProcessRecordLocked(
8438                                cpi.processName, cpr.appInfo.uid, false);
8439                        if (proc != null && proc.thread != null) {
8440                            if (DEBUG_PROVIDER) {
8441                                Slog.d(TAG, "Installing in existing process " + proc);
8442                            }
8443                            proc.pubProviders.put(cpi.name, cpr);
8444                            try {
8445                                proc.thread.scheduleInstallProvider(cpi);
8446                            } catch (RemoteException e) {
8447                            }
8448                        } else {
8449                            proc = startProcessLocked(cpi.processName,
8450                                    cpr.appInfo, false, 0, "content provider",
8451                                    new ComponentName(cpi.applicationInfo.packageName,
8452                                            cpi.name), false, false, false);
8453                            if (proc == null) {
8454                                Slog.w(TAG, "Unable to launch app "
8455                                        + cpi.applicationInfo.packageName + "/"
8456                                        + cpi.applicationInfo.uid + " for provider "
8457                                        + name + ": process is bad");
8458                                return null;
8459                            }
8460                        }
8461                        cpr.launchingApp = proc;
8462                        mLaunchingProviders.add(cpr);
8463                    } finally {
8464                        Binder.restoreCallingIdentity(origId);
8465                    }
8466                }
8467
8468                // Make sure the provider is published (the same provider class
8469                // may be published under multiple names).
8470                if (firstClass) {
8471                    mProviderMap.putProviderByClass(comp, cpr);
8472                }
8473
8474                mProviderMap.putProviderByName(name, cpr);
8475                conn = incProviderCountLocked(r, cpr, token, stable);
8476                if (conn != null) {
8477                    conn.waiting = true;
8478                }
8479            }
8480        }
8481
8482        // Wait for the provider to be published...
8483        synchronized (cpr) {
8484            while (cpr.provider == null) {
8485                if (cpr.launchingApp == null) {
8486                    Slog.w(TAG, "Unable to launch app "
8487                            + cpi.applicationInfo.packageName + "/"
8488                            + cpi.applicationInfo.uid + " for provider "
8489                            + name + ": launching app became null");
8490                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8491                            UserHandle.getUserId(cpi.applicationInfo.uid),
8492                            cpi.applicationInfo.packageName,
8493                            cpi.applicationInfo.uid, name);
8494                    return null;
8495                }
8496                try {
8497                    if (DEBUG_MU) {
8498                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8499                                + cpr.launchingApp);
8500                    }
8501                    if (conn != null) {
8502                        conn.waiting = true;
8503                    }
8504                    cpr.wait();
8505                } catch (InterruptedException ex) {
8506                } finally {
8507                    if (conn != null) {
8508                        conn.waiting = false;
8509                    }
8510                }
8511            }
8512        }
8513        return cpr != null ? cpr.newHolder(conn) : null;
8514    }
8515
8516    @Override
8517    public final ContentProviderHolder getContentProvider(
8518            IApplicationThread caller, String name, int userId, boolean stable) {
8519        enforceNotIsolatedCaller("getContentProvider");
8520        if (caller == null) {
8521            String msg = "null IApplicationThread when getting content provider "
8522                    + name;
8523            Slog.w(TAG, msg);
8524            throw new SecurityException(msg);
8525        }
8526        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8527        // with cross-user grant.
8528        return getContentProviderImpl(caller, name, null, stable, userId);
8529    }
8530
8531    public ContentProviderHolder getContentProviderExternal(
8532            String name, int userId, IBinder token) {
8533        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8534            "Do not have permission in call getContentProviderExternal()");
8535        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8536                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8537        return getContentProviderExternalUnchecked(name, token, userId);
8538    }
8539
8540    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8541            IBinder token, int userId) {
8542        return getContentProviderImpl(null, name, token, true, userId);
8543    }
8544
8545    /**
8546     * Drop a content provider from a ProcessRecord's bookkeeping
8547     */
8548    public void removeContentProvider(IBinder connection, boolean stable) {
8549        enforceNotIsolatedCaller("removeContentProvider");
8550        long ident = Binder.clearCallingIdentity();
8551        try {
8552            synchronized (this) {
8553                ContentProviderConnection conn;
8554                try {
8555                    conn = (ContentProviderConnection)connection;
8556                } catch (ClassCastException e) {
8557                    String msg ="removeContentProvider: " + connection
8558                            + " not a ContentProviderConnection";
8559                    Slog.w(TAG, msg);
8560                    throw new IllegalArgumentException(msg);
8561                }
8562                if (conn == null) {
8563                    throw new NullPointerException("connection is null");
8564                }
8565                if (decProviderCountLocked(conn, null, null, stable)) {
8566                    updateOomAdjLocked();
8567                }
8568            }
8569        } finally {
8570            Binder.restoreCallingIdentity(ident);
8571        }
8572    }
8573
8574    public void removeContentProviderExternal(String name, IBinder token) {
8575        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8576            "Do not have permission in call removeContentProviderExternal()");
8577        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8578    }
8579
8580    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8581        synchronized (this) {
8582            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8583            if(cpr == null) {
8584                //remove from mProvidersByClass
8585                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8586                return;
8587            }
8588
8589            //update content provider record entry info
8590            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8591            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8592            if (localCpr.hasExternalProcessHandles()) {
8593                if (localCpr.removeExternalProcessHandleLocked(token)) {
8594                    updateOomAdjLocked();
8595                } else {
8596                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8597                            + " with no external reference for token: "
8598                            + token + ".");
8599                }
8600            } else {
8601                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8602                        + " with no external references.");
8603            }
8604        }
8605    }
8606
8607    public final void publishContentProviders(IApplicationThread caller,
8608            List<ContentProviderHolder> providers) {
8609        if (providers == null) {
8610            return;
8611        }
8612
8613        enforceNotIsolatedCaller("publishContentProviders");
8614        synchronized (this) {
8615            final ProcessRecord r = getRecordForAppLocked(caller);
8616            if (DEBUG_MU)
8617                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8618            if (r == null) {
8619                throw new SecurityException(
8620                        "Unable to find app for caller " + caller
8621                      + " (pid=" + Binder.getCallingPid()
8622                      + ") when publishing content providers");
8623            }
8624
8625            final long origId = Binder.clearCallingIdentity();
8626
8627            final int N = providers.size();
8628            for (int i=0; i<N; i++) {
8629                ContentProviderHolder src = providers.get(i);
8630                if (src == null || src.info == null || src.provider == null) {
8631                    continue;
8632                }
8633                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8634                if (DEBUG_MU)
8635                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8636                if (dst != null) {
8637                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8638                    mProviderMap.putProviderByClass(comp, dst);
8639                    String names[] = dst.info.authority.split(";");
8640                    for (int j = 0; j < names.length; j++) {
8641                        mProviderMap.putProviderByName(names[j], dst);
8642                    }
8643
8644                    int NL = mLaunchingProviders.size();
8645                    int j;
8646                    for (j=0; j<NL; j++) {
8647                        if (mLaunchingProviders.get(j) == dst) {
8648                            mLaunchingProviders.remove(j);
8649                            j--;
8650                            NL--;
8651                        }
8652                    }
8653                    synchronized (dst) {
8654                        dst.provider = src.provider;
8655                        dst.proc = r;
8656                        dst.notifyAll();
8657                    }
8658                    updateOomAdjLocked(r);
8659                }
8660            }
8661
8662            Binder.restoreCallingIdentity(origId);
8663        }
8664    }
8665
8666    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8667        ContentProviderConnection conn;
8668        try {
8669            conn = (ContentProviderConnection)connection;
8670        } catch (ClassCastException e) {
8671            String msg ="refContentProvider: " + connection
8672                    + " not a ContentProviderConnection";
8673            Slog.w(TAG, msg);
8674            throw new IllegalArgumentException(msg);
8675        }
8676        if (conn == null) {
8677            throw new NullPointerException("connection is null");
8678        }
8679
8680        synchronized (this) {
8681            if (stable > 0) {
8682                conn.numStableIncs += stable;
8683            }
8684            stable = conn.stableCount + stable;
8685            if (stable < 0) {
8686                throw new IllegalStateException("stableCount < 0: " + stable);
8687            }
8688
8689            if (unstable > 0) {
8690                conn.numUnstableIncs += unstable;
8691            }
8692            unstable = conn.unstableCount + unstable;
8693            if (unstable < 0) {
8694                throw new IllegalStateException("unstableCount < 0: " + unstable);
8695            }
8696
8697            if ((stable+unstable) <= 0) {
8698                throw new IllegalStateException("ref counts can't go to zero here: stable="
8699                        + stable + " unstable=" + unstable);
8700            }
8701            conn.stableCount = stable;
8702            conn.unstableCount = unstable;
8703            return !conn.dead;
8704        }
8705    }
8706
8707    public void unstableProviderDied(IBinder connection) {
8708        ContentProviderConnection conn;
8709        try {
8710            conn = (ContentProviderConnection)connection;
8711        } catch (ClassCastException e) {
8712            String msg ="refContentProvider: " + connection
8713                    + " not a ContentProviderConnection";
8714            Slog.w(TAG, msg);
8715            throw new IllegalArgumentException(msg);
8716        }
8717        if (conn == null) {
8718            throw new NullPointerException("connection is null");
8719        }
8720
8721        // Safely retrieve the content provider associated with the connection.
8722        IContentProvider provider;
8723        synchronized (this) {
8724            provider = conn.provider.provider;
8725        }
8726
8727        if (provider == null) {
8728            // Um, yeah, we're way ahead of you.
8729            return;
8730        }
8731
8732        // Make sure the caller is being honest with us.
8733        if (provider.asBinder().pingBinder()) {
8734            // Er, no, still looks good to us.
8735            synchronized (this) {
8736                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8737                        + " says " + conn + " died, but we don't agree");
8738                return;
8739            }
8740        }
8741
8742        // Well look at that!  It's dead!
8743        synchronized (this) {
8744            if (conn.provider.provider != provider) {
8745                // But something changed...  good enough.
8746                return;
8747            }
8748
8749            ProcessRecord proc = conn.provider.proc;
8750            if (proc == null || proc.thread == null) {
8751                // Seems like the process is already cleaned up.
8752                return;
8753            }
8754
8755            // As far as we're concerned, this is just like receiving a
8756            // death notification...  just a bit prematurely.
8757            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8758                    + ") early provider death");
8759            final long ident = Binder.clearCallingIdentity();
8760            try {
8761                appDiedLocked(proc, proc.pid, proc.thread);
8762            } finally {
8763                Binder.restoreCallingIdentity(ident);
8764            }
8765        }
8766    }
8767
8768    @Override
8769    public void appNotRespondingViaProvider(IBinder connection) {
8770        enforceCallingPermission(
8771                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8772
8773        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8774        if (conn == null) {
8775            Slog.w(TAG, "ContentProviderConnection is null");
8776            return;
8777        }
8778
8779        final ProcessRecord host = conn.provider.proc;
8780        if (host == null) {
8781            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8782            return;
8783        }
8784
8785        final long token = Binder.clearCallingIdentity();
8786        try {
8787            appNotResponding(host, null, null, false, "ContentProvider not responding");
8788        } finally {
8789            Binder.restoreCallingIdentity(token);
8790        }
8791    }
8792
8793    public final void installSystemProviders() {
8794        List<ProviderInfo> providers;
8795        synchronized (this) {
8796            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8797            providers = generateApplicationProvidersLocked(app);
8798            if (providers != null) {
8799                for (int i=providers.size()-1; i>=0; i--) {
8800                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8801                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8802                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8803                                + ": not system .apk");
8804                        providers.remove(i);
8805                    }
8806                }
8807            }
8808        }
8809        if (providers != null) {
8810            mSystemThread.installSystemProviders(providers);
8811        }
8812
8813        mCoreSettingsObserver = new CoreSettingsObserver(this);
8814
8815        //mUsageStatsService.monitorPackages();
8816    }
8817
8818    /**
8819     * Allows app to retrieve the MIME type of a URI without having permission
8820     * to access its content provider.
8821     *
8822     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8823     *
8824     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8825     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8826     */
8827    public String getProviderMimeType(Uri uri, int userId) {
8828        enforceNotIsolatedCaller("getProviderMimeType");
8829        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8830                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8831        final String name = uri.getAuthority();
8832        final long ident = Binder.clearCallingIdentity();
8833        ContentProviderHolder holder = null;
8834
8835        try {
8836            holder = getContentProviderExternalUnchecked(name, null, userId);
8837            if (holder != null) {
8838                return holder.provider.getType(uri);
8839            }
8840        } catch (RemoteException e) {
8841            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8842            return null;
8843        } finally {
8844            if (holder != null) {
8845                removeContentProviderExternalUnchecked(name, null, userId);
8846            }
8847            Binder.restoreCallingIdentity(ident);
8848        }
8849
8850        return null;
8851    }
8852
8853    // =========================================================
8854    // GLOBAL MANAGEMENT
8855    // =========================================================
8856
8857    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8858            boolean isolated) {
8859        String proc = customProcess != null ? customProcess : info.processName;
8860        BatteryStatsImpl.Uid.Proc ps = null;
8861        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8862        int uid = info.uid;
8863        if (isolated) {
8864            int userId = UserHandle.getUserId(uid);
8865            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8866            while (true) {
8867                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8868                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8869                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8870                }
8871                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8872                mNextIsolatedProcessUid++;
8873                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8874                    // No process for this uid, use it.
8875                    break;
8876                }
8877                stepsLeft--;
8878                if (stepsLeft <= 0) {
8879                    return null;
8880                }
8881            }
8882        }
8883        return new ProcessRecord(stats, info, proc, uid);
8884    }
8885
8886    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8887            String abiOverride) {
8888        ProcessRecord app;
8889        if (!isolated) {
8890            app = getProcessRecordLocked(info.processName, info.uid, true);
8891        } else {
8892            app = null;
8893        }
8894
8895        if (app == null) {
8896            app = newProcessRecordLocked(info, null, isolated);
8897            mProcessNames.put(info.processName, app.uid, app);
8898            if (isolated) {
8899                mIsolatedProcesses.put(app.uid, app);
8900            }
8901            updateLruProcessLocked(app, false, null);
8902            updateOomAdjLocked();
8903        }
8904
8905        // This package really, really can not be stopped.
8906        try {
8907            AppGlobals.getPackageManager().setPackageStoppedState(
8908                    info.packageName, false, UserHandle.getUserId(app.uid));
8909        } catch (RemoteException e) {
8910        } catch (IllegalArgumentException e) {
8911            Slog.w(TAG, "Failed trying to unstop package "
8912                    + info.packageName + ": " + e);
8913        }
8914
8915        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8916                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8917            app.persistent = true;
8918            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8919        }
8920        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8921            mPersistentStartingProcesses.add(app);
8922            startProcessLocked(app, "added application", app.processName,
8923                    abiOverride);
8924        }
8925
8926        return app;
8927    }
8928
8929    public void unhandledBack() {
8930        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8931                "unhandledBack()");
8932
8933        synchronized(this) {
8934            final long origId = Binder.clearCallingIdentity();
8935            try {
8936                getFocusedStack().unhandledBackLocked();
8937            } finally {
8938                Binder.restoreCallingIdentity(origId);
8939            }
8940        }
8941    }
8942
8943    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8944        enforceNotIsolatedCaller("openContentUri");
8945        final int userId = UserHandle.getCallingUserId();
8946        String name = uri.getAuthority();
8947        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8948        ParcelFileDescriptor pfd = null;
8949        if (cph != null) {
8950            // We record the binder invoker's uid in thread-local storage before
8951            // going to the content provider to open the file.  Later, in the code
8952            // that handles all permissions checks, we look for this uid and use
8953            // that rather than the Activity Manager's own uid.  The effect is that
8954            // we do the check against the caller's permissions even though it looks
8955            // to the content provider like the Activity Manager itself is making
8956            // the request.
8957            sCallerIdentity.set(new Identity(
8958                    Binder.getCallingPid(), Binder.getCallingUid()));
8959            try {
8960                pfd = cph.provider.openFile(null, uri, "r", null);
8961            } catch (FileNotFoundException e) {
8962                // do nothing; pfd will be returned null
8963            } finally {
8964                // Ensure that whatever happens, we clean up the identity state
8965                sCallerIdentity.remove();
8966            }
8967
8968            // We've got the fd now, so we're done with the provider.
8969            removeContentProviderExternalUnchecked(name, null, userId);
8970        } else {
8971            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8972        }
8973        return pfd;
8974    }
8975
8976    // Actually is sleeping or shutting down or whatever else in the future
8977    // is an inactive state.
8978    public boolean isSleepingOrShuttingDown() {
8979        return mSleeping || mShuttingDown;
8980    }
8981
8982    public boolean isSleeping() {
8983        return mSleeping;
8984    }
8985
8986    void goingToSleep() {
8987        synchronized(this) {
8988            mWentToSleep = true;
8989            updateEventDispatchingLocked();
8990            goToSleepIfNeededLocked();
8991        }
8992    }
8993
8994    void finishRunningVoiceLocked() {
8995        if (mRunningVoice) {
8996            mRunningVoice = false;
8997            goToSleepIfNeededLocked();
8998        }
8999    }
9000
9001    void goToSleepIfNeededLocked() {
9002        if (mWentToSleep && !mRunningVoice) {
9003            if (!mSleeping) {
9004                mSleeping = true;
9005                mStackSupervisor.goingToSleepLocked();
9006
9007                // Initialize the wake times of all processes.
9008                checkExcessivePowerUsageLocked(false);
9009                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9010                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9011                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9012            }
9013        }
9014    }
9015
9016    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9017        mTaskPersister.notify(task, flush);
9018    }
9019
9020    @Override
9021    public boolean shutdown(int timeout) {
9022        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9023                != PackageManager.PERMISSION_GRANTED) {
9024            throw new SecurityException("Requires permission "
9025                    + android.Manifest.permission.SHUTDOWN);
9026        }
9027
9028        boolean timedout = false;
9029
9030        synchronized(this) {
9031            mShuttingDown = true;
9032            updateEventDispatchingLocked();
9033            timedout = mStackSupervisor.shutdownLocked(timeout);
9034        }
9035
9036        mAppOpsService.shutdown();
9037        if (mUsageStatsService != null) {
9038            mUsageStatsService.prepareShutdown();
9039        }
9040        mBatteryStatsService.shutdown();
9041        synchronized (this) {
9042            mProcessStats.shutdownLocked();
9043        }
9044        notifyTaskPersisterLocked(null, true);
9045
9046        return timedout;
9047    }
9048
9049    public final void activitySlept(IBinder token) {
9050        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9051
9052        final long origId = Binder.clearCallingIdentity();
9053
9054        synchronized (this) {
9055            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9056            if (r != null) {
9057                mStackSupervisor.activitySleptLocked(r);
9058            }
9059        }
9060
9061        Binder.restoreCallingIdentity(origId);
9062    }
9063
9064    void logLockScreen(String msg) {
9065        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9066                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9067                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9068                mStackSupervisor.mDismissKeyguardOnNextActivity);
9069    }
9070
9071    private void comeOutOfSleepIfNeededLocked() {
9072        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9073            if (mSleeping) {
9074                mSleeping = false;
9075                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9076            }
9077        }
9078    }
9079
9080    void wakingUp() {
9081        synchronized(this) {
9082            mWentToSleep = false;
9083            updateEventDispatchingLocked();
9084            comeOutOfSleepIfNeededLocked();
9085        }
9086    }
9087
9088    void startRunningVoiceLocked() {
9089        if (!mRunningVoice) {
9090            mRunningVoice = true;
9091            comeOutOfSleepIfNeededLocked();
9092        }
9093    }
9094
9095    private void updateEventDispatchingLocked() {
9096        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9097    }
9098
9099    public void setLockScreenShown(boolean shown) {
9100        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9101                != PackageManager.PERMISSION_GRANTED) {
9102            throw new SecurityException("Requires permission "
9103                    + android.Manifest.permission.DEVICE_POWER);
9104        }
9105
9106        synchronized(this) {
9107            long ident = Binder.clearCallingIdentity();
9108            try {
9109                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9110                mLockScreenShown = shown;
9111                comeOutOfSleepIfNeededLocked();
9112            } finally {
9113                Binder.restoreCallingIdentity(ident);
9114            }
9115        }
9116    }
9117
9118    @Override
9119    public void stopAppSwitches() {
9120        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9121                != PackageManager.PERMISSION_GRANTED) {
9122            throw new SecurityException("Requires permission "
9123                    + android.Manifest.permission.STOP_APP_SWITCHES);
9124        }
9125
9126        synchronized(this) {
9127            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9128                    + APP_SWITCH_DELAY_TIME;
9129            mDidAppSwitch = false;
9130            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9131            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9132            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9133        }
9134    }
9135
9136    public void resumeAppSwitches() {
9137        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9138                != PackageManager.PERMISSION_GRANTED) {
9139            throw new SecurityException("Requires permission "
9140                    + android.Manifest.permission.STOP_APP_SWITCHES);
9141        }
9142
9143        synchronized(this) {
9144            // Note that we don't execute any pending app switches... we will
9145            // let those wait until either the timeout, or the next start
9146            // activity request.
9147            mAppSwitchesAllowedTime = 0;
9148        }
9149    }
9150
9151    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9152            String name) {
9153        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9154            return true;
9155        }
9156
9157        final int perm = checkComponentPermission(
9158                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9159                callingUid, -1, true);
9160        if (perm == PackageManager.PERMISSION_GRANTED) {
9161            return true;
9162        }
9163
9164        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9165        return false;
9166    }
9167
9168    public void setDebugApp(String packageName, boolean waitForDebugger,
9169            boolean persistent) {
9170        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9171                "setDebugApp()");
9172
9173        long ident = Binder.clearCallingIdentity();
9174        try {
9175            // Note that this is not really thread safe if there are multiple
9176            // callers into it at the same time, but that's not a situation we
9177            // care about.
9178            if (persistent) {
9179                final ContentResolver resolver = mContext.getContentResolver();
9180                Settings.Global.putString(
9181                    resolver, Settings.Global.DEBUG_APP,
9182                    packageName);
9183                Settings.Global.putInt(
9184                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9185                    waitForDebugger ? 1 : 0);
9186            }
9187
9188            synchronized (this) {
9189                if (!persistent) {
9190                    mOrigDebugApp = mDebugApp;
9191                    mOrigWaitForDebugger = mWaitForDebugger;
9192                }
9193                mDebugApp = packageName;
9194                mWaitForDebugger = waitForDebugger;
9195                mDebugTransient = !persistent;
9196                if (packageName != null) {
9197                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9198                            false, UserHandle.USER_ALL, "set debug app");
9199                }
9200            }
9201        } finally {
9202            Binder.restoreCallingIdentity(ident);
9203        }
9204    }
9205
9206    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9207        synchronized (this) {
9208            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9209            if (!isDebuggable) {
9210                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9211                    throw new SecurityException("Process not debuggable: " + app.packageName);
9212                }
9213            }
9214
9215            mOpenGlTraceApp = processName;
9216        }
9217    }
9218
9219    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9220            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9221        synchronized (this) {
9222            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9223            if (!isDebuggable) {
9224                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9225                    throw new SecurityException("Process not debuggable: " + app.packageName);
9226                }
9227            }
9228            mProfileApp = processName;
9229            mProfileFile = profileFile;
9230            if (mProfileFd != null) {
9231                try {
9232                    mProfileFd.close();
9233                } catch (IOException e) {
9234                }
9235                mProfileFd = null;
9236            }
9237            mProfileFd = profileFd;
9238            mProfileType = 0;
9239            mAutoStopProfiler = autoStopProfiler;
9240        }
9241    }
9242
9243    @Override
9244    public void setAlwaysFinish(boolean enabled) {
9245        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9246                "setAlwaysFinish()");
9247
9248        Settings.Global.putInt(
9249                mContext.getContentResolver(),
9250                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9251
9252        synchronized (this) {
9253            mAlwaysFinishActivities = enabled;
9254        }
9255    }
9256
9257    @Override
9258    public void setActivityController(IActivityController controller) {
9259        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9260                "setActivityController()");
9261        synchronized (this) {
9262            mController = controller;
9263            Watchdog.getInstance().setActivityController(controller);
9264        }
9265    }
9266
9267    @Override
9268    public void setUserIsMonkey(boolean userIsMonkey) {
9269        synchronized (this) {
9270            synchronized (mPidsSelfLocked) {
9271                final int callingPid = Binder.getCallingPid();
9272                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9273                if (precessRecord == null) {
9274                    throw new SecurityException("Unknown process: " + callingPid);
9275                }
9276                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9277                    throw new SecurityException("Only an instrumentation process "
9278                            + "with a UiAutomation can call setUserIsMonkey");
9279                }
9280            }
9281            mUserIsMonkey = userIsMonkey;
9282        }
9283    }
9284
9285    @Override
9286    public boolean isUserAMonkey() {
9287        synchronized (this) {
9288            // If there is a controller also implies the user is a monkey.
9289            return (mUserIsMonkey || mController != null);
9290        }
9291    }
9292
9293    public void requestBugReport() {
9294        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9295        SystemProperties.set("ctl.start", "bugreport");
9296    }
9297
9298    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9299        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9300    }
9301
9302    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9303        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9304            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9305        }
9306        return KEY_DISPATCHING_TIMEOUT;
9307    }
9308
9309    @Override
9310    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9311        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9312                != PackageManager.PERMISSION_GRANTED) {
9313            throw new SecurityException("Requires permission "
9314                    + android.Manifest.permission.FILTER_EVENTS);
9315        }
9316        ProcessRecord proc;
9317        long timeout;
9318        synchronized (this) {
9319            synchronized (mPidsSelfLocked) {
9320                proc = mPidsSelfLocked.get(pid);
9321            }
9322            timeout = getInputDispatchingTimeoutLocked(proc);
9323        }
9324
9325        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9326            return -1;
9327        }
9328
9329        return timeout;
9330    }
9331
9332    /**
9333     * Handle input dispatching timeouts.
9334     * Returns whether input dispatching should be aborted or not.
9335     */
9336    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9337            final ActivityRecord activity, final ActivityRecord parent,
9338            final boolean aboveSystem, String reason) {
9339        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9340                != PackageManager.PERMISSION_GRANTED) {
9341            throw new SecurityException("Requires permission "
9342                    + android.Manifest.permission.FILTER_EVENTS);
9343        }
9344
9345        final String annotation;
9346        if (reason == null) {
9347            annotation = "Input dispatching timed out";
9348        } else {
9349            annotation = "Input dispatching timed out (" + reason + ")";
9350        }
9351
9352        if (proc != null) {
9353            synchronized (this) {
9354                if (proc.debugging) {
9355                    return false;
9356                }
9357
9358                if (mDidDexOpt) {
9359                    // Give more time since we were dexopting.
9360                    mDidDexOpt = false;
9361                    return false;
9362                }
9363
9364                if (proc.instrumentationClass != null) {
9365                    Bundle info = new Bundle();
9366                    info.putString("shortMsg", "keyDispatchingTimedOut");
9367                    info.putString("longMsg", annotation);
9368                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9369                    return true;
9370                }
9371            }
9372            mHandler.post(new Runnable() {
9373                @Override
9374                public void run() {
9375                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9376                }
9377            });
9378        }
9379
9380        return true;
9381    }
9382
9383    public Bundle getAssistContextExtras(int requestType) {
9384        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9385                "getAssistContextExtras()");
9386        PendingAssistExtras pae;
9387        Bundle extras = new Bundle();
9388        synchronized (this) {
9389            ActivityRecord activity = getFocusedStack().mResumedActivity;
9390            if (activity == null) {
9391                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9392                return null;
9393            }
9394            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9395            if (activity.app == null || activity.app.thread == null) {
9396                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9397                return extras;
9398            }
9399            if (activity.app.pid == Binder.getCallingPid()) {
9400                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9401                return extras;
9402            }
9403            pae = new PendingAssistExtras(activity);
9404            try {
9405                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9406                        requestType);
9407                mPendingAssistExtras.add(pae);
9408                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9409            } catch (RemoteException e) {
9410                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9411                return extras;
9412            }
9413        }
9414        synchronized (pae) {
9415            while (!pae.haveResult) {
9416                try {
9417                    pae.wait();
9418                } catch (InterruptedException e) {
9419                }
9420            }
9421            if (pae.result != null) {
9422                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9423            }
9424        }
9425        synchronized (this) {
9426            mPendingAssistExtras.remove(pae);
9427            mHandler.removeCallbacks(pae);
9428        }
9429        return extras;
9430    }
9431
9432    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9433        PendingAssistExtras pae = (PendingAssistExtras)token;
9434        synchronized (pae) {
9435            pae.result = extras;
9436            pae.haveResult = true;
9437            pae.notifyAll();
9438        }
9439    }
9440
9441    public void registerProcessObserver(IProcessObserver observer) {
9442        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9443                "registerProcessObserver()");
9444        synchronized (this) {
9445            mProcessObservers.register(observer);
9446        }
9447    }
9448
9449    @Override
9450    public void unregisterProcessObserver(IProcessObserver observer) {
9451        synchronized (this) {
9452            mProcessObservers.unregister(observer);
9453        }
9454    }
9455
9456    @Override
9457    public boolean convertFromTranslucent(IBinder token) {
9458        final long origId = Binder.clearCallingIdentity();
9459        try {
9460            synchronized (this) {
9461                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9462                if (r == null) {
9463                    return false;
9464                }
9465                if (r.changeWindowTranslucency(true)) {
9466                    mWindowManager.setAppFullscreen(token, true);
9467                    r.task.stack.releaseMediaResources();
9468                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9469                    return true;
9470                }
9471                return false;
9472            }
9473        } finally {
9474            Binder.restoreCallingIdentity(origId);
9475        }
9476    }
9477
9478    @Override
9479    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9480        final long origId = Binder.clearCallingIdentity();
9481        try {
9482            synchronized (this) {
9483                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9484                if (r == null) {
9485                    return false;
9486                }
9487                if (r.changeWindowTranslucency(false)) {
9488                    r.task.stack.convertToTranslucent(r, options);
9489                    mWindowManager.setAppFullscreen(token, false);
9490                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9491                    return true;
9492                } else {
9493                    r.task.stack.mReturningActivityOptions = options;
9494                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9495                    return false;
9496                }
9497            }
9498        } finally {
9499            Binder.restoreCallingIdentity(origId);
9500        }
9501    }
9502
9503    @Override
9504    public boolean setMediaPlaying(IBinder token, boolean playing) {
9505        final long origId = Binder.clearCallingIdentity();
9506        try {
9507            synchronized (this) {
9508                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9509                if (r != null) {
9510                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9511                }
9512            }
9513            return false;
9514        } finally {
9515            Binder.restoreCallingIdentity(origId);
9516        }
9517    }
9518
9519    @Override
9520    public boolean isBackgroundMediaPlaying(IBinder token) {
9521        final long origId = Binder.clearCallingIdentity();
9522        try {
9523            synchronized (this) {
9524                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9525                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9526                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9527                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9528                return playing;
9529            }
9530        } finally {
9531            Binder.restoreCallingIdentity(origId);
9532        }
9533    }
9534
9535    @Override
9536    public ActivityOptions getActivityOptions(IBinder token) {
9537        final long origId = Binder.clearCallingIdentity();
9538        try {
9539            synchronized (this) {
9540                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9541                if (r != null) {
9542                    final ActivityOptions activityOptions = r.pendingOptions;
9543                    r.pendingOptions = null;
9544                    return activityOptions;
9545                }
9546                return null;
9547            }
9548        } finally {
9549            Binder.restoreCallingIdentity(origId);
9550        }
9551    }
9552
9553    @Override
9554    public void setImmersive(IBinder token, boolean immersive) {
9555        synchronized(this) {
9556            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9557            if (r == null) {
9558                throw new IllegalArgumentException();
9559            }
9560            r.immersive = immersive;
9561
9562            // update associated state if we're frontmost
9563            if (r == mFocusedActivity) {
9564                if (DEBUG_IMMERSIVE) {
9565                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9566                }
9567                applyUpdateLockStateLocked(r);
9568            }
9569        }
9570    }
9571
9572    @Override
9573    public boolean isImmersive(IBinder token) {
9574        synchronized (this) {
9575            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9576            if (r == null) {
9577                throw new IllegalArgumentException();
9578            }
9579            return r.immersive;
9580        }
9581    }
9582
9583    public boolean isTopActivityImmersive() {
9584        enforceNotIsolatedCaller("startActivity");
9585        synchronized (this) {
9586            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9587            return (r != null) ? r.immersive : false;
9588        }
9589    }
9590
9591    @Override
9592    public boolean isTopOfTask(IBinder token) {
9593        synchronized (this) {
9594            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9595            if (r == null) {
9596                throw new IllegalArgumentException();
9597            }
9598            return r.task.getTopActivity() == r;
9599        }
9600    }
9601
9602    public final void enterSafeMode() {
9603        synchronized(this) {
9604            // It only makes sense to do this before the system is ready
9605            // and started launching other packages.
9606            if (!mSystemReady) {
9607                try {
9608                    AppGlobals.getPackageManager().enterSafeMode();
9609                } catch (RemoteException e) {
9610                }
9611            }
9612
9613            mSafeMode = true;
9614        }
9615    }
9616
9617    public final void showSafeModeOverlay() {
9618        View v = LayoutInflater.from(mContext).inflate(
9619                com.android.internal.R.layout.safe_mode, null);
9620        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9621        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9622        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9623        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9624        lp.gravity = Gravity.BOTTOM | Gravity.START;
9625        lp.format = v.getBackground().getOpacity();
9626        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9627                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9628        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9629        ((WindowManager)mContext.getSystemService(
9630                Context.WINDOW_SERVICE)).addView(v, lp);
9631    }
9632
9633    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9634        if (!(sender instanceof PendingIntentRecord)) {
9635            return;
9636        }
9637        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9638        synchronized (stats) {
9639            if (mBatteryStatsService.isOnBattery()) {
9640                mBatteryStatsService.enforceCallingPermission();
9641                PendingIntentRecord rec = (PendingIntentRecord)sender;
9642                int MY_UID = Binder.getCallingUid();
9643                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9644                BatteryStatsImpl.Uid.Pkg pkg =
9645                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9646                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9647                pkg.incWakeupsLocked();
9648            }
9649        }
9650    }
9651
9652    public boolean killPids(int[] pids, String pReason, boolean secure) {
9653        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9654            throw new SecurityException("killPids only available to the system");
9655        }
9656        String reason = (pReason == null) ? "Unknown" : pReason;
9657        // XXX Note: don't acquire main activity lock here, because the window
9658        // manager calls in with its locks held.
9659
9660        boolean killed = false;
9661        synchronized (mPidsSelfLocked) {
9662            int[] types = new int[pids.length];
9663            int worstType = 0;
9664            for (int i=0; i<pids.length; i++) {
9665                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9666                if (proc != null) {
9667                    int type = proc.setAdj;
9668                    types[i] = type;
9669                    if (type > worstType) {
9670                        worstType = type;
9671                    }
9672                }
9673            }
9674
9675            // If the worst oom_adj is somewhere in the cached proc LRU range,
9676            // then constrain it so we will kill all cached procs.
9677            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9678                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9679                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9680            }
9681
9682            // If this is not a secure call, don't let it kill processes that
9683            // are important.
9684            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9685                worstType = ProcessList.SERVICE_ADJ;
9686            }
9687
9688            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9689            for (int i=0; i<pids.length; i++) {
9690                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9691                if (proc == null) {
9692                    continue;
9693                }
9694                int adj = proc.setAdj;
9695                if (adj >= worstType && !proc.killedByAm) {
9696                    killUnneededProcessLocked(proc, reason);
9697                    killed = true;
9698                }
9699            }
9700        }
9701        return killed;
9702    }
9703
9704    @Override
9705    public void killUid(int uid, String reason) {
9706        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9707            throw new SecurityException("killUid only available to the system");
9708        }
9709        synchronized (this) {
9710            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9711                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9712                    reason != null ? reason : "kill uid");
9713        }
9714    }
9715
9716    @Override
9717    public boolean killProcessesBelowForeground(String reason) {
9718        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9719            throw new SecurityException("killProcessesBelowForeground() only available to system");
9720        }
9721
9722        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9723    }
9724
9725    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9726        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9727            throw new SecurityException("killProcessesBelowAdj() only available to system");
9728        }
9729
9730        boolean killed = false;
9731        synchronized (mPidsSelfLocked) {
9732            final int size = mPidsSelfLocked.size();
9733            for (int i = 0; i < size; i++) {
9734                final int pid = mPidsSelfLocked.keyAt(i);
9735                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9736                if (proc == null) continue;
9737
9738                final int adj = proc.setAdj;
9739                if (adj > belowAdj && !proc.killedByAm) {
9740                    killUnneededProcessLocked(proc, reason);
9741                    killed = true;
9742                }
9743            }
9744        }
9745        return killed;
9746    }
9747
9748    @Override
9749    public void hang(final IBinder who, boolean allowRestart) {
9750        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9751                != PackageManager.PERMISSION_GRANTED) {
9752            throw new SecurityException("Requires permission "
9753                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9754        }
9755
9756        final IBinder.DeathRecipient death = new DeathRecipient() {
9757            @Override
9758            public void binderDied() {
9759                synchronized (this) {
9760                    notifyAll();
9761                }
9762            }
9763        };
9764
9765        try {
9766            who.linkToDeath(death, 0);
9767        } catch (RemoteException e) {
9768            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9769            return;
9770        }
9771
9772        synchronized (this) {
9773            Watchdog.getInstance().setAllowRestart(allowRestart);
9774            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9775            synchronized (death) {
9776                while (who.isBinderAlive()) {
9777                    try {
9778                        death.wait();
9779                    } catch (InterruptedException e) {
9780                    }
9781                }
9782            }
9783            Watchdog.getInstance().setAllowRestart(true);
9784        }
9785    }
9786
9787    @Override
9788    public void restart() {
9789        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9790                != PackageManager.PERMISSION_GRANTED) {
9791            throw new SecurityException("Requires permission "
9792                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9793        }
9794
9795        Log.i(TAG, "Sending shutdown broadcast...");
9796
9797        BroadcastReceiver br = new BroadcastReceiver() {
9798            @Override public void onReceive(Context context, Intent intent) {
9799                // Now the broadcast is done, finish up the low-level shutdown.
9800                Log.i(TAG, "Shutting down activity manager...");
9801                shutdown(10000);
9802                Log.i(TAG, "Shutdown complete, restarting!");
9803                Process.killProcess(Process.myPid());
9804                System.exit(10);
9805            }
9806        };
9807
9808        // First send the high-level shut down broadcast.
9809        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9810        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9811        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9812        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9813        mContext.sendOrderedBroadcastAsUser(intent,
9814                UserHandle.ALL, null, br, mHandler, 0, null, null);
9815        */
9816        br.onReceive(mContext, intent);
9817    }
9818
9819    private long getLowRamTimeSinceIdle(long now) {
9820        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9821    }
9822
9823    @Override
9824    public void performIdleMaintenance() {
9825        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9826                != PackageManager.PERMISSION_GRANTED) {
9827            throw new SecurityException("Requires permission "
9828                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9829        }
9830
9831        synchronized (this) {
9832            final long now = SystemClock.uptimeMillis();
9833            final long timeSinceLastIdle = now - mLastIdleTime;
9834            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9835            mLastIdleTime = now;
9836            mLowRamTimeSinceLastIdle = 0;
9837            if (mLowRamStartTime != 0) {
9838                mLowRamStartTime = now;
9839            }
9840
9841            StringBuilder sb = new StringBuilder(128);
9842            sb.append("Idle maintenance over ");
9843            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9844            sb.append(" low RAM for ");
9845            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9846            Slog.i(TAG, sb.toString());
9847
9848            // If at least 1/3 of our time since the last idle period has been spent
9849            // with RAM low, then we want to kill processes.
9850            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9851
9852            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9853                ProcessRecord proc = mLruProcesses.get(i);
9854                if (proc.notCachedSinceIdle) {
9855                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9856                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9857                        if (doKilling && proc.initialIdlePss != 0
9858                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9859                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9860                                    + " from " + proc.initialIdlePss + ")");
9861                        }
9862                    }
9863                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9864                    proc.notCachedSinceIdle = true;
9865                    proc.initialIdlePss = 0;
9866                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9867                            isSleeping(), now);
9868                }
9869            }
9870
9871            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9872            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9873        }
9874    }
9875
9876    private void retrieveSettings() {
9877        final ContentResolver resolver = mContext.getContentResolver();
9878        String debugApp = Settings.Global.getString(
9879            resolver, Settings.Global.DEBUG_APP);
9880        boolean waitForDebugger = Settings.Global.getInt(
9881            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9882        boolean alwaysFinishActivities = Settings.Global.getInt(
9883            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9884        boolean forceRtl = Settings.Global.getInt(
9885                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9886        // Transfer any global setting for forcing RTL layout, into a System Property
9887        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9888
9889        Configuration configuration = new Configuration();
9890        Settings.System.getConfiguration(resolver, configuration);
9891        if (forceRtl) {
9892            // This will take care of setting the correct layout direction flags
9893            configuration.setLayoutDirection(configuration.locale);
9894        }
9895
9896        synchronized (this) {
9897            mDebugApp = mOrigDebugApp = debugApp;
9898            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9899            mAlwaysFinishActivities = alwaysFinishActivities;
9900            // This happens before any activities are started, so we can
9901            // change mConfiguration in-place.
9902            updateConfigurationLocked(configuration, null, false, true);
9903            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9904        }
9905    }
9906
9907    public boolean testIsSystemReady() {
9908        // no need to synchronize(this) just to read & return the value
9909        return mSystemReady;
9910    }
9911
9912    private static File getCalledPreBootReceiversFile() {
9913        File dataDir = Environment.getDataDirectory();
9914        File systemDir = new File(dataDir, "system");
9915        File fname = new File(systemDir, "called_pre_boots.dat");
9916        return fname;
9917    }
9918
9919    static final int LAST_DONE_VERSION = 10000;
9920
9921    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9922        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9923        File file = getCalledPreBootReceiversFile();
9924        FileInputStream fis = null;
9925        try {
9926            fis = new FileInputStream(file);
9927            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9928            int fvers = dis.readInt();
9929            if (fvers == LAST_DONE_VERSION) {
9930                String vers = dis.readUTF();
9931                String codename = dis.readUTF();
9932                String build = dis.readUTF();
9933                if (android.os.Build.VERSION.RELEASE.equals(vers)
9934                        && android.os.Build.VERSION.CODENAME.equals(codename)
9935                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9936                    int num = dis.readInt();
9937                    while (num > 0) {
9938                        num--;
9939                        String pkg = dis.readUTF();
9940                        String cls = dis.readUTF();
9941                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9942                    }
9943                }
9944            }
9945        } catch (FileNotFoundException e) {
9946        } catch (IOException e) {
9947            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9948        } finally {
9949            if (fis != null) {
9950                try {
9951                    fis.close();
9952                } catch (IOException e) {
9953                }
9954            }
9955        }
9956        return lastDoneReceivers;
9957    }
9958
9959    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9960        File file = getCalledPreBootReceiversFile();
9961        FileOutputStream fos = null;
9962        DataOutputStream dos = null;
9963        try {
9964            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9965            fos = new FileOutputStream(file);
9966            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9967            dos.writeInt(LAST_DONE_VERSION);
9968            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9969            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9970            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9971            dos.writeInt(list.size());
9972            for (int i=0; i<list.size(); i++) {
9973                dos.writeUTF(list.get(i).getPackageName());
9974                dos.writeUTF(list.get(i).getClassName());
9975            }
9976        } catch (IOException e) {
9977            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9978            file.delete();
9979        } finally {
9980            FileUtils.sync(fos);
9981            if (dos != null) {
9982                try {
9983                    dos.close();
9984                } catch (IOException e) {
9985                    // TODO Auto-generated catch block
9986                    e.printStackTrace();
9987                }
9988            }
9989        }
9990    }
9991
9992    public void systemReady(final Runnable goingCallback) {
9993        synchronized(this) {
9994            if (mSystemReady) {
9995                if (goingCallback != null) goingCallback.run();
9996                return;
9997            }
9998
9999            // Make sure we have the current profile info, since it is needed for
10000            // security checks.
10001            updateCurrentProfileIdsLocked();
10002
10003            if (mRecentTasks == null) {
10004                mRecentTasks = mTaskPersister.restoreTasksLocked();
10005                if (!mRecentTasks.isEmpty()) {
10006                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10007                }
10008                mTaskPersister.startPersisting();
10009            }
10010
10011            // Check to see if there are any update receivers to run.
10012            if (!mDidUpdate) {
10013                if (mWaitingUpdate) {
10014                    return;
10015                }
10016                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10017                List<ResolveInfo> ris = null;
10018                try {
10019                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
10020                            intent, null, 0, 0);
10021                } catch (RemoteException e) {
10022                }
10023                if (ris != null) {
10024                    for (int i=ris.size()-1; i>=0; i--) {
10025                        if ((ris.get(i).activityInfo.applicationInfo.flags
10026                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
10027                            ris.remove(i);
10028                        }
10029                    }
10030                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10031
10032                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10033
10034                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10035                    for (int i=0; i<ris.size(); i++) {
10036                        ActivityInfo ai = ris.get(i).activityInfo;
10037                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10038                        if (lastDoneReceivers.contains(comp)) {
10039                            // We already did the pre boot receiver for this app with the current
10040                            // platform version, so don't do it again...
10041                            ris.remove(i);
10042                            i--;
10043                            // ...however, do keep it as one that has been done, so we don't
10044                            // forget about it when rewriting the file of last done receivers.
10045                            doneReceivers.add(comp);
10046                        }
10047                    }
10048
10049                    final int[] users = getUsersLocked();
10050                    for (int i=0; i<ris.size(); i++) {
10051                        ActivityInfo ai = ris.get(i).activityInfo;
10052                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10053                        doneReceivers.add(comp);
10054                        intent.setComponent(comp);
10055                        for (int j=0; j<users.length; j++) {
10056                            IIntentReceiver finisher = null;
10057                            if (i == ris.size()-1 && j == users.length-1) {
10058                                finisher = new IIntentReceiver.Stub() {
10059                                    public void performReceive(Intent intent, int resultCode,
10060                                            String data, Bundle extras, boolean ordered,
10061                                            boolean sticky, int sendingUser) {
10062                                        // The raw IIntentReceiver interface is called
10063                                        // with the AM lock held, so redispatch to
10064                                        // execute our code without the lock.
10065                                        mHandler.post(new Runnable() {
10066                                            public void run() {
10067                                                synchronized (ActivityManagerService.this) {
10068                                                    mDidUpdate = true;
10069                                                }
10070                                                writeLastDonePreBootReceivers(doneReceivers);
10071                                                showBootMessage(mContext.getText(
10072                                                        R.string.android_upgrading_complete),
10073                                                        false);
10074                                                systemReady(goingCallback);
10075                                            }
10076                                        });
10077                                    }
10078                                };
10079                            }
10080                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
10081                                    + " for user " + users[j]);
10082                            broadcastIntentLocked(null, null, intent, null, finisher,
10083                                    0, null, null, null, AppOpsManager.OP_NONE,
10084                                    true, false, MY_PID, Process.SYSTEM_UID,
10085                                    users[j]);
10086                            if (finisher != null) {
10087                                mWaitingUpdate = true;
10088                            }
10089                        }
10090                    }
10091                }
10092                if (mWaitingUpdate) {
10093                    return;
10094                }
10095                mDidUpdate = true;
10096            }
10097
10098            mAppOpsService.systemReady();
10099            mSystemReady = true;
10100        }
10101
10102        ArrayList<ProcessRecord> procsToKill = null;
10103        synchronized(mPidsSelfLocked) {
10104            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10105                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10106                if (!isAllowedWhileBooting(proc.info)){
10107                    if (procsToKill == null) {
10108                        procsToKill = new ArrayList<ProcessRecord>();
10109                    }
10110                    procsToKill.add(proc);
10111                }
10112            }
10113        }
10114
10115        synchronized(this) {
10116            if (procsToKill != null) {
10117                for (int i=procsToKill.size()-1; i>=0; i--) {
10118                    ProcessRecord proc = procsToKill.get(i);
10119                    Slog.i(TAG, "Removing system update proc: " + proc);
10120                    removeProcessLocked(proc, true, false, "system update done");
10121                }
10122            }
10123
10124            // Now that we have cleaned up any update processes, we
10125            // are ready to start launching real processes and know that
10126            // we won't trample on them any more.
10127            mProcessesReady = true;
10128        }
10129
10130        Slog.i(TAG, "System now ready");
10131        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10132            SystemClock.uptimeMillis());
10133
10134        synchronized(this) {
10135            // Make sure we have no pre-ready processes sitting around.
10136
10137            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10138                ResolveInfo ri = mContext.getPackageManager()
10139                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10140                                STOCK_PM_FLAGS);
10141                CharSequence errorMsg = null;
10142                if (ri != null) {
10143                    ActivityInfo ai = ri.activityInfo;
10144                    ApplicationInfo app = ai.applicationInfo;
10145                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10146                        mTopAction = Intent.ACTION_FACTORY_TEST;
10147                        mTopData = null;
10148                        mTopComponent = new ComponentName(app.packageName,
10149                                ai.name);
10150                    } else {
10151                        errorMsg = mContext.getResources().getText(
10152                                com.android.internal.R.string.factorytest_not_system);
10153                    }
10154                } else {
10155                    errorMsg = mContext.getResources().getText(
10156                            com.android.internal.R.string.factorytest_no_action);
10157                }
10158                if (errorMsg != null) {
10159                    mTopAction = null;
10160                    mTopData = null;
10161                    mTopComponent = null;
10162                    Message msg = Message.obtain();
10163                    msg.what = SHOW_FACTORY_ERROR_MSG;
10164                    msg.getData().putCharSequence("msg", errorMsg);
10165                    mHandler.sendMessage(msg);
10166                }
10167            }
10168        }
10169
10170        retrieveSettings();
10171
10172        synchronized (this) {
10173            readGrantedUriPermissionsLocked();
10174        }
10175
10176        if (goingCallback != null) goingCallback.run();
10177
10178        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10179                Integer.toString(mCurrentUserId), mCurrentUserId);
10180        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10181                Integer.toString(mCurrentUserId), mCurrentUserId);
10182        mSystemServiceManager.startUser(mCurrentUserId);
10183
10184        synchronized (this) {
10185            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10186                try {
10187                    List apps = AppGlobals.getPackageManager().
10188                        getPersistentApplications(STOCK_PM_FLAGS);
10189                    if (apps != null) {
10190                        int N = apps.size();
10191                        int i;
10192                        for (i=0; i<N; i++) {
10193                            ApplicationInfo info
10194                                = (ApplicationInfo)apps.get(i);
10195                            if (info != null &&
10196                                    !info.packageName.equals("android")) {
10197                                addAppLocked(info, false, null /* ABI override */);
10198                            }
10199                        }
10200                    }
10201                } catch (RemoteException ex) {
10202                    // pm is in same process, this will never happen.
10203                }
10204            }
10205
10206            // Start up initial activity.
10207            mBooting = true;
10208
10209            try {
10210                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10211                    Message msg = Message.obtain();
10212                    msg.what = SHOW_UID_ERROR_MSG;
10213                    mHandler.sendMessage(msg);
10214                }
10215            } catch (RemoteException e) {
10216            }
10217
10218            long ident = Binder.clearCallingIdentity();
10219            try {
10220                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10221                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10222                        | Intent.FLAG_RECEIVER_FOREGROUND);
10223                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10224                broadcastIntentLocked(null, null, intent,
10225                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10226                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10227                intent = new Intent(Intent.ACTION_USER_STARTING);
10228                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10229                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10230                broadcastIntentLocked(null, null, intent,
10231                        null, new IIntentReceiver.Stub() {
10232                            @Override
10233                            public void performReceive(Intent intent, int resultCode, String data,
10234                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10235                                    throws RemoteException {
10236                            }
10237                        }, 0, null, null,
10238                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10239                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10240            } catch (Throwable t) {
10241                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10242            } finally {
10243                Binder.restoreCallingIdentity(ident);
10244            }
10245            mStackSupervisor.resumeTopActivitiesLocked();
10246            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10247        }
10248    }
10249
10250    private boolean makeAppCrashingLocked(ProcessRecord app,
10251            String shortMsg, String longMsg, String stackTrace) {
10252        app.crashing = true;
10253        app.crashingReport = generateProcessError(app,
10254                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10255        startAppProblemLocked(app);
10256        app.stopFreezingAllLocked();
10257        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10258    }
10259
10260    private void makeAppNotRespondingLocked(ProcessRecord app,
10261            String activity, String shortMsg, String longMsg) {
10262        app.notResponding = true;
10263        app.notRespondingReport = generateProcessError(app,
10264                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10265                activity, shortMsg, longMsg, null);
10266        startAppProblemLocked(app);
10267        app.stopFreezingAllLocked();
10268    }
10269
10270    /**
10271     * Generate a process error record, suitable for attachment to a ProcessRecord.
10272     *
10273     * @param app The ProcessRecord in which the error occurred.
10274     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10275     *                      ActivityManager.AppErrorStateInfo
10276     * @param activity The activity associated with the crash, if known.
10277     * @param shortMsg Short message describing the crash.
10278     * @param longMsg Long message describing the crash.
10279     * @param stackTrace Full crash stack trace, may be null.
10280     *
10281     * @return Returns a fully-formed AppErrorStateInfo record.
10282     */
10283    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10284            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10285        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10286
10287        report.condition = condition;
10288        report.processName = app.processName;
10289        report.pid = app.pid;
10290        report.uid = app.info.uid;
10291        report.tag = activity;
10292        report.shortMsg = shortMsg;
10293        report.longMsg = longMsg;
10294        report.stackTrace = stackTrace;
10295
10296        return report;
10297    }
10298
10299    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10300        synchronized (this) {
10301            app.crashing = false;
10302            app.crashingReport = null;
10303            app.notResponding = false;
10304            app.notRespondingReport = null;
10305            if (app.anrDialog == fromDialog) {
10306                app.anrDialog = null;
10307            }
10308            if (app.waitDialog == fromDialog) {
10309                app.waitDialog = null;
10310            }
10311            if (app.pid > 0 && app.pid != MY_PID) {
10312                handleAppCrashLocked(app, null, null, null);
10313                killUnneededProcessLocked(app, "user request after error");
10314            }
10315        }
10316    }
10317
10318    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10319            String stackTrace) {
10320        long now = SystemClock.uptimeMillis();
10321
10322        Long crashTime;
10323        if (!app.isolated) {
10324            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10325        } else {
10326            crashTime = null;
10327        }
10328        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10329            // This process loses!
10330            Slog.w(TAG, "Process " + app.info.processName
10331                    + " has crashed too many times: killing!");
10332            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10333                    app.userId, app.info.processName, app.uid);
10334            mStackSupervisor.handleAppCrashLocked(app);
10335            if (!app.persistent) {
10336                // We don't want to start this process again until the user
10337                // explicitly does so...  but for persistent process, we really
10338                // need to keep it running.  If a persistent process is actually
10339                // repeatedly crashing, then badness for everyone.
10340                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10341                        app.info.processName);
10342                if (!app.isolated) {
10343                    // XXX We don't have a way to mark isolated processes
10344                    // as bad, since they don't have a peristent identity.
10345                    mBadProcesses.put(app.info.processName, app.uid,
10346                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10347                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10348                }
10349                app.bad = true;
10350                app.removed = true;
10351                // Don't let services in this process be restarted and potentially
10352                // annoy the user repeatedly.  Unless it is persistent, since those
10353                // processes run critical code.
10354                removeProcessLocked(app, false, false, "crash");
10355                mStackSupervisor.resumeTopActivitiesLocked();
10356                return false;
10357            }
10358            mStackSupervisor.resumeTopActivitiesLocked();
10359        } else {
10360            mStackSupervisor.finishTopRunningActivityLocked(app);
10361        }
10362
10363        // Bump up the crash count of any services currently running in the proc.
10364        for (int i=app.services.size()-1; i>=0; i--) {
10365            // Any services running in the application need to be placed
10366            // back in the pending list.
10367            ServiceRecord sr = app.services.valueAt(i);
10368            sr.crashCount++;
10369        }
10370
10371        // If the crashing process is what we consider to be the "home process" and it has been
10372        // replaced by a third-party app, clear the package preferred activities from packages
10373        // with a home activity running in the process to prevent a repeatedly crashing app
10374        // from blocking the user to manually clear the list.
10375        final ArrayList<ActivityRecord> activities = app.activities;
10376        if (app == mHomeProcess && activities.size() > 0
10377                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10378            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10379                final ActivityRecord r = activities.get(activityNdx);
10380                if (r.isHomeActivity()) {
10381                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10382                    try {
10383                        ActivityThread.getPackageManager()
10384                                .clearPackagePreferredActivities(r.packageName);
10385                    } catch (RemoteException c) {
10386                        // pm is in same process, this will never happen.
10387                    }
10388                }
10389            }
10390        }
10391
10392        if (!app.isolated) {
10393            // XXX Can't keep track of crash times for isolated processes,
10394            // because they don't have a perisistent identity.
10395            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10396        }
10397
10398        return true;
10399    }
10400
10401    void startAppProblemLocked(ProcessRecord app) {
10402        if (app.userId == mCurrentUserId) {
10403            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10404                    mContext, app.info.packageName, app.info.flags);
10405        } else {
10406            // If this app is not running under the current user, then we
10407            // can't give it a report button because that would require
10408            // launching the report UI under a different user.
10409            app.errorReportReceiver = null;
10410        }
10411        skipCurrentReceiverLocked(app);
10412    }
10413
10414    void skipCurrentReceiverLocked(ProcessRecord app) {
10415        for (BroadcastQueue queue : mBroadcastQueues) {
10416            queue.skipCurrentReceiverLocked(app);
10417        }
10418    }
10419
10420    /**
10421     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10422     * The application process will exit immediately after this call returns.
10423     * @param app object of the crashing app, null for the system server
10424     * @param crashInfo describing the exception
10425     */
10426    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10427        ProcessRecord r = findAppProcess(app, "Crash");
10428        final String processName = app == null ? "system_server"
10429                : (r == null ? "unknown" : r.processName);
10430
10431        handleApplicationCrashInner("crash", r, processName, crashInfo);
10432    }
10433
10434    /* Native crash reporting uses this inner version because it needs to be somewhat
10435     * decoupled from the AM-managed cleanup lifecycle
10436     */
10437    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10438            ApplicationErrorReport.CrashInfo crashInfo) {
10439        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10440                UserHandle.getUserId(Binder.getCallingUid()), processName,
10441                r == null ? -1 : r.info.flags,
10442                crashInfo.exceptionClassName,
10443                crashInfo.exceptionMessage,
10444                crashInfo.throwFileName,
10445                crashInfo.throwLineNumber);
10446
10447        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10448
10449        crashApplication(r, crashInfo);
10450    }
10451
10452    public void handleApplicationStrictModeViolation(
10453            IBinder app,
10454            int violationMask,
10455            StrictMode.ViolationInfo info) {
10456        ProcessRecord r = findAppProcess(app, "StrictMode");
10457        if (r == null) {
10458            return;
10459        }
10460
10461        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10462            Integer stackFingerprint = info.hashCode();
10463            boolean logIt = true;
10464            synchronized (mAlreadyLoggedViolatedStacks) {
10465                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10466                    logIt = false;
10467                    // TODO: sub-sample into EventLog for these, with
10468                    // the info.durationMillis?  Then we'd get
10469                    // the relative pain numbers, without logging all
10470                    // the stack traces repeatedly.  We'd want to do
10471                    // likewise in the client code, which also does
10472                    // dup suppression, before the Binder call.
10473                } else {
10474                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10475                        mAlreadyLoggedViolatedStacks.clear();
10476                    }
10477                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10478                }
10479            }
10480            if (logIt) {
10481                logStrictModeViolationToDropBox(r, info);
10482            }
10483        }
10484
10485        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10486            AppErrorResult result = new AppErrorResult();
10487            synchronized (this) {
10488                final long origId = Binder.clearCallingIdentity();
10489
10490                Message msg = Message.obtain();
10491                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10492                HashMap<String, Object> data = new HashMap<String, Object>();
10493                data.put("result", result);
10494                data.put("app", r);
10495                data.put("violationMask", violationMask);
10496                data.put("info", info);
10497                msg.obj = data;
10498                mHandler.sendMessage(msg);
10499
10500                Binder.restoreCallingIdentity(origId);
10501            }
10502            int res = result.get();
10503            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10504        }
10505    }
10506
10507    // Depending on the policy in effect, there could be a bunch of
10508    // these in quick succession so we try to batch these together to
10509    // minimize disk writes, number of dropbox entries, and maximize
10510    // compression, by having more fewer, larger records.
10511    private void logStrictModeViolationToDropBox(
10512            ProcessRecord process,
10513            StrictMode.ViolationInfo info) {
10514        if (info == null) {
10515            return;
10516        }
10517        final boolean isSystemApp = process == null ||
10518                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10519                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10520        final String processName = process == null ? "unknown" : process.processName;
10521        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10522        final DropBoxManager dbox = (DropBoxManager)
10523                mContext.getSystemService(Context.DROPBOX_SERVICE);
10524
10525        // Exit early if the dropbox isn't configured to accept this report type.
10526        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10527
10528        boolean bufferWasEmpty;
10529        boolean needsFlush;
10530        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10531        synchronized (sb) {
10532            bufferWasEmpty = sb.length() == 0;
10533            appendDropBoxProcessHeaders(process, processName, sb);
10534            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10535            sb.append("System-App: ").append(isSystemApp).append("\n");
10536            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10537            if (info.violationNumThisLoop != 0) {
10538                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10539            }
10540            if (info.numAnimationsRunning != 0) {
10541                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10542            }
10543            if (info.broadcastIntentAction != null) {
10544                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10545            }
10546            if (info.durationMillis != -1) {
10547                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10548            }
10549            if (info.numInstances != -1) {
10550                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10551            }
10552            if (info.tags != null) {
10553                for (String tag : info.tags) {
10554                    sb.append("Span-Tag: ").append(tag).append("\n");
10555                }
10556            }
10557            sb.append("\n");
10558            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10559                sb.append(info.crashInfo.stackTrace);
10560            }
10561            sb.append("\n");
10562
10563            // Only buffer up to ~64k.  Various logging bits truncate
10564            // things at 128k.
10565            needsFlush = (sb.length() > 64 * 1024);
10566        }
10567
10568        // Flush immediately if the buffer's grown too large, or this
10569        // is a non-system app.  Non-system apps are isolated with a
10570        // different tag & policy and not batched.
10571        //
10572        // Batching is useful during internal testing with
10573        // StrictMode settings turned up high.  Without batching,
10574        // thousands of separate files could be created on boot.
10575        if (!isSystemApp || needsFlush) {
10576            new Thread("Error dump: " + dropboxTag) {
10577                @Override
10578                public void run() {
10579                    String report;
10580                    synchronized (sb) {
10581                        report = sb.toString();
10582                        sb.delete(0, sb.length());
10583                        sb.trimToSize();
10584                    }
10585                    if (report.length() != 0) {
10586                        dbox.addText(dropboxTag, report);
10587                    }
10588                }
10589            }.start();
10590            return;
10591        }
10592
10593        // System app batching:
10594        if (!bufferWasEmpty) {
10595            // An existing dropbox-writing thread is outstanding, so
10596            // we don't need to start it up.  The existing thread will
10597            // catch the buffer appends we just did.
10598            return;
10599        }
10600
10601        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10602        // (After this point, we shouldn't access AMS internal data structures.)
10603        new Thread("Error dump: " + dropboxTag) {
10604            @Override
10605            public void run() {
10606                // 5 second sleep to let stacks arrive and be batched together
10607                try {
10608                    Thread.sleep(5000);  // 5 seconds
10609                } catch (InterruptedException e) {}
10610
10611                String errorReport;
10612                synchronized (mStrictModeBuffer) {
10613                    errorReport = mStrictModeBuffer.toString();
10614                    if (errorReport.length() == 0) {
10615                        return;
10616                    }
10617                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10618                    mStrictModeBuffer.trimToSize();
10619                }
10620                dbox.addText(dropboxTag, errorReport);
10621            }
10622        }.start();
10623    }
10624
10625    /**
10626     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10627     * @param app object of the crashing app, null for the system server
10628     * @param tag reported by the caller
10629     * @param crashInfo describing the context of the error
10630     * @return true if the process should exit immediately (WTF is fatal)
10631     */
10632    public boolean handleApplicationWtf(IBinder app, String tag,
10633            ApplicationErrorReport.CrashInfo crashInfo) {
10634        ProcessRecord r = findAppProcess(app, "WTF");
10635        final String processName = app == null ? "system_server"
10636                : (r == null ? "unknown" : r.processName);
10637
10638        EventLog.writeEvent(EventLogTags.AM_WTF,
10639                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10640                processName,
10641                r == null ? -1 : r.info.flags,
10642                tag, crashInfo.exceptionMessage);
10643
10644        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10645
10646        if (r != null && r.pid != Process.myPid() &&
10647                Settings.Global.getInt(mContext.getContentResolver(),
10648                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10649            crashApplication(r, crashInfo);
10650            return true;
10651        } else {
10652            return false;
10653        }
10654    }
10655
10656    /**
10657     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10658     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10659     */
10660    private ProcessRecord findAppProcess(IBinder app, String reason) {
10661        if (app == null) {
10662            return null;
10663        }
10664
10665        synchronized (this) {
10666            final int NP = mProcessNames.getMap().size();
10667            for (int ip=0; ip<NP; ip++) {
10668                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10669                final int NA = apps.size();
10670                for (int ia=0; ia<NA; ia++) {
10671                    ProcessRecord p = apps.valueAt(ia);
10672                    if (p.thread != null && p.thread.asBinder() == app) {
10673                        return p;
10674                    }
10675                }
10676            }
10677
10678            Slog.w(TAG, "Can't find mystery application for " + reason
10679                    + " from pid=" + Binder.getCallingPid()
10680                    + " uid=" + Binder.getCallingUid() + ": " + app);
10681            return null;
10682        }
10683    }
10684
10685    /**
10686     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10687     * to append various headers to the dropbox log text.
10688     */
10689    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10690            StringBuilder sb) {
10691        // Watchdog thread ends up invoking this function (with
10692        // a null ProcessRecord) to add the stack file to dropbox.
10693        // Do not acquire a lock on this (am) in such cases, as it
10694        // could cause a potential deadlock, if and when watchdog
10695        // is invoked due to unavailability of lock on am and it
10696        // would prevent watchdog from killing system_server.
10697        if (process == null) {
10698            sb.append("Process: ").append(processName).append("\n");
10699            return;
10700        }
10701        // Note: ProcessRecord 'process' is guarded by the service
10702        // instance.  (notably process.pkgList, which could otherwise change
10703        // concurrently during execution of this method)
10704        synchronized (this) {
10705            sb.append("Process: ").append(processName).append("\n");
10706            int flags = process.info.flags;
10707            IPackageManager pm = AppGlobals.getPackageManager();
10708            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10709            for (int ip=0; ip<process.pkgList.size(); ip++) {
10710                String pkg = process.pkgList.keyAt(ip);
10711                sb.append("Package: ").append(pkg);
10712                try {
10713                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10714                    if (pi != null) {
10715                        sb.append(" v").append(pi.versionCode);
10716                        if (pi.versionName != null) {
10717                            sb.append(" (").append(pi.versionName).append(")");
10718                        }
10719                    }
10720                } catch (RemoteException e) {
10721                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10722                }
10723                sb.append("\n");
10724            }
10725        }
10726    }
10727
10728    private static String processClass(ProcessRecord process) {
10729        if (process == null || process.pid == MY_PID) {
10730            return "system_server";
10731        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10732            return "system_app";
10733        } else {
10734            return "data_app";
10735        }
10736    }
10737
10738    /**
10739     * Write a description of an error (crash, WTF, ANR) to the drop box.
10740     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10741     * @param process which caused the error, null means the system server
10742     * @param activity which triggered the error, null if unknown
10743     * @param parent activity related to the error, null if unknown
10744     * @param subject line related to the error, null if absent
10745     * @param report in long form describing the error, null if absent
10746     * @param logFile to include in the report, null if none
10747     * @param crashInfo giving an application stack trace, null if absent
10748     */
10749    public void addErrorToDropBox(String eventType,
10750            ProcessRecord process, String processName, ActivityRecord activity,
10751            ActivityRecord parent, String subject,
10752            final String report, final File logFile,
10753            final ApplicationErrorReport.CrashInfo crashInfo) {
10754        // NOTE -- this must never acquire the ActivityManagerService lock,
10755        // otherwise the watchdog may be prevented from resetting the system.
10756
10757        final String dropboxTag = processClass(process) + "_" + eventType;
10758        final DropBoxManager dbox = (DropBoxManager)
10759                mContext.getSystemService(Context.DROPBOX_SERVICE);
10760
10761        // Exit early if the dropbox isn't configured to accept this report type.
10762        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10763
10764        final StringBuilder sb = new StringBuilder(1024);
10765        appendDropBoxProcessHeaders(process, processName, sb);
10766        if (activity != null) {
10767            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10768        }
10769        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10770            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10771        }
10772        if (parent != null && parent != activity) {
10773            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10774        }
10775        if (subject != null) {
10776            sb.append("Subject: ").append(subject).append("\n");
10777        }
10778        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10779        if (Debug.isDebuggerConnected()) {
10780            sb.append("Debugger: Connected\n");
10781        }
10782        sb.append("\n");
10783
10784        // Do the rest in a worker thread to avoid blocking the caller on I/O
10785        // (After this point, we shouldn't access AMS internal data structures.)
10786        Thread worker = new Thread("Error dump: " + dropboxTag) {
10787            @Override
10788            public void run() {
10789                if (report != null) {
10790                    sb.append(report);
10791                }
10792                if (logFile != null) {
10793                    try {
10794                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10795                                    "\n\n[[TRUNCATED]]"));
10796                    } catch (IOException e) {
10797                        Slog.e(TAG, "Error reading " + logFile, e);
10798                    }
10799                }
10800                if (crashInfo != null && crashInfo.stackTrace != null) {
10801                    sb.append(crashInfo.stackTrace);
10802                }
10803
10804                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10805                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10806                if (lines > 0) {
10807                    sb.append("\n");
10808
10809                    // Merge several logcat streams, and take the last N lines
10810                    InputStreamReader input = null;
10811                    try {
10812                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10813                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10814                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10815
10816                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10817                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10818                        input = new InputStreamReader(logcat.getInputStream());
10819
10820                        int num;
10821                        char[] buf = new char[8192];
10822                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10823                    } catch (IOException e) {
10824                        Slog.e(TAG, "Error running logcat", e);
10825                    } finally {
10826                        if (input != null) try { input.close(); } catch (IOException e) {}
10827                    }
10828                }
10829
10830                dbox.addText(dropboxTag, sb.toString());
10831            }
10832        };
10833
10834        if (process == null) {
10835            // If process is null, we are being called from some internal code
10836            // and may be about to die -- run this synchronously.
10837            worker.run();
10838        } else {
10839            worker.start();
10840        }
10841    }
10842
10843    /**
10844     * Bring up the "unexpected error" dialog box for a crashing app.
10845     * Deal with edge cases (intercepts from instrumented applications,
10846     * ActivityController, error intent receivers, that sort of thing).
10847     * @param r the application crashing
10848     * @param crashInfo describing the failure
10849     */
10850    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10851        long timeMillis = System.currentTimeMillis();
10852        String shortMsg = crashInfo.exceptionClassName;
10853        String longMsg = crashInfo.exceptionMessage;
10854        String stackTrace = crashInfo.stackTrace;
10855        if (shortMsg != null && longMsg != null) {
10856            longMsg = shortMsg + ": " + longMsg;
10857        } else if (shortMsg != null) {
10858            longMsg = shortMsg;
10859        }
10860
10861        AppErrorResult result = new AppErrorResult();
10862        synchronized (this) {
10863            if (mController != null) {
10864                try {
10865                    String name = r != null ? r.processName : null;
10866                    int pid = r != null ? r.pid : Binder.getCallingPid();
10867                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10868                    if (!mController.appCrashed(name, pid,
10869                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10870                        Slog.w(TAG, "Force-killing crashed app " + name
10871                                + " at watcher's request");
10872                        Process.killProcess(pid);
10873                        if (r != null) {
10874                            Process.killProcessGroup(uid, pid);
10875                        }
10876                        return;
10877                    }
10878                } catch (RemoteException e) {
10879                    mController = null;
10880                    Watchdog.getInstance().setActivityController(null);
10881                }
10882            }
10883
10884            final long origId = Binder.clearCallingIdentity();
10885
10886            // If this process is running instrumentation, finish it.
10887            if (r != null && r.instrumentationClass != null) {
10888                Slog.w(TAG, "Error in app " + r.processName
10889                      + " running instrumentation " + r.instrumentationClass + ":");
10890                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10891                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10892                Bundle info = new Bundle();
10893                info.putString("shortMsg", shortMsg);
10894                info.putString("longMsg", longMsg);
10895                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10896                Binder.restoreCallingIdentity(origId);
10897                return;
10898            }
10899
10900            // If we can't identify the process or it's already exceeded its crash quota,
10901            // quit right away without showing a crash dialog.
10902            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10903                Binder.restoreCallingIdentity(origId);
10904                return;
10905            }
10906
10907            Message msg = Message.obtain();
10908            msg.what = SHOW_ERROR_MSG;
10909            HashMap data = new HashMap();
10910            data.put("result", result);
10911            data.put("app", r);
10912            msg.obj = data;
10913            mHandler.sendMessage(msg);
10914
10915            Binder.restoreCallingIdentity(origId);
10916        }
10917
10918        int res = result.get();
10919
10920        Intent appErrorIntent = null;
10921        synchronized (this) {
10922            if (r != null && !r.isolated) {
10923                // XXX Can't keep track of crash time for isolated processes,
10924                // since they don't have a persistent identity.
10925                mProcessCrashTimes.put(r.info.processName, r.uid,
10926                        SystemClock.uptimeMillis());
10927            }
10928            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10929                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10930            }
10931        }
10932
10933        if (appErrorIntent != null) {
10934            try {
10935                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10936            } catch (ActivityNotFoundException e) {
10937                Slog.w(TAG, "bug report receiver dissappeared", e);
10938            }
10939        }
10940    }
10941
10942    Intent createAppErrorIntentLocked(ProcessRecord r,
10943            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10944        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10945        if (report == null) {
10946            return null;
10947        }
10948        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10949        result.setComponent(r.errorReportReceiver);
10950        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10951        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10952        return result;
10953    }
10954
10955    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10956            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10957        if (r.errorReportReceiver == null) {
10958            return null;
10959        }
10960
10961        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10962            return null;
10963        }
10964
10965        ApplicationErrorReport report = new ApplicationErrorReport();
10966        report.packageName = r.info.packageName;
10967        report.installerPackageName = r.errorReportReceiver.getPackageName();
10968        report.processName = r.processName;
10969        report.time = timeMillis;
10970        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10971
10972        if (r.crashing || r.forceCrashReport) {
10973            report.type = ApplicationErrorReport.TYPE_CRASH;
10974            report.crashInfo = crashInfo;
10975        } else if (r.notResponding) {
10976            report.type = ApplicationErrorReport.TYPE_ANR;
10977            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10978
10979            report.anrInfo.activity = r.notRespondingReport.tag;
10980            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10981            report.anrInfo.info = r.notRespondingReport.longMsg;
10982        }
10983
10984        return report;
10985    }
10986
10987    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10988        enforceNotIsolatedCaller("getProcessesInErrorState");
10989        // assume our apps are happy - lazy create the list
10990        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10991
10992        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10993                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10994        int userId = UserHandle.getUserId(Binder.getCallingUid());
10995
10996        synchronized (this) {
10997
10998            // iterate across all processes
10999            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11000                ProcessRecord app = mLruProcesses.get(i);
11001                if (!allUsers && app.userId != userId) {
11002                    continue;
11003                }
11004                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11005                    // This one's in trouble, so we'll generate a report for it
11006                    // crashes are higher priority (in case there's a crash *and* an anr)
11007                    ActivityManager.ProcessErrorStateInfo report = null;
11008                    if (app.crashing) {
11009                        report = app.crashingReport;
11010                    } else if (app.notResponding) {
11011                        report = app.notRespondingReport;
11012                    }
11013
11014                    if (report != null) {
11015                        if (errList == null) {
11016                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11017                        }
11018                        errList.add(report);
11019                    } else {
11020                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11021                                " crashing = " + app.crashing +
11022                                " notResponding = " + app.notResponding);
11023                    }
11024                }
11025            }
11026        }
11027
11028        return errList;
11029    }
11030
11031    static int procStateToImportance(int procState, int memAdj,
11032            ActivityManager.RunningAppProcessInfo currApp) {
11033        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11034        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11035            currApp.lru = memAdj;
11036        } else {
11037            currApp.lru = 0;
11038        }
11039        return imp;
11040    }
11041
11042    private void fillInProcMemInfo(ProcessRecord app,
11043            ActivityManager.RunningAppProcessInfo outInfo) {
11044        outInfo.pid = app.pid;
11045        outInfo.uid = app.info.uid;
11046        if (mHeavyWeightProcess == app) {
11047            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11048        }
11049        if (app.persistent) {
11050            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11051        }
11052        if (app.activities.size() > 0) {
11053            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11054        }
11055        outInfo.lastTrimLevel = app.trimMemoryLevel;
11056        int adj = app.curAdj;
11057        int procState = app.curProcState;
11058        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11059        outInfo.importanceReasonCode = app.adjTypeCode;
11060        outInfo.processState = app.curProcState;
11061    }
11062
11063    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11064        enforceNotIsolatedCaller("getRunningAppProcesses");
11065        // Lazy instantiation of list
11066        List<ActivityManager.RunningAppProcessInfo> runList = null;
11067        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11068                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11069        int userId = UserHandle.getUserId(Binder.getCallingUid());
11070        synchronized (this) {
11071            // Iterate across all processes
11072            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11073                ProcessRecord app = mLruProcesses.get(i);
11074                if (!allUsers && app.userId != userId) {
11075                    continue;
11076                }
11077                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11078                    // Generate process state info for running application
11079                    ActivityManager.RunningAppProcessInfo currApp =
11080                        new ActivityManager.RunningAppProcessInfo(app.processName,
11081                                app.pid, app.getPackageList());
11082                    fillInProcMemInfo(app, currApp);
11083                    if (app.adjSource instanceof ProcessRecord) {
11084                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11085                        currApp.importanceReasonImportance =
11086                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11087                                        app.adjSourceProcState);
11088                    } else if (app.adjSource instanceof ActivityRecord) {
11089                        ActivityRecord r = (ActivityRecord)app.adjSource;
11090                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11091                    }
11092                    if (app.adjTarget instanceof ComponentName) {
11093                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11094                    }
11095                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11096                    //        + " lru=" + currApp.lru);
11097                    if (runList == null) {
11098                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11099                    }
11100                    runList.add(currApp);
11101                }
11102            }
11103        }
11104        return runList;
11105    }
11106
11107    public List<ApplicationInfo> getRunningExternalApplications() {
11108        enforceNotIsolatedCaller("getRunningExternalApplications");
11109        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11110        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11111        if (runningApps != null && runningApps.size() > 0) {
11112            Set<String> extList = new HashSet<String>();
11113            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11114                if (app.pkgList != null) {
11115                    for (String pkg : app.pkgList) {
11116                        extList.add(pkg);
11117                    }
11118                }
11119            }
11120            IPackageManager pm = AppGlobals.getPackageManager();
11121            for (String pkg : extList) {
11122                try {
11123                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11124                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11125                        retList.add(info);
11126                    }
11127                } catch (RemoteException e) {
11128                }
11129            }
11130        }
11131        return retList;
11132    }
11133
11134    @Override
11135    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11136        enforceNotIsolatedCaller("getMyMemoryState");
11137        synchronized (this) {
11138            ProcessRecord proc;
11139            synchronized (mPidsSelfLocked) {
11140                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11141            }
11142            fillInProcMemInfo(proc, outInfo);
11143        }
11144    }
11145
11146    @Override
11147    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11148        if (checkCallingPermission(android.Manifest.permission.DUMP)
11149                != PackageManager.PERMISSION_GRANTED) {
11150            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11151                    + Binder.getCallingPid()
11152                    + ", uid=" + Binder.getCallingUid()
11153                    + " without permission "
11154                    + android.Manifest.permission.DUMP);
11155            return;
11156        }
11157
11158        boolean dumpAll = false;
11159        boolean dumpClient = false;
11160        String dumpPackage = null;
11161
11162        int opti = 0;
11163        while (opti < args.length) {
11164            String opt = args[opti];
11165            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11166                break;
11167            }
11168            opti++;
11169            if ("-a".equals(opt)) {
11170                dumpAll = true;
11171            } else if ("-c".equals(opt)) {
11172                dumpClient = true;
11173            } else if ("-h".equals(opt)) {
11174                pw.println("Activity manager dump options:");
11175                pw.println("  [-a] [-c] [-h] [cmd] ...");
11176                pw.println("  cmd may be one of:");
11177                pw.println("    a[ctivities]: activity stack state");
11178                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11179                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11180                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11181                pw.println("    o[om]: out of memory management");
11182                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11183                pw.println("    provider [COMP_SPEC]: provider client-side state");
11184                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11185                pw.println("    service [COMP_SPEC]: service client-side state");
11186                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11187                pw.println("    all: dump all activities");
11188                pw.println("    top: dump the top activity");
11189                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11190                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11191                pw.println("    a partial substring in a component name, a");
11192                pw.println("    hex object identifier.");
11193                pw.println("  -a: include all available server state.");
11194                pw.println("  -c: include client state.");
11195                return;
11196            } else {
11197                pw.println("Unknown argument: " + opt + "; use -h for help");
11198            }
11199        }
11200
11201        long origId = Binder.clearCallingIdentity();
11202        boolean more = false;
11203        // Is the caller requesting to dump a particular piece of data?
11204        if (opti < args.length) {
11205            String cmd = args[opti];
11206            opti++;
11207            if ("activities".equals(cmd) || "a".equals(cmd)) {
11208                synchronized (this) {
11209                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11210                }
11211            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11212                String[] newArgs;
11213                String name;
11214                if (opti >= args.length) {
11215                    name = null;
11216                    newArgs = EMPTY_STRING_ARRAY;
11217                } else {
11218                    name = args[opti];
11219                    opti++;
11220                    newArgs = new String[args.length - opti];
11221                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11222                            args.length - opti);
11223                }
11224                synchronized (this) {
11225                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11226                }
11227            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11228                String[] newArgs;
11229                String name;
11230                if (opti >= args.length) {
11231                    name = null;
11232                    newArgs = EMPTY_STRING_ARRAY;
11233                } else {
11234                    name = args[opti];
11235                    opti++;
11236                    newArgs = new String[args.length - opti];
11237                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11238                            args.length - opti);
11239                }
11240                synchronized (this) {
11241                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11242                }
11243            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11244                String[] newArgs;
11245                String name;
11246                if (opti >= args.length) {
11247                    name = null;
11248                    newArgs = EMPTY_STRING_ARRAY;
11249                } else {
11250                    name = args[opti];
11251                    opti++;
11252                    newArgs = new String[args.length - opti];
11253                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11254                            args.length - opti);
11255                }
11256                synchronized (this) {
11257                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11258                }
11259            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11260                synchronized (this) {
11261                    dumpOomLocked(fd, pw, args, opti, true);
11262                }
11263            } else if ("provider".equals(cmd)) {
11264                String[] newArgs;
11265                String name;
11266                if (opti >= args.length) {
11267                    name = null;
11268                    newArgs = EMPTY_STRING_ARRAY;
11269                } else {
11270                    name = args[opti];
11271                    opti++;
11272                    newArgs = new String[args.length - opti];
11273                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11274                }
11275                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11276                    pw.println("No providers match: " + name);
11277                    pw.println("Use -h for help.");
11278                }
11279            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11280                synchronized (this) {
11281                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11282                }
11283            } else if ("service".equals(cmd)) {
11284                String[] newArgs;
11285                String name;
11286                if (opti >= args.length) {
11287                    name = null;
11288                    newArgs = EMPTY_STRING_ARRAY;
11289                } else {
11290                    name = args[opti];
11291                    opti++;
11292                    newArgs = new String[args.length - opti];
11293                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11294                            args.length - opti);
11295                }
11296                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11297                    pw.println("No services match: " + name);
11298                    pw.println("Use -h for help.");
11299                }
11300            } else if ("package".equals(cmd)) {
11301                String[] newArgs;
11302                if (opti >= args.length) {
11303                    pw.println("package: no package name specified");
11304                    pw.println("Use -h for help.");
11305                } else {
11306                    dumpPackage = args[opti];
11307                    opti++;
11308                    newArgs = new String[args.length - opti];
11309                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11310                            args.length - opti);
11311                    args = newArgs;
11312                    opti = 0;
11313                    more = true;
11314                }
11315            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11316                synchronized (this) {
11317                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11318                }
11319            } else {
11320                // Dumping a single activity?
11321                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11322                    pw.println("Bad activity command, or no activities match: " + cmd);
11323                    pw.println("Use -h for help.");
11324                }
11325            }
11326            if (!more) {
11327                Binder.restoreCallingIdentity(origId);
11328                return;
11329            }
11330        }
11331
11332        // No piece of data specified, dump everything.
11333        synchronized (this) {
11334            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11335            pw.println();
11336            if (dumpAll) {
11337                pw.println("-------------------------------------------------------------------------------");
11338            }
11339            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11340            pw.println();
11341            if (dumpAll) {
11342                pw.println("-------------------------------------------------------------------------------");
11343            }
11344            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11345            pw.println();
11346            if (dumpAll) {
11347                pw.println("-------------------------------------------------------------------------------");
11348            }
11349            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11350            pw.println();
11351            if (dumpAll) {
11352                pw.println("-------------------------------------------------------------------------------");
11353            }
11354            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11355            pw.println();
11356            if (dumpAll) {
11357                pw.println("-------------------------------------------------------------------------------");
11358            }
11359            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11360        }
11361        Binder.restoreCallingIdentity(origId);
11362    }
11363
11364    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11365            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11366        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11367
11368        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11369                dumpPackage);
11370        boolean needSep = printedAnything;
11371
11372        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11373                dumpPackage, needSep, "  mFocusedActivity: ");
11374        if (printed) {
11375            printedAnything = true;
11376            needSep = false;
11377        }
11378
11379        if (dumpPackage == null) {
11380            if (needSep) {
11381                pw.println();
11382            }
11383            needSep = true;
11384            printedAnything = true;
11385            mStackSupervisor.dump(pw, "  ");
11386        }
11387
11388        if (mRecentTasks.size() > 0) {
11389            boolean printedHeader = false;
11390
11391            final int N = mRecentTasks.size();
11392            for (int i=0; i<N; i++) {
11393                TaskRecord tr = mRecentTasks.get(i);
11394                if (dumpPackage != null) {
11395                    if (tr.realActivity == null ||
11396                            !dumpPackage.equals(tr.realActivity)) {
11397                        continue;
11398                    }
11399                }
11400                if (!printedHeader) {
11401                    if (needSep) {
11402                        pw.println();
11403                    }
11404                    pw.println("  Recent tasks:");
11405                    printedHeader = true;
11406                    printedAnything = true;
11407                }
11408                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11409                        pw.println(tr);
11410                if (dumpAll) {
11411                    mRecentTasks.get(i).dump(pw, "    ");
11412                }
11413            }
11414        }
11415
11416        if (!printedAnything) {
11417            pw.println("  (nothing)");
11418        }
11419    }
11420
11421    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11422            int opti, boolean dumpAll, String dumpPackage) {
11423        boolean needSep = false;
11424        boolean printedAnything = false;
11425        int numPers = 0;
11426
11427        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11428
11429        if (dumpAll) {
11430            final int NP = mProcessNames.getMap().size();
11431            for (int ip=0; ip<NP; ip++) {
11432                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11433                final int NA = procs.size();
11434                for (int ia=0; ia<NA; ia++) {
11435                    ProcessRecord r = procs.valueAt(ia);
11436                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11437                        continue;
11438                    }
11439                    if (!needSep) {
11440                        pw.println("  All known processes:");
11441                        needSep = true;
11442                        printedAnything = true;
11443                    }
11444                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11445                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11446                        pw.print(" "); pw.println(r);
11447                    r.dump(pw, "    ");
11448                    if (r.persistent) {
11449                        numPers++;
11450                    }
11451                }
11452            }
11453        }
11454
11455        if (mIsolatedProcesses.size() > 0) {
11456            boolean printed = false;
11457            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11458                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11459                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11460                    continue;
11461                }
11462                if (!printed) {
11463                    if (needSep) {
11464                        pw.println();
11465                    }
11466                    pw.println("  Isolated process list (sorted by uid):");
11467                    printedAnything = true;
11468                    printed = true;
11469                    needSep = true;
11470                }
11471                pw.println(String.format("%sIsolated #%2d: %s",
11472                        "    ", i, r.toString()));
11473            }
11474        }
11475
11476        if (mLruProcesses.size() > 0) {
11477            if (needSep) {
11478                pw.println();
11479            }
11480            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11481                    pw.print(" total, non-act at ");
11482                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11483                    pw.print(", non-svc at ");
11484                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11485                    pw.println("):");
11486            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11487            needSep = true;
11488            printedAnything = true;
11489        }
11490
11491        if (dumpAll || dumpPackage != null) {
11492            synchronized (mPidsSelfLocked) {
11493                boolean printed = false;
11494                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11495                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11496                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11497                        continue;
11498                    }
11499                    if (!printed) {
11500                        if (needSep) pw.println();
11501                        needSep = true;
11502                        pw.println("  PID mappings:");
11503                        printed = true;
11504                        printedAnything = true;
11505                    }
11506                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11507                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11508                }
11509            }
11510        }
11511
11512        if (mForegroundProcesses.size() > 0) {
11513            synchronized (mPidsSelfLocked) {
11514                boolean printed = false;
11515                for (int i=0; i<mForegroundProcesses.size(); i++) {
11516                    ProcessRecord r = mPidsSelfLocked.get(
11517                            mForegroundProcesses.valueAt(i).pid);
11518                    if (dumpPackage != null && (r == null
11519                            || !r.pkgList.containsKey(dumpPackage))) {
11520                        continue;
11521                    }
11522                    if (!printed) {
11523                        if (needSep) pw.println();
11524                        needSep = true;
11525                        pw.println("  Foreground Processes:");
11526                        printed = true;
11527                        printedAnything = true;
11528                    }
11529                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11530                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11531                }
11532            }
11533        }
11534
11535        if (mPersistentStartingProcesses.size() > 0) {
11536            if (needSep) pw.println();
11537            needSep = true;
11538            printedAnything = true;
11539            pw.println("  Persisent processes that are starting:");
11540            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11541                    "Starting Norm", "Restarting PERS", dumpPackage);
11542        }
11543
11544        if (mRemovedProcesses.size() > 0) {
11545            if (needSep) pw.println();
11546            needSep = true;
11547            printedAnything = true;
11548            pw.println("  Processes that are being removed:");
11549            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11550                    "Removed Norm", "Removed PERS", dumpPackage);
11551        }
11552
11553        if (mProcessesOnHold.size() > 0) {
11554            if (needSep) pw.println();
11555            needSep = true;
11556            printedAnything = true;
11557            pw.println("  Processes that are on old until the system is ready:");
11558            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11559                    "OnHold Norm", "OnHold PERS", dumpPackage);
11560        }
11561
11562        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11563
11564        if (mProcessCrashTimes.getMap().size() > 0) {
11565            boolean printed = false;
11566            long now = SystemClock.uptimeMillis();
11567            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11568            final int NP = pmap.size();
11569            for (int ip=0; ip<NP; ip++) {
11570                String pname = pmap.keyAt(ip);
11571                SparseArray<Long> uids = pmap.valueAt(ip);
11572                final int N = uids.size();
11573                for (int i=0; i<N; i++) {
11574                    int puid = uids.keyAt(i);
11575                    ProcessRecord r = mProcessNames.get(pname, puid);
11576                    if (dumpPackage != null && (r == null
11577                            || !r.pkgList.containsKey(dumpPackage))) {
11578                        continue;
11579                    }
11580                    if (!printed) {
11581                        if (needSep) pw.println();
11582                        needSep = true;
11583                        pw.println("  Time since processes crashed:");
11584                        printed = true;
11585                        printedAnything = true;
11586                    }
11587                    pw.print("    Process "); pw.print(pname);
11588                            pw.print(" uid "); pw.print(puid);
11589                            pw.print(": last crashed ");
11590                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11591                            pw.println(" ago");
11592                }
11593            }
11594        }
11595
11596        if (mBadProcesses.getMap().size() > 0) {
11597            boolean printed = false;
11598            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11599            final int NP = pmap.size();
11600            for (int ip=0; ip<NP; ip++) {
11601                String pname = pmap.keyAt(ip);
11602                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11603                final int N = uids.size();
11604                for (int i=0; i<N; i++) {
11605                    int puid = uids.keyAt(i);
11606                    ProcessRecord r = mProcessNames.get(pname, puid);
11607                    if (dumpPackage != null && (r == null
11608                            || !r.pkgList.containsKey(dumpPackage))) {
11609                        continue;
11610                    }
11611                    if (!printed) {
11612                        if (needSep) pw.println();
11613                        needSep = true;
11614                        pw.println("  Bad processes:");
11615                        printedAnything = true;
11616                    }
11617                    BadProcessInfo info = uids.valueAt(i);
11618                    pw.print("    Bad process "); pw.print(pname);
11619                            pw.print(" uid "); pw.print(puid);
11620                            pw.print(": crashed at time "); pw.println(info.time);
11621                    if (info.shortMsg != null) {
11622                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11623                    }
11624                    if (info.longMsg != null) {
11625                        pw.print("      Long msg: "); pw.println(info.longMsg);
11626                    }
11627                    if (info.stack != null) {
11628                        pw.println("      Stack:");
11629                        int lastPos = 0;
11630                        for (int pos=0; pos<info.stack.length(); pos++) {
11631                            if (info.stack.charAt(pos) == '\n') {
11632                                pw.print("        ");
11633                                pw.write(info.stack, lastPos, pos-lastPos);
11634                                pw.println();
11635                                lastPos = pos+1;
11636                            }
11637                        }
11638                        if (lastPos < info.stack.length()) {
11639                            pw.print("        ");
11640                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11641                            pw.println();
11642                        }
11643                    }
11644                }
11645            }
11646        }
11647
11648        if (dumpPackage == null) {
11649            pw.println();
11650            needSep = false;
11651            pw.println("  mStartedUsers:");
11652            for (int i=0; i<mStartedUsers.size(); i++) {
11653                UserStartedState uss = mStartedUsers.valueAt(i);
11654                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11655                        pw.print(": "); uss.dump("", pw);
11656            }
11657            pw.print("  mStartedUserArray: [");
11658            for (int i=0; i<mStartedUserArray.length; i++) {
11659                if (i > 0) pw.print(", ");
11660                pw.print(mStartedUserArray[i]);
11661            }
11662            pw.println("]");
11663            pw.print("  mUserLru: [");
11664            for (int i=0; i<mUserLru.size(); i++) {
11665                if (i > 0) pw.print(", ");
11666                pw.print(mUserLru.get(i));
11667            }
11668            pw.println("]");
11669            if (dumpAll) {
11670                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11671            }
11672            synchronized (mUserProfileGroupIdsSelfLocked) {
11673                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11674                    pw.println("  mUserProfileGroupIds:");
11675                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11676                        pw.print("    User #");
11677                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11678                        pw.print(" -> profile #");
11679                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11680                    }
11681                }
11682            }
11683        }
11684        if (mHomeProcess != null && (dumpPackage == null
11685                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11686            if (needSep) {
11687                pw.println();
11688                needSep = false;
11689            }
11690            pw.println("  mHomeProcess: " + mHomeProcess);
11691        }
11692        if (mPreviousProcess != null && (dumpPackage == null
11693                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11694            if (needSep) {
11695                pw.println();
11696                needSep = false;
11697            }
11698            pw.println("  mPreviousProcess: " + mPreviousProcess);
11699        }
11700        if (dumpAll) {
11701            StringBuilder sb = new StringBuilder(128);
11702            sb.append("  mPreviousProcessVisibleTime: ");
11703            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11704            pw.println(sb);
11705        }
11706        if (mHeavyWeightProcess != null && (dumpPackage == null
11707                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11708            if (needSep) {
11709                pw.println();
11710                needSep = false;
11711            }
11712            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11713        }
11714        if (dumpPackage == null) {
11715            pw.println("  mConfiguration: " + mConfiguration);
11716        }
11717        if (dumpAll) {
11718            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11719            if (mCompatModePackages.getPackages().size() > 0) {
11720                boolean printed = false;
11721                for (Map.Entry<String, Integer> entry
11722                        : mCompatModePackages.getPackages().entrySet()) {
11723                    String pkg = entry.getKey();
11724                    int mode = entry.getValue();
11725                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11726                        continue;
11727                    }
11728                    if (!printed) {
11729                        pw.println("  mScreenCompatPackages:");
11730                        printed = true;
11731                    }
11732                    pw.print("    "); pw.print(pkg); pw.print(": ");
11733                            pw.print(mode); pw.println();
11734                }
11735            }
11736        }
11737        if (dumpPackage == null) {
11738            if (mSleeping || mWentToSleep || mLockScreenShown) {
11739                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11740                        + " mLockScreenShown " + mLockScreenShown);
11741            }
11742            if (mShuttingDown || mRunningVoice) {
11743                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11744            }
11745        }
11746        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11747                || mOrigWaitForDebugger) {
11748            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11749                    || dumpPackage.equals(mOrigDebugApp)) {
11750                if (needSep) {
11751                    pw.println();
11752                    needSep = false;
11753                }
11754                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11755                        + " mDebugTransient=" + mDebugTransient
11756                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11757            }
11758        }
11759        if (mOpenGlTraceApp != null) {
11760            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11761                if (needSep) {
11762                    pw.println();
11763                    needSep = false;
11764                }
11765                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11766            }
11767        }
11768        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11769                || mProfileFd != null) {
11770            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11771                if (needSep) {
11772                    pw.println();
11773                    needSep = false;
11774                }
11775                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11776                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11777                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11778                        + mAutoStopProfiler);
11779            }
11780        }
11781        if (dumpPackage == null) {
11782            if (mAlwaysFinishActivities || mController != null) {
11783                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11784                        + " mController=" + mController);
11785            }
11786            if (dumpAll) {
11787                pw.println("  Total persistent processes: " + numPers);
11788                pw.println("  mProcessesReady=" + mProcessesReady
11789                        + " mSystemReady=" + mSystemReady);
11790                pw.println("  mBooting=" + mBooting
11791                        + " mBooted=" + mBooted
11792                        + " mFactoryTest=" + mFactoryTest);
11793                pw.print("  mLastPowerCheckRealtime=");
11794                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11795                        pw.println("");
11796                pw.print("  mLastPowerCheckUptime=");
11797                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11798                        pw.println("");
11799                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11800                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11801                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11802                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11803                        + " (" + mLruProcesses.size() + " total)"
11804                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11805                        + " mNumServiceProcs=" + mNumServiceProcs
11806                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11807                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11808                        + " mLastMemoryLevel" + mLastMemoryLevel
11809                        + " mLastNumProcesses" + mLastNumProcesses);
11810                long now = SystemClock.uptimeMillis();
11811                pw.print("  mLastIdleTime=");
11812                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11813                        pw.print(" mLowRamSinceLastIdle=");
11814                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11815                        pw.println();
11816            }
11817        }
11818
11819        if (!printedAnything) {
11820            pw.println("  (nothing)");
11821        }
11822    }
11823
11824    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11825            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11826        if (mProcessesToGc.size() > 0) {
11827            boolean printed = false;
11828            long now = SystemClock.uptimeMillis();
11829            for (int i=0; i<mProcessesToGc.size(); i++) {
11830                ProcessRecord proc = mProcessesToGc.get(i);
11831                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11832                    continue;
11833                }
11834                if (!printed) {
11835                    if (needSep) pw.println();
11836                    needSep = true;
11837                    pw.println("  Processes that are waiting to GC:");
11838                    printed = true;
11839                }
11840                pw.print("    Process "); pw.println(proc);
11841                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11842                        pw.print(", last gced=");
11843                        pw.print(now-proc.lastRequestedGc);
11844                        pw.print(" ms ago, last lowMem=");
11845                        pw.print(now-proc.lastLowMemory);
11846                        pw.println(" ms ago");
11847
11848            }
11849        }
11850        return needSep;
11851    }
11852
11853    void printOomLevel(PrintWriter pw, String name, int adj) {
11854        pw.print("    ");
11855        if (adj >= 0) {
11856            pw.print(' ');
11857            if (adj < 10) pw.print(' ');
11858        } else {
11859            if (adj > -10) pw.print(' ');
11860        }
11861        pw.print(adj);
11862        pw.print(": ");
11863        pw.print(name);
11864        pw.print(" (");
11865        pw.print(mProcessList.getMemLevel(adj)/1024);
11866        pw.println(" kB)");
11867    }
11868
11869    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11870            int opti, boolean dumpAll) {
11871        boolean needSep = false;
11872
11873        if (mLruProcesses.size() > 0) {
11874            if (needSep) pw.println();
11875            needSep = true;
11876            pw.println("  OOM levels:");
11877            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11878            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11879            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11880            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11881            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11882            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11883            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11884            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11885            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11886            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11887            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11888            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11889            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11890
11891            if (needSep) pw.println();
11892            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11893                    pw.print(" total, non-act at ");
11894                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11895                    pw.print(", non-svc at ");
11896                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11897                    pw.println("):");
11898            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11899            needSep = true;
11900        }
11901
11902        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11903
11904        pw.println();
11905        pw.println("  mHomeProcess: " + mHomeProcess);
11906        pw.println("  mPreviousProcess: " + mPreviousProcess);
11907        if (mHeavyWeightProcess != null) {
11908            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11909        }
11910
11911        return true;
11912    }
11913
11914    /**
11915     * There are three ways to call this:
11916     *  - no provider specified: dump all the providers
11917     *  - a flattened component name that matched an existing provider was specified as the
11918     *    first arg: dump that one provider
11919     *  - the first arg isn't the flattened component name of an existing provider:
11920     *    dump all providers whose component contains the first arg as a substring
11921     */
11922    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11923            int opti, boolean dumpAll) {
11924        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11925    }
11926
11927    static class ItemMatcher {
11928        ArrayList<ComponentName> components;
11929        ArrayList<String> strings;
11930        ArrayList<Integer> objects;
11931        boolean all;
11932
11933        ItemMatcher() {
11934            all = true;
11935        }
11936
11937        void build(String name) {
11938            ComponentName componentName = ComponentName.unflattenFromString(name);
11939            if (componentName != null) {
11940                if (components == null) {
11941                    components = new ArrayList<ComponentName>();
11942                }
11943                components.add(componentName);
11944                all = false;
11945            } else {
11946                int objectId = 0;
11947                // Not a '/' separated full component name; maybe an object ID?
11948                try {
11949                    objectId = Integer.parseInt(name, 16);
11950                    if (objects == null) {
11951                        objects = new ArrayList<Integer>();
11952                    }
11953                    objects.add(objectId);
11954                    all = false;
11955                } catch (RuntimeException e) {
11956                    // Not an integer; just do string match.
11957                    if (strings == null) {
11958                        strings = new ArrayList<String>();
11959                    }
11960                    strings.add(name);
11961                    all = false;
11962                }
11963            }
11964        }
11965
11966        int build(String[] args, int opti) {
11967            for (; opti<args.length; opti++) {
11968                String name = args[opti];
11969                if ("--".equals(name)) {
11970                    return opti+1;
11971                }
11972                build(name);
11973            }
11974            return opti;
11975        }
11976
11977        boolean match(Object object, ComponentName comp) {
11978            if (all) {
11979                return true;
11980            }
11981            if (components != null) {
11982                for (int i=0; i<components.size(); i++) {
11983                    if (components.get(i).equals(comp)) {
11984                        return true;
11985                    }
11986                }
11987            }
11988            if (objects != null) {
11989                for (int i=0; i<objects.size(); i++) {
11990                    if (System.identityHashCode(object) == objects.get(i)) {
11991                        return true;
11992                    }
11993                }
11994            }
11995            if (strings != null) {
11996                String flat = comp.flattenToString();
11997                for (int i=0; i<strings.size(); i++) {
11998                    if (flat.contains(strings.get(i))) {
11999                        return true;
12000                    }
12001                }
12002            }
12003            return false;
12004        }
12005    }
12006
12007    /**
12008     * There are three things that cmd can be:
12009     *  - a flattened component name that matches an existing activity
12010     *  - the cmd arg isn't the flattened component name of an existing activity:
12011     *    dump all activity whose component contains the cmd as a substring
12012     *  - A hex number of the ActivityRecord object instance.
12013     */
12014    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12015            int opti, boolean dumpAll) {
12016        ArrayList<ActivityRecord> activities;
12017
12018        synchronized (this) {
12019            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12020        }
12021
12022        if (activities.size() <= 0) {
12023            return false;
12024        }
12025
12026        String[] newArgs = new String[args.length - opti];
12027        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12028
12029        TaskRecord lastTask = null;
12030        boolean needSep = false;
12031        for (int i=activities.size()-1; i>=0; i--) {
12032            ActivityRecord r = activities.get(i);
12033            if (needSep) {
12034                pw.println();
12035            }
12036            needSep = true;
12037            synchronized (this) {
12038                if (lastTask != r.task) {
12039                    lastTask = r.task;
12040                    pw.print("TASK "); pw.print(lastTask.affinity);
12041                            pw.print(" id="); pw.println(lastTask.taskId);
12042                    if (dumpAll) {
12043                        lastTask.dump(pw, "  ");
12044                    }
12045                }
12046            }
12047            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12048        }
12049        return true;
12050    }
12051
12052    /**
12053     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12054     * there is a thread associated with the activity.
12055     */
12056    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12057            final ActivityRecord r, String[] args, boolean dumpAll) {
12058        String innerPrefix = prefix + "  ";
12059        synchronized (this) {
12060            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12061                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12062                    pw.print(" pid=");
12063                    if (r.app != null) pw.println(r.app.pid);
12064                    else pw.println("(not running)");
12065            if (dumpAll) {
12066                r.dump(pw, innerPrefix);
12067            }
12068        }
12069        if (r.app != null && r.app.thread != null) {
12070            // flush anything that is already in the PrintWriter since the thread is going
12071            // to write to the file descriptor directly
12072            pw.flush();
12073            try {
12074                TransferPipe tp = new TransferPipe();
12075                try {
12076                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12077                            r.appToken, innerPrefix, args);
12078                    tp.go(fd);
12079                } finally {
12080                    tp.kill();
12081                }
12082            } catch (IOException e) {
12083                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12084            } catch (RemoteException e) {
12085                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12086            }
12087        }
12088    }
12089
12090    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12091            int opti, boolean dumpAll, String dumpPackage) {
12092        boolean needSep = false;
12093        boolean onlyHistory = false;
12094        boolean printedAnything = false;
12095
12096        if ("history".equals(dumpPackage)) {
12097            if (opti < args.length && "-s".equals(args[opti])) {
12098                dumpAll = false;
12099            }
12100            onlyHistory = true;
12101            dumpPackage = null;
12102        }
12103
12104        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12105        if (!onlyHistory && dumpAll) {
12106            if (mRegisteredReceivers.size() > 0) {
12107                boolean printed = false;
12108                Iterator it = mRegisteredReceivers.values().iterator();
12109                while (it.hasNext()) {
12110                    ReceiverList r = (ReceiverList)it.next();
12111                    if (dumpPackage != null && (r.app == null ||
12112                            !dumpPackage.equals(r.app.info.packageName))) {
12113                        continue;
12114                    }
12115                    if (!printed) {
12116                        pw.println("  Registered Receivers:");
12117                        needSep = true;
12118                        printed = true;
12119                        printedAnything = true;
12120                    }
12121                    pw.print("  * "); pw.println(r);
12122                    r.dump(pw, "    ");
12123                }
12124            }
12125
12126            if (mReceiverResolver.dump(pw, needSep ?
12127                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12128                    "    ", dumpPackage, false)) {
12129                needSep = true;
12130                printedAnything = true;
12131            }
12132        }
12133
12134        for (BroadcastQueue q : mBroadcastQueues) {
12135            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12136            printedAnything |= needSep;
12137        }
12138
12139        needSep = true;
12140
12141        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12142            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12143                if (needSep) {
12144                    pw.println();
12145                }
12146                needSep = true;
12147                printedAnything = true;
12148                pw.print("  Sticky broadcasts for user ");
12149                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12150                StringBuilder sb = new StringBuilder(128);
12151                for (Map.Entry<String, ArrayList<Intent>> ent
12152                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12153                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12154                    if (dumpAll) {
12155                        pw.println(":");
12156                        ArrayList<Intent> intents = ent.getValue();
12157                        final int N = intents.size();
12158                        for (int i=0; i<N; i++) {
12159                            sb.setLength(0);
12160                            sb.append("    Intent: ");
12161                            intents.get(i).toShortString(sb, false, true, false, false);
12162                            pw.println(sb.toString());
12163                            Bundle bundle = intents.get(i).getExtras();
12164                            if (bundle != null) {
12165                                pw.print("      ");
12166                                pw.println(bundle.toString());
12167                            }
12168                        }
12169                    } else {
12170                        pw.println("");
12171                    }
12172                }
12173            }
12174        }
12175
12176        if (!onlyHistory && dumpAll) {
12177            pw.println();
12178            for (BroadcastQueue queue : mBroadcastQueues) {
12179                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12180                        + queue.mBroadcastsScheduled);
12181            }
12182            pw.println("  mHandler:");
12183            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12184            needSep = true;
12185            printedAnything = true;
12186        }
12187
12188        if (!printedAnything) {
12189            pw.println("  (nothing)");
12190        }
12191    }
12192
12193    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12194            int opti, boolean dumpAll, String dumpPackage) {
12195        boolean needSep;
12196        boolean printedAnything = false;
12197
12198        ItemMatcher matcher = new ItemMatcher();
12199        matcher.build(args, opti);
12200
12201        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12202
12203        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12204        printedAnything |= needSep;
12205
12206        if (mLaunchingProviders.size() > 0) {
12207            boolean printed = false;
12208            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12209                ContentProviderRecord r = mLaunchingProviders.get(i);
12210                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12211                    continue;
12212                }
12213                if (!printed) {
12214                    if (needSep) pw.println();
12215                    needSep = true;
12216                    pw.println("  Launching content providers:");
12217                    printed = true;
12218                    printedAnything = true;
12219                }
12220                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12221                        pw.println(r);
12222            }
12223        }
12224
12225        if (mGrantedUriPermissions.size() > 0) {
12226            boolean printed = false;
12227            int dumpUid = -2;
12228            if (dumpPackage != null) {
12229                try {
12230                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12231                } catch (NameNotFoundException e) {
12232                    dumpUid = -1;
12233                }
12234            }
12235            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12236                int uid = mGrantedUriPermissions.keyAt(i);
12237                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12238                    continue;
12239                }
12240                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12241                if (!printed) {
12242                    if (needSep) pw.println();
12243                    needSep = true;
12244                    pw.println("  Granted Uri Permissions:");
12245                    printed = true;
12246                    printedAnything = true;
12247                }
12248                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12249                for (UriPermission perm : perms.values()) {
12250                    pw.print("    "); pw.println(perm);
12251                    if (dumpAll) {
12252                        perm.dump(pw, "      ");
12253                    }
12254                }
12255            }
12256        }
12257
12258        if (!printedAnything) {
12259            pw.println("  (nothing)");
12260        }
12261    }
12262
12263    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12264            int opti, boolean dumpAll, String dumpPackage) {
12265        boolean printed = false;
12266
12267        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12268
12269        if (mIntentSenderRecords.size() > 0) {
12270            Iterator<WeakReference<PendingIntentRecord>> it
12271                    = mIntentSenderRecords.values().iterator();
12272            while (it.hasNext()) {
12273                WeakReference<PendingIntentRecord> ref = it.next();
12274                PendingIntentRecord rec = ref != null ? ref.get(): null;
12275                if (dumpPackage != null && (rec == null
12276                        || !dumpPackage.equals(rec.key.packageName))) {
12277                    continue;
12278                }
12279                printed = true;
12280                if (rec != null) {
12281                    pw.print("  * "); pw.println(rec);
12282                    if (dumpAll) {
12283                        rec.dump(pw, "    ");
12284                    }
12285                } else {
12286                    pw.print("  * "); pw.println(ref);
12287                }
12288            }
12289        }
12290
12291        if (!printed) {
12292            pw.println("  (nothing)");
12293        }
12294    }
12295
12296    private static final int dumpProcessList(PrintWriter pw,
12297            ActivityManagerService service, List list,
12298            String prefix, String normalLabel, String persistentLabel,
12299            String dumpPackage) {
12300        int numPers = 0;
12301        final int N = list.size()-1;
12302        for (int i=N; i>=0; i--) {
12303            ProcessRecord r = (ProcessRecord)list.get(i);
12304            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12305                continue;
12306            }
12307            pw.println(String.format("%s%s #%2d: %s",
12308                    prefix, (r.persistent ? persistentLabel : normalLabel),
12309                    i, r.toString()));
12310            if (r.persistent) {
12311                numPers++;
12312            }
12313        }
12314        return numPers;
12315    }
12316
12317    private static final boolean dumpProcessOomList(PrintWriter pw,
12318            ActivityManagerService service, List<ProcessRecord> origList,
12319            String prefix, String normalLabel, String persistentLabel,
12320            boolean inclDetails, String dumpPackage) {
12321
12322        ArrayList<Pair<ProcessRecord, Integer>> list
12323                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12324        for (int i=0; i<origList.size(); i++) {
12325            ProcessRecord r = origList.get(i);
12326            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12327                continue;
12328            }
12329            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12330        }
12331
12332        if (list.size() <= 0) {
12333            return false;
12334        }
12335
12336        Comparator<Pair<ProcessRecord, Integer>> comparator
12337                = new Comparator<Pair<ProcessRecord, Integer>>() {
12338            @Override
12339            public int compare(Pair<ProcessRecord, Integer> object1,
12340                    Pair<ProcessRecord, Integer> object2) {
12341                if (object1.first.setAdj != object2.first.setAdj) {
12342                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12343                }
12344                if (object1.second.intValue() != object2.second.intValue()) {
12345                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12346                }
12347                return 0;
12348            }
12349        };
12350
12351        Collections.sort(list, comparator);
12352
12353        final long curRealtime = SystemClock.elapsedRealtime();
12354        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12355        final long curUptime = SystemClock.uptimeMillis();
12356        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12357
12358        for (int i=list.size()-1; i>=0; i--) {
12359            ProcessRecord r = list.get(i).first;
12360            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12361            char schedGroup;
12362            switch (r.setSchedGroup) {
12363                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12364                    schedGroup = 'B';
12365                    break;
12366                case Process.THREAD_GROUP_DEFAULT:
12367                    schedGroup = 'F';
12368                    break;
12369                default:
12370                    schedGroup = '?';
12371                    break;
12372            }
12373            char foreground;
12374            if (r.foregroundActivities) {
12375                foreground = 'A';
12376            } else if (r.foregroundServices) {
12377                foreground = 'S';
12378            } else {
12379                foreground = ' ';
12380            }
12381            String procState = ProcessList.makeProcStateString(r.curProcState);
12382            pw.print(prefix);
12383            pw.print(r.persistent ? persistentLabel : normalLabel);
12384            pw.print(" #");
12385            int num = (origList.size()-1)-list.get(i).second;
12386            if (num < 10) pw.print(' ');
12387            pw.print(num);
12388            pw.print(": ");
12389            pw.print(oomAdj);
12390            pw.print(' ');
12391            pw.print(schedGroup);
12392            pw.print('/');
12393            pw.print(foreground);
12394            pw.print('/');
12395            pw.print(procState);
12396            pw.print(" trm:");
12397            if (r.trimMemoryLevel < 10) pw.print(' ');
12398            pw.print(r.trimMemoryLevel);
12399            pw.print(' ');
12400            pw.print(r.toShortString());
12401            pw.print(" (");
12402            pw.print(r.adjType);
12403            pw.println(')');
12404            if (r.adjSource != null || r.adjTarget != null) {
12405                pw.print(prefix);
12406                pw.print("    ");
12407                if (r.adjTarget instanceof ComponentName) {
12408                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12409                } else if (r.adjTarget != null) {
12410                    pw.print(r.adjTarget.toString());
12411                } else {
12412                    pw.print("{null}");
12413                }
12414                pw.print("<=");
12415                if (r.adjSource instanceof ProcessRecord) {
12416                    pw.print("Proc{");
12417                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12418                    pw.println("}");
12419                } else if (r.adjSource != null) {
12420                    pw.println(r.adjSource.toString());
12421                } else {
12422                    pw.println("{null}");
12423                }
12424            }
12425            if (inclDetails) {
12426                pw.print(prefix);
12427                pw.print("    ");
12428                pw.print("oom: max="); pw.print(r.maxAdj);
12429                pw.print(" curRaw="); pw.print(r.curRawAdj);
12430                pw.print(" setRaw="); pw.print(r.setRawAdj);
12431                pw.print(" cur="); pw.print(r.curAdj);
12432                pw.print(" set="); pw.println(r.setAdj);
12433                pw.print(prefix);
12434                pw.print("    ");
12435                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12436                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12437                pw.print(" lastPss="); pw.print(r.lastPss);
12438                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12439                pw.print(prefix);
12440                pw.print("    ");
12441                pw.print("cached="); pw.print(r.cached);
12442                pw.print(" empty="); pw.print(r.empty);
12443                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12444
12445                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12446                    if (r.lastWakeTime != 0) {
12447                        long wtime;
12448                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12449                        synchronized (stats) {
12450                            wtime = stats.getProcessWakeTime(r.info.uid,
12451                                    r.pid, curRealtime);
12452                        }
12453                        long timeUsed = wtime - r.lastWakeTime;
12454                        pw.print(prefix);
12455                        pw.print("    ");
12456                        pw.print("keep awake over ");
12457                        TimeUtils.formatDuration(realtimeSince, pw);
12458                        pw.print(" used ");
12459                        TimeUtils.formatDuration(timeUsed, pw);
12460                        pw.print(" (");
12461                        pw.print((timeUsed*100)/realtimeSince);
12462                        pw.println("%)");
12463                    }
12464                    if (r.lastCpuTime != 0) {
12465                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12466                        pw.print(prefix);
12467                        pw.print("    ");
12468                        pw.print("run cpu over ");
12469                        TimeUtils.formatDuration(uptimeSince, pw);
12470                        pw.print(" used ");
12471                        TimeUtils.formatDuration(timeUsed, pw);
12472                        pw.print(" (");
12473                        pw.print((timeUsed*100)/uptimeSince);
12474                        pw.println("%)");
12475                    }
12476                }
12477            }
12478        }
12479        return true;
12480    }
12481
12482    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12483        ArrayList<ProcessRecord> procs;
12484        synchronized (this) {
12485            if (args != null && args.length > start
12486                    && args[start].charAt(0) != '-') {
12487                procs = new ArrayList<ProcessRecord>();
12488                int pid = -1;
12489                try {
12490                    pid = Integer.parseInt(args[start]);
12491                } catch (NumberFormatException e) {
12492                }
12493                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12494                    ProcessRecord proc = mLruProcesses.get(i);
12495                    if (proc.pid == pid) {
12496                        procs.add(proc);
12497                    } else if (proc.processName.equals(args[start])) {
12498                        procs.add(proc);
12499                    }
12500                }
12501                if (procs.size() <= 0) {
12502                    return null;
12503                }
12504            } else {
12505                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12506            }
12507        }
12508        return procs;
12509    }
12510
12511    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12512            PrintWriter pw, String[] args) {
12513        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12514        if (procs == null) {
12515            pw.println("No process found for: " + args[0]);
12516            return;
12517        }
12518
12519        long uptime = SystemClock.uptimeMillis();
12520        long realtime = SystemClock.elapsedRealtime();
12521        pw.println("Applications Graphics Acceleration Info:");
12522        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12523
12524        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12525            ProcessRecord r = procs.get(i);
12526            if (r.thread != null) {
12527                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12528                pw.flush();
12529                try {
12530                    TransferPipe tp = new TransferPipe();
12531                    try {
12532                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12533                        tp.go(fd);
12534                    } finally {
12535                        tp.kill();
12536                    }
12537                } catch (IOException e) {
12538                    pw.println("Failure while dumping the app: " + r);
12539                    pw.flush();
12540                } catch (RemoteException e) {
12541                    pw.println("Got a RemoteException while dumping the app " + r);
12542                    pw.flush();
12543                }
12544            }
12545        }
12546    }
12547
12548    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12549        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12550        if (procs == null) {
12551            pw.println("No process found for: " + args[0]);
12552            return;
12553        }
12554
12555        pw.println("Applications Database Info:");
12556
12557        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12558            ProcessRecord r = procs.get(i);
12559            if (r.thread != null) {
12560                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12561                pw.flush();
12562                try {
12563                    TransferPipe tp = new TransferPipe();
12564                    try {
12565                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12566                        tp.go(fd);
12567                    } finally {
12568                        tp.kill();
12569                    }
12570                } catch (IOException e) {
12571                    pw.println("Failure while dumping the app: " + r);
12572                    pw.flush();
12573                } catch (RemoteException e) {
12574                    pw.println("Got a RemoteException while dumping the app " + r);
12575                    pw.flush();
12576                }
12577            }
12578        }
12579    }
12580
12581    final static class MemItem {
12582        final boolean isProc;
12583        final String label;
12584        final String shortLabel;
12585        final long pss;
12586        final int id;
12587        final boolean hasActivities;
12588        ArrayList<MemItem> subitems;
12589
12590        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12591                boolean _hasActivities) {
12592            isProc = true;
12593            label = _label;
12594            shortLabel = _shortLabel;
12595            pss = _pss;
12596            id = _id;
12597            hasActivities = _hasActivities;
12598        }
12599
12600        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12601            isProc = false;
12602            label = _label;
12603            shortLabel = _shortLabel;
12604            pss = _pss;
12605            id = _id;
12606            hasActivities = false;
12607        }
12608    }
12609
12610    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12611            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12612        if (sort && !isCompact) {
12613            Collections.sort(items, new Comparator<MemItem>() {
12614                @Override
12615                public int compare(MemItem lhs, MemItem rhs) {
12616                    if (lhs.pss < rhs.pss) {
12617                        return 1;
12618                    } else if (lhs.pss > rhs.pss) {
12619                        return -1;
12620                    }
12621                    return 0;
12622                }
12623            });
12624        }
12625
12626        for (int i=0; i<items.size(); i++) {
12627            MemItem mi = items.get(i);
12628            if (!isCompact) {
12629                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12630            } else if (mi.isProc) {
12631                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12632                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12633                pw.println(mi.hasActivities ? ",a" : ",e");
12634            } else {
12635                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12636                pw.println(mi.pss);
12637            }
12638            if (mi.subitems != null) {
12639                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12640                        true, isCompact);
12641            }
12642        }
12643    }
12644
12645    // These are in KB.
12646    static final long[] DUMP_MEM_BUCKETS = new long[] {
12647        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12648        120*1024, 160*1024, 200*1024,
12649        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12650        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12651    };
12652
12653    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12654            boolean stackLike) {
12655        int start = label.lastIndexOf('.');
12656        if (start >= 0) start++;
12657        else start = 0;
12658        int end = label.length();
12659        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12660            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12661                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12662                out.append(bucket);
12663                out.append(stackLike ? "MB." : "MB ");
12664                out.append(label, start, end);
12665                return;
12666            }
12667        }
12668        out.append(memKB/1024);
12669        out.append(stackLike ? "MB." : "MB ");
12670        out.append(label, start, end);
12671    }
12672
12673    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12674            ProcessList.NATIVE_ADJ,
12675            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12676            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12677            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12678            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12679            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12680    };
12681    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12682            "Native",
12683            "System", "Persistent", "Foreground",
12684            "Visible", "Perceptible",
12685            "Heavy Weight", "Backup",
12686            "A Services", "Home",
12687            "Previous", "B Services", "Cached"
12688    };
12689    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12690            "native",
12691            "sys", "pers", "fore",
12692            "vis", "percept",
12693            "heavy", "backup",
12694            "servicea", "home",
12695            "prev", "serviceb", "cached"
12696    };
12697
12698    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12699            long realtime, boolean isCheckinRequest, boolean isCompact) {
12700        if (isCheckinRequest || isCompact) {
12701            // short checkin version
12702            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12703        } else {
12704            pw.println("Applications Memory Usage (kB):");
12705            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12706        }
12707    }
12708
12709    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12710            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12711        boolean dumpDetails = false;
12712        boolean dumpFullDetails = false;
12713        boolean dumpDalvik = false;
12714        boolean oomOnly = false;
12715        boolean isCompact = false;
12716        boolean localOnly = false;
12717
12718        int opti = 0;
12719        while (opti < args.length) {
12720            String opt = args[opti];
12721            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12722                break;
12723            }
12724            opti++;
12725            if ("-a".equals(opt)) {
12726                dumpDetails = true;
12727                dumpFullDetails = true;
12728                dumpDalvik = true;
12729            } else if ("-d".equals(opt)) {
12730                dumpDalvik = true;
12731            } else if ("-c".equals(opt)) {
12732                isCompact = true;
12733            } else if ("--oom".equals(opt)) {
12734                oomOnly = true;
12735            } else if ("--local".equals(opt)) {
12736                localOnly = true;
12737            } else if ("-h".equals(opt)) {
12738                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12739                pw.println("  -a: include all available information for each process.");
12740                pw.println("  -d: include dalvik details when dumping process details.");
12741                pw.println("  -c: dump in a compact machine-parseable representation.");
12742                pw.println("  --oom: only show processes organized by oom adj.");
12743                pw.println("  --local: only collect details locally, don't call process.");
12744                pw.println("If [process] is specified it can be the name or ");
12745                pw.println("pid of a specific process to dump.");
12746                return;
12747            } else {
12748                pw.println("Unknown argument: " + opt + "; use -h for help");
12749            }
12750        }
12751
12752        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12753        long uptime = SystemClock.uptimeMillis();
12754        long realtime = SystemClock.elapsedRealtime();
12755        final long[] tmpLong = new long[1];
12756
12757        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12758        if (procs == null) {
12759            // No Java processes.  Maybe they want to print a native process.
12760            if (args != null && args.length > opti
12761                    && args[opti].charAt(0) != '-') {
12762                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12763                        = new ArrayList<ProcessCpuTracker.Stats>();
12764                updateCpuStatsNow();
12765                int findPid = -1;
12766                try {
12767                    findPid = Integer.parseInt(args[opti]);
12768                } catch (NumberFormatException e) {
12769                }
12770                synchronized (mProcessCpuThread) {
12771                    final int N = mProcessCpuTracker.countStats();
12772                    for (int i=0; i<N; i++) {
12773                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12774                        if (st.pid == findPid || (st.baseName != null
12775                                && st.baseName.equals(args[opti]))) {
12776                            nativeProcs.add(st);
12777                        }
12778                    }
12779                }
12780                if (nativeProcs.size() > 0) {
12781                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12782                            isCompact);
12783                    Debug.MemoryInfo mi = null;
12784                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12785                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12786                        final int pid = r.pid;
12787                        if (!isCheckinRequest && dumpDetails) {
12788                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12789                        }
12790                        if (mi == null) {
12791                            mi = new Debug.MemoryInfo();
12792                        }
12793                        if (dumpDetails || (!brief && !oomOnly)) {
12794                            Debug.getMemoryInfo(pid, mi);
12795                        } else {
12796                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12797                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12798                        }
12799                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12800                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12801                        if (isCheckinRequest) {
12802                            pw.println();
12803                        }
12804                    }
12805                    return;
12806                }
12807            }
12808            pw.println("No process found for: " + args[opti]);
12809            return;
12810        }
12811
12812        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12813            dumpDetails = true;
12814        }
12815
12816        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12817
12818        String[] innerArgs = new String[args.length-opti];
12819        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12820
12821        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12822        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12823        long nativePss=0, dalvikPss=0, otherPss=0;
12824        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12825
12826        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12827        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12828                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12829
12830        long totalPss = 0;
12831        long cachedPss = 0;
12832
12833        Debug.MemoryInfo mi = null;
12834        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12835            final ProcessRecord r = procs.get(i);
12836            final IApplicationThread thread;
12837            final int pid;
12838            final int oomAdj;
12839            final boolean hasActivities;
12840            synchronized (this) {
12841                thread = r.thread;
12842                pid = r.pid;
12843                oomAdj = r.getSetAdjWithServices();
12844                hasActivities = r.activities.size() > 0;
12845            }
12846            if (thread != null) {
12847                if (!isCheckinRequest && dumpDetails) {
12848                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12849                }
12850                if (mi == null) {
12851                    mi = new Debug.MemoryInfo();
12852                }
12853                if (dumpDetails || (!brief && !oomOnly)) {
12854                    Debug.getMemoryInfo(pid, mi);
12855                } else {
12856                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12857                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12858                }
12859                if (dumpDetails) {
12860                    if (localOnly) {
12861                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12862                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12863                        if (isCheckinRequest) {
12864                            pw.println();
12865                        }
12866                    } else {
12867                        try {
12868                            pw.flush();
12869                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12870                                    dumpDalvik, innerArgs);
12871                        } catch (RemoteException e) {
12872                            if (!isCheckinRequest) {
12873                                pw.println("Got RemoteException!");
12874                                pw.flush();
12875                            }
12876                        }
12877                    }
12878                }
12879
12880                final long myTotalPss = mi.getTotalPss();
12881                final long myTotalUss = mi.getTotalUss();
12882
12883                synchronized (this) {
12884                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12885                        // Record this for posterity if the process has been stable.
12886                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12887                    }
12888                }
12889
12890                if (!isCheckinRequest && mi != null) {
12891                    totalPss += myTotalPss;
12892                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12893                            (hasActivities ? " / activities)" : ")"),
12894                            r.processName, myTotalPss, pid, hasActivities);
12895                    procMems.add(pssItem);
12896                    procMemsMap.put(pid, pssItem);
12897
12898                    nativePss += mi.nativePss;
12899                    dalvikPss += mi.dalvikPss;
12900                    otherPss += mi.otherPss;
12901                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12902                        long mem = mi.getOtherPss(j);
12903                        miscPss[j] += mem;
12904                        otherPss -= mem;
12905                    }
12906
12907                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12908                        cachedPss += myTotalPss;
12909                    }
12910
12911                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12912                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12913                                || oomIndex == (oomPss.length-1)) {
12914                            oomPss[oomIndex] += myTotalPss;
12915                            if (oomProcs[oomIndex] == null) {
12916                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12917                            }
12918                            oomProcs[oomIndex].add(pssItem);
12919                            break;
12920                        }
12921                    }
12922                }
12923            }
12924        }
12925
12926        long nativeProcTotalPss = 0;
12927
12928        if (!isCheckinRequest && procs.size() > 1) {
12929            // If we are showing aggregations, also look for native processes to
12930            // include so that our aggregations are more accurate.
12931            updateCpuStatsNow();
12932            synchronized (mProcessCpuThread) {
12933                final int N = mProcessCpuTracker.countStats();
12934                for (int i=0; i<N; i++) {
12935                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12936                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12937                        if (mi == null) {
12938                            mi = new Debug.MemoryInfo();
12939                        }
12940                        if (!brief && !oomOnly) {
12941                            Debug.getMemoryInfo(st.pid, mi);
12942                        } else {
12943                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12944                            mi.nativePrivateDirty = (int)tmpLong[0];
12945                        }
12946
12947                        final long myTotalPss = mi.getTotalPss();
12948                        totalPss += myTotalPss;
12949                        nativeProcTotalPss += myTotalPss;
12950
12951                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12952                                st.name, myTotalPss, st.pid, false);
12953                        procMems.add(pssItem);
12954
12955                        nativePss += mi.nativePss;
12956                        dalvikPss += mi.dalvikPss;
12957                        otherPss += mi.otherPss;
12958                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12959                            long mem = mi.getOtherPss(j);
12960                            miscPss[j] += mem;
12961                            otherPss -= mem;
12962                        }
12963                        oomPss[0] += myTotalPss;
12964                        if (oomProcs[0] == null) {
12965                            oomProcs[0] = new ArrayList<MemItem>();
12966                        }
12967                        oomProcs[0].add(pssItem);
12968                    }
12969                }
12970            }
12971
12972            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12973
12974            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12975            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12976            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12977            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12978                String label = Debug.MemoryInfo.getOtherLabel(j);
12979                catMems.add(new MemItem(label, label, miscPss[j], j));
12980            }
12981
12982            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12983            for (int j=0; j<oomPss.length; j++) {
12984                if (oomPss[j] != 0) {
12985                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12986                            : DUMP_MEM_OOM_LABEL[j];
12987                    MemItem item = new MemItem(label, label, oomPss[j],
12988                            DUMP_MEM_OOM_ADJ[j]);
12989                    item.subitems = oomProcs[j];
12990                    oomMems.add(item);
12991                }
12992            }
12993
12994            if (!brief && !oomOnly && !isCompact) {
12995                pw.println();
12996                pw.println("Total PSS by process:");
12997                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12998                pw.println();
12999            }
13000            if (!isCompact) {
13001                pw.println("Total PSS by OOM adjustment:");
13002            }
13003            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13004            if (!brief && !oomOnly) {
13005                PrintWriter out = categoryPw != null ? categoryPw : pw;
13006                if (!isCompact) {
13007                    out.println();
13008                    out.println("Total PSS by category:");
13009                }
13010                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13011            }
13012            if (!isCompact) {
13013                pw.println();
13014            }
13015            MemInfoReader memInfo = new MemInfoReader();
13016            memInfo.readMemInfo();
13017            if (nativeProcTotalPss > 0) {
13018                synchronized (this) {
13019                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13020                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13021                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13022                            nativeProcTotalPss);
13023                }
13024            }
13025            if (!brief) {
13026                if (!isCompact) {
13027                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13028                    pw.print(" kB (status ");
13029                    switch (mLastMemoryLevel) {
13030                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13031                            pw.println("normal)");
13032                            break;
13033                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13034                            pw.println("moderate)");
13035                            break;
13036                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13037                            pw.println("low)");
13038                            break;
13039                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13040                            pw.println("critical)");
13041                            break;
13042                        default:
13043                            pw.print(mLastMemoryLevel);
13044                            pw.println(")");
13045                            break;
13046                    }
13047                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13048                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13049                            pw.print(cachedPss); pw.print(" cached pss + ");
13050                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13051                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13052                } else {
13053                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13054                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13055                            + memInfo.getFreeSizeKb()); pw.print(",");
13056                    pw.println(totalPss - cachedPss);
13057                }
13058            }
13059            if (!isCompact) {
13060                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13061                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13062                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13063                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13064                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13065                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13066                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13067                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13068                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13069                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13070                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13071            }
13072            if (!brief) {
13073                if (memInfo.getZramTotalSizeKb() != 0) {
13074                    if (!isCompact) {
13075                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13076                                pw.print(" kB physical used for ");
13077                                pw.print(memInfo.getSwapTotalSizeKb()
13078                                        - memInfo.getSwapFreeSizeKb());
13079                                pw.print(" kB in swap (");
13080                                pw.print(memInfo.getSwapTotalSizeKb());
13081                                pw.println(" kB total swap)");
13082                    } else {
13083                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13084                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13085                                pw.println(memInfo.getSwapFreeSizeKb());
13086                    }
13087                }
13088                final int[] SINGLE_LONG_FORMAT = new int[] {
13089                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13090                };
13091                long[] longOut = new long[1];
13092                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13093                        SINGLE_LONG_FORMAT, null, longOut, null);
13094                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13095                longOut[0] = 0;
13096                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13097                        SINGLE_LONG_FORMAT, null, longOut, null);
13098                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13099                longOut[0] = 0;
13100                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13101                        SINGLE_LONG_FORMAT, null, longOut, null);
13102                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13103                longOut[0] = 0;
13104                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13105                        SINGLE_LONG_FORMAT, null, longOut, null);
13106                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13107                if (!isCompact) {
13108                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13109                        pw.print("      KSM: "); pw.print(sharing);
13110                                pw.print(" kB saved from shared ");
13111                                pw.print(shared); pw.println(" kB");
13112                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13113                                pw.print(voltile); pw.println(" kB volatile");
13114                    }
13115                    pw.print("   Tuning: ");
13116                    pw.print(ActivityManager.staticGetMemoryClass());
13117                    pw.print(" (large ");
13118                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13119                    pw.print("), oom ");
13120                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13121                    pw.print(" kB");
13122                    pw.print(", restore limit ");
13123                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13124                    pw.print(" kB");
13125                    if (ActivityManager.isLowRamDeviceStatic()) {
13126                        pw.print(" (low-ram)");
13127                    }
13128                    if (ActivityManager.isHighEndGfx()) {
13129                        pw.print(" (high-end-gfx)");
13130                    }
13131                    pw.println();
13132                } else {
13133                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13134                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13135                    pw.println(voltile);
13136                    pw.print("tuning,");
13137                    pw.print(ActivityManager.staticGetMemoryClass());
13138                    pw.print(',');
13139                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13140                    pw.print(',');
13141                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13142                    if (ActivityManager.isLowRamDeviceStatic()) {
13143                        pw.print(",low-ram");
13144                    }
13145                    if (ActivityManager.isHighEndGfx()) {
13146                        pw.print(",high-end-gfx");
13147                    }
13148                    pw.println();
13149                }
13150            }
13151        }
13152    }
13153
13154    /**
13155     * Searches array of arguments for the specified string
13156     * @param args array of argument strings
13157     * @param value value to search for
13158     * @return true if the value is contained in the array
13159     */
13160    private static boolean scanArgs(String[] args, String value) {
13161        if (args != null) {
13162            for (String arg : args) {
13163                if (value.equals(arg)) {
13164                    return true;
13165                }
13166            }
13167        }
13168        return false;
13169    }
13170
13171    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13172            ContentProviderRecord cpr, boolean always) {
13173        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13174
13175        if (!inLaunching || always) {
13176            synchronized (cpr) {
13177                cpr.launchingApp = null;
13178                cpr.notifyAll();
13179            }
13180            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13181            String names[] = cpr.info.authority.split(";");
13182            for (int j = 0; j < names.length; j++) {
13183                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13184            }
13185        }
13186
13187        for (int i=0; i<cpr.connections.size(); i++) {
13188            ContentProviderConnection conn = cpr.connections.get(i);
13189            if (conn.waiting) {
13190                // If this connection is waiting for the provider, then we don't
13191                // need to mess with its process unless we are always removing
13192                // or for some reason the provider is not currently launching.
13193                if (inLaunching && !always) {
13194                    continue;
13195                }
13196            }
13197            ProcessRecord capp = conn.client;
13198            conn.dead = true;
13199            if (conn.stableCount > 0) {
13200                if (!capp.persistent && capp.thread != null
13201                        && capp.pid != 0
13202                        && capp.pid != MY_PID) {
13203                    killUnneededProcessLocked(capp, "depends on provider "
13204                            + cpr.name.flattenToShortString()
13205                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13206                }
13207            } else if (capp.thread != null && conn.provider.provider != null) {
13208                try {
13209                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13210                } catch (RemoteException e) {
13211                }
13212                // In the protocol here, we don't expect the client to correctly
13213                // clean up this connection, we'll just remove it.
13214                cpr.connections.remove(i);
13215                conn.client.conProviders.remove(conn);
13216            }
13217        }
13218
13219        if (inLaunching && always) {
13220            mLaunchingProviders.remove(cpr);
13221        }
13222        return inLaunching;
13223    }
13224
13225    /**
13226     * Main code for cleaning up a process when it has gone away.  This is
13227     * called both as a result of the process dying, or directly when stopping
13228     * a process when running in single process mode.
13229     */
13230    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13231            boolean restarting, boolean allowRestart, int index) {
13232        if (index >= 0) {
13233            removeLruProcessLocked(app);
13234            ProcessList.remove(app.pid);
13235        }
13236
13237        mProcessesToGc.remove(app);
13238        mPendingPssProcesses.remove(app);
13239
13240        // Dismiss any open dialogs.
13241        if (app.crashDialog != null && !app.forceCrashReport) {
13242            app.crashDialog.dismiss();
13243            app.crashDialog = null;
13244        }
13245        if (app.anrDialog != null) {
13246            app.anrDialog.dismiss();
13247            app.anrDialog = null;
13248        }
13249        if (app.waitDialog != null) {
13250            app.waitDialog.dismiss();
13251            app.waitDialog = null;
13252        }
13253
13254        app.crashing = false;
13255        app.notResponding = false;
13256
13257        app.resetPackageList(mProcessStats);
13258        app.unlinkDeathRecipient();
13259        app.makeInactive(mProcessStats);
13260        app.waitingToKill = null;
13261        app.forcingToForeground = null;
13262        updateProcessForegroundLocked(app, false, false);
13263        app.foregroundActivities = false;
13264        app.hasShownUi = false;
13265        app.treatLikeActivity = false;
13266        app.hasAboveClient = false;
13267        app.hasClientActivities = false;
13268
13269        mServices.killServicesLocked(app, allowRestart);
13270
13271        boolean restart = false;
13272
13273        // Remove published content providers.
13274        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13275            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13276            final boolean always = app.bad || !allowRestart;
13277            if (removeDyingProviderLocked(app, cpr, always) || always) {
13278                // We left the provider in the launching list, need to
13279                // restart it.
13280                restart = true;
13281            }
13282
13283            cpr.provider = null;
13284            cpr.proc = null;
13285        }
13286        app.pubProviders.clear();
13287
13288        // Take care of any launching providers waiting for this process.
13289        if (checkAppInLaunchingProvidersLocked(app, false)) {
13290            restart = true;
13291        }
13292
13293        // Unregister from connected content providers.
13294        if (!app.conProviders.isEmpty()) {
13295            for (int i=0; i<app.conProviders.size(); i++) {
13296                ContentProviderConnection conn = app.conProviders.get(i);
13297                conn.provider.connections.remove(conn);
13298            }
13299            app.conProviders.clear();
13300        }
13301
13302        // At this point there may be remaining entries in mLaunchingProviders
13303        // where we were the only one waiting, so they are no longer of use.
13304        // Look for these and clean up if found.
13305        // XXX Commented out for now.  Trying to figure out a way to reproduce
13306        // the actual situation to identify what is actually going on.
13307        if (false) {
13308            for (int i=0; i<mLaunchingProviders.size(); i++) {
13309                ContentProviderRecord cpr = (ContentProviderRecord)
13310                        mLaunchingProviders.get(i);
13311                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13312                    synchronized (cpr) {
13313                        cpr.launchingApp = null;
13314                        cpr.notifyAll();
13315                    }
13316                }
13317            }
13318        }
13319
13320        skipCurrentReceiverLocked(app);
13321
13322        // Unregister any receivers.
13323        for (int i=app.receivers.size()-1; i>=0; i--) {
13324            removeReceiverLocked(app.receivers.valueAt(i));
13325        }
13326        app.receivers.clear();
13327
13328        // If the app is undergoing backup, tell the backup manager about it
13329        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13330            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13331                    + mBackupTarget.appInfo + " died during backup");
13332            try {
13333                IBackupManager bm = IBackupManager.Stub.asInterface(
13334                        ServiceManager.getService(Context.BACKUP_SERVICE));
13335                bm.agentDisconnected(app.info.packageName);
13336            } catch (RemoteException e) {
13337                // can't happen; backup manager is local
13338            }
13339        }
13340
13341        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13342            ProcessChangeItem item = mPendingProcessChanges.get(i);
13343            if (item.pid == app.pid) {
13344                mPendingProcessChanges.remove(i);
13345                mAvailProcessChanges.add(item);
13346            }
13347        }
13348        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13349
13350        // If the caller is restarting this app, then leave it in its
13351        // current lists and let the caller take care of it.
13352        if (restarting) {
13353            return;
13354        }
13355
13356        if (!app.persistent || app.isolated) {
13357            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13358                    "Removing non-persistent process during cleanup: " + app);
13359            mProcessNames.remove(app.processName, app.uid);
13360            mIsolatedProcesses.remove(app.uid);
13361            if (mHeavyWeightProcess == app) {
13362                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13363                        mHeavyWeightProcess.userId, 0));
13364                mHeavyWeightProcess = null;
13365            }
13366        } else if (!app.removed) {
13367            // This app is persistent, so we need to keep its record around.
13368            // If it is not already on the pending app list, add it there
13369            // and start a new process for it.
13370            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13371                mPersistentStartingProcesses.add(app);
13372                restart = true;
13373            }
13374        }
13375        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13376                "Clean-up removing on hold: " + app);
13377        mProcessesOnHold.remove(app);
13378
13379        if (app == mHomeProcess) {
13380            mHomeProcess = null;
13381        }
13382        if (app == mPreviousProcess) {
13383            mPreviousProcess = null;
13384        }
13385
13386        if (restart && !app.isolated) {
13387            // We have components that still need to be running in the
13388            // process, so re-launch it.
13389            mProcessNames.put(app.processName, app.uid, app);
13390            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13391        } else if (app.pid > 0 && app.pid != MY_PID) {
13392            // Goodbye!
13393            boolean removed;
13394            synchronized (mPidsSelfLocked) {
13395                mPidsSelfLocked.remove(app.pid);
13396                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13397            }
13398            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13399            if (app.isolated) {
13400                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13401            }
13402            app.setPid(0);
13403        }
13404    }
13405
13406    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13407        // Look through the content providers we are waiting to have launched,
13408        // and if any run in this process then either schedule a restart of
13409        // the process or kill the client waiting for it if this process has
13410        // gone bad.
13411        int NL = mLaunchingProviders.size();
13412        boolean restart = false;
13413        for (int i=0; i<NL; i++) {
13414            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13415            if (cpr.launchingApp == app) {
13416                if (!alwaysBad && !app.bad) {
13417                    restart = true;
13418                } else {
13419                    removeDyingProviderLocked(app, cpr, true);
13420                    // cpr should have been removed from mLaunchingProviders
13421                    NL = mLaunchingProviders.size();
13422                    i--;
13423                }
13424            }
13425        }
13426        return restart;
13427    }
13428
13429    // =========================================================
13430    // SERVICES
13431    // =========================================================
13432
13433    @Override
13434    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13435            int flags) {
13436        enforceNotIsolatedCaller("getServices");
13437        synchronized (this) {
13438            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13439        }
13440    }
13441
13442    @Override
13443    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13444        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13445        synchronized (this) {
13446            return mServices.getRunningServiceControlPanelLocked(name);
13447        }
13448    }
13449
13450    @Override
13451    public ComponentName startService(IApplicationThread caller, Intent service,
13452            String resolvedType, int userId) {
13453        enforceNotIsolatedCaller("startService");
13454        // Refuse possible leaked file descriptors
13455        if (service != null && service.hasFileDescriptors() == true) {
13456            throw new IllegalArgumentException("File descriptors passed in Intent");
13457        }
13458
13459        if (DEBUG_SERVICE)
13460            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13461        synchronized(this) {
13462            final int callingPid = Binder.getCallingPid();
13463            final int callingUid = Binder.getCallingUid();
13464            final long origId = Binder.clearCallingIdentity();
13465            ComponentName res = mServices.startServiceLocked(caller, service,
13466                    resolvedType, callingPid, callingUid, userId);
13467            Binder.restoreCallingIdentity(origId);
13468            return res;
13469        }
13470    }
13471
13472    ComponentName startServiceInPackage(int uid,
13473            Intent service, String resolvedType, int userId) {
13474        synchronized(this) {
13475            if (DEBUG_SERVICE)
13476                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13477            final long origId = Binder.clearCallingIdentity();
13478            ComponentName res = mServices.startServiceLocked(null, service,
13479                    resolvedType, -1, uid, userId);
13480            Binder.restoreCallingIdentity(origId);
13481            return res;
13482        }
13483    }
13484
13485    @Override
13486    public int stopService(IApplicationThread caller, Intent service,
13487            String resolvedType, int userId) {
13488        enforceNotIsolatedCaller("stopService");
13489        // Refuse possible leaked file descriptors
13490        if (service != null && service.hasFileDescriptors() == true) {
13491            throw new IllegalArgumentException("File descriptors passed in Intent");
13492        }
13493
13494        synchronized(this) {
13495            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13496        }
13497    }
13498
13499    @Override
13500    public IBinder peekService(Intent service, String resolvedType) {
13501        enforceNotIsolatedCaller("peekService");
13502        // Refuse possible leaked file descriptors
13503        if (service != null && service.hasFileDescriptors() == true) {
13504            throw new IllegalArgumentException("File descriptors passed in Intent");
13505        }
13506        synchronized(this) {
13507            return mServices.peekServiceLocked(service, resolvedType);
13508        }
13509    }
13510
13511    @Override
13512    public boolean stopServiceToken(ComponentName className, IBinder token,
13513            int startId) {
13514        synchronized(this) {
13515            return mServices.stopServiceTokenLocked(className, token, startId);
13516        }
13517    }
13518
13519    @Override
13520    public void setServiceForeground(ComponentName className, IBinder token,
13521            int id, Notification notification, boolean removeNotification) {
13522        synchronized(this) {
13523            mServices.setServiceForegroundLocked(className, token, id, notification,
13524                    removeNotification);
13525        }
13526    }
13527
13528    @Override
13529    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13530            boolean requireFull, String name, String callerPackage) {
13531        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13532                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13533    }
13534
13535    int unsafeConvertIncomingUser(int userId) {
13536        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13537                ? mCurrentUserId : userId;
13538    }
13539
13540    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13541            int allowMode, String name, String callerPackage) {
13542        final int callingUserId = UserHandle.getUserId(callingUid);
13543        if (callingUserId == userId) {
13544            return userId;
13545        }
13546
13547        // Note that we may be accessing mCurrentUserId outside of a lock...
13548        // shouldn't be a big deal, if this is being called outside
13549        // of a locked context there is intrinsically a race with
13550        // the value the caller will receive and someone else changing it.
13551        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13552        // we will switch to the calling user if access to the current user fails.
13553        int targetUserId = unsafeConvertIncomingUser(userId);
13554
13555        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13556            final boolean allow;
13557            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13558                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13559                // If the caller has this permission, they always pass go.  And collect $200.
13560                allow = true;
13561            } else if (allowMode == ALLOW_FULL_ONLY) {
13562                // We require full access, sucks to be you.
13563                allow = false;
13564            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13565                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13566                // If the caller does not have either permission, they are always doomed.
13567                allow = false;
13568            } else if (allowMode == ALLOW_NON_FULL) {
13569                // We are blanket allowing non-full access, you lucky caller!
13570                allow = true;
13571            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13572                // We may or may not allow this depending on whether the two users are
13573                // in the same profile.
13574                synchronized (mUserProfileGroupIdsSelfLocked) {
13575                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13576                            UserInfo.NO_PROFILE_GROUP_ID);
13577                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13578                            UserInfo.NO_PROFILE_GROUP_ID);
13579                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13580                            && callingProfile == targetProfile;
13581                }
13582            } else {
13583                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13584            }
13585            if (!allow) {
13586                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13587                    // In this case, they would like to just execute as their
13588                    // owner user instead of failing.
13589                    targetUserId = callingUserId;
13590                } else {
13591                    StringBuilder builder = new StringBuilder(128);
13592                    builder.append("Permission Denial: ");
13593                    builder.append(name);
13594                    if (callerPackage != null) {
13595                        builder.append(" from ");
13596                        builder.append(callerPackage);
13597                    }
13598                    builder.append(" asks to run as user ");
13599                    builder.append(userId);
13600                    builder.append(" but is calling from user ");
13601                    builder.append(UserHandle.getUserId(callingUid));
13602                    builder.append("; this requires ");
13603                    builder.append(INTERACT_ACROSS_USERS_FULL);
13604                    if (allowMode != ALLOW_FULL_ONLY) {
13605                        builder.append(" or ");
13606                        builder.append(INTERACT_ACROSS_USERS);
13607                    }
13608                    String msg = builder.toString();
13609                    Slog.w(TAG, msg);
13610                    throw new SecurityException(msg);
13611                }
13612            }
13613        }
13614        if (!allowAll && targetUserId < 0) {
13615            throw new IllegalArgumentException(
13616                    "Call does not support special user #" + targetUserId);
13617        }
13618        return targetUserId;
13619    }
13620
13621    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13622            String className, int flags) {
13623        boolean result = false;
13624        // For apps that don't have pre-defined UIDs, check for permission
13625        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13626            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13627                if (ActivityManager.checkUidPermission(
13628                        INTERACT_ACROSS_USERS,
13629                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13630                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13631                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13632                            + " requests FLAG_SINGLE_USER, but app does not hold "
13633                            + INTERACT_ACROSS_USERS;
13634                    Slog.w(TAG, msg);
13635                    throw new SecurityException(msg);
13636                }
13637                // Permission passed
13638                result = true;
13639            }
13640        } else if ("system".equals(componentProcessName)) {
13641            result = true;
13642        } else {
13643            // App with pre-defined UID, check if it's a persistent app
13644            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13645        }
13646        if (DEBUG_MU) {
13647            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13648                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13649        }
13650        return result;
13651    }
13652
13653    /**
13654     * Checks to see if the caller is in the same app as the singleton
13655     * component, or the component is in a special app. It allows special apps
13656     * to export singleton components but prevents exporting singleton
13657     * components for regular apps.
13658     */
13659    boolean isValidSingletonCall(int callingUid, int componentUid) {
13660        int componentAppId = UserHandle.getAppId(componentUid);
13661        return UserHandle.isSameApp(callingUid, componentUid)
13662                || componentAppId == Process.SYSTEM_UID
13663                || componentAppId == Process.PHONE_UID
13664                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13665                        == PackageManager.PERMISSION_GRANTED;
13666    }
13667
13668    public int bindService(IApplicationThread caller, IBinder token,
13669            Intent service, String resolvedType,
13670            IServiceConnection connection, int flags, int userId) {
13671        enforceNotIsolatedCaller("bindService");
13672        // Refuse possible leaked file descriptors
13673        if (service != null && service.hasFileDescriptors() == true) {
13674            throw new IllegalArgumentException("File descriptors passed in Intent");
13675        }
13676
13677        synchronized(this) {
13678            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13679                    connection, flags, userId);
13680        }
13681    }
13682
13683    public boolean unbindService(IServiceConnection connection) {
13684        synchronized (this) {
13685            return mServices.unbindServiceLocked(connection);
13686        }
13687    }
13688
13689    public void publishService(IBinder token, Intent intent, IBinder service) {
13690        // Refuse possible leaked file descriptors
13691        if (intent != null && intent.hasFileDescriptors() == true) {
13692            throw new IllegalArgumentException("File descriptors passed in Intent");
13693        }
13694
13695        synchronized(this) {
13696            if (!(token instanceof ServiceRecord)) {
13697                throw new IllegalArgumentException("Invalid service token");
13698            }
13699            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13700        }
13701    }
13702
13703    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13704        // Refuse possible leaked file descriptors
13705        if (intent != null && intent.hasFileDescriptors() == true) {
13706            throw new IllegalArgumentException("File descriptors passed in Intent");
13707        }
13708
13709        synchronized(this) {
13710            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13711        }
13712    }
13713
13714    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13715        synchronized(this) {
13716            if (!(token instanceof ServiceRecord)) {
13717                throw new IllegalArgumentException("Invalid service token");
13718            }
13719            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13720        }
13721    }
13722
13723    // =========================================================
13724    // BACKUP AND RESTORE
13725    // =========================================================
13726
13727    // Cause the target app to be launched if necessary and its backup agent
13728    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13729    // activity manager to announce its creation.
13730    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13731        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13732        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13733
13734        synchronized(this) {
13735            // !!! TODO: currently no check here that we're already bound
13736            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13737            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13738            synchronized (stats) {
13739                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13740            }
13741
13742            // Backup agent is now in use, its package can't be stopped.
13743            try {
13744                AppGlobals.getPackageManager().setPackageStoppedState(
13745                        app.packageName, false, UserHandle.getUserId(app.uid));
13746            } catch (RemoteException e) {
13747            } catch (IllegalArgumentException e) {
13748                Slog.w(TAG, "Failed trying to unstop package "
13749                        + app.packageName + ": " + e);
13750            }
13751
13752            BackupRecord r = new BackupRecord(ss, app, backupMode);
13753            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13754                    ? new ComponentName(app.packageName, app.backupAgentName)
13755                    : new ComponentName("android", "FullBackupAgent");
13756            // startProcessLocked() returns existing proc's record if it's already running
13757            ProcessRecord proc = startProcessLocked(app.processName, app,
13758                    false, 0, "backup", hostingName, false, false, false);
13759            if (proc == null) {
13760                Slog.e(TAG, "Unable to start backup agent process " + r);
13761                return false;
13762            }
13763
13764            r.app = proc;
13765            mBackupTarget = r;
13766            mBackupAppName = app.packageName;
13767
13768            // Try not to kill the process during backup
13769            updateOomAdjLocked(proc);
13770
13771            // If the process is already attached, schedule the creation of the backup agent now.
13772            // If it is not yet live, this will be done when it attaches to the framework.
13773            if (proc.thread != null) {
13774                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13775                try {
13776                    proc.thread.scheduleCreateBackupAgent(app,
13777                            compatibilityInfoForPackageLocked(app), backupMode);
13778                } catch (RemoteException e) {
13779                    // Will time out on the backup manager side
13780                }
13781            } else {
13782                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13783            }
13784            // Invariants: at this point, the target app process exists and the application
13785            // is either already running or in the process of coming up.  mBackupTarget and
13786            // mBackupAppName describe the app, so that when it binds back to the AM we
13787            // know that it's scheduled for a backup-agent operation.
13788        }
13789
13790        return true;
13791    }
13792
13793    @Override
13794    public void clearPendingBackup() {
13795        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13796        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13797
13798        synchronized (this) {
13799            mBackupTarget = null;
13800            mBackupAppName = null;
13801        }
13802    }
13803
13804    // A backup agent has just come up
13805    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13806        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13807                + " = " + agent);
13808
13809        synchronized(this) {
13810            if (!agentPackageName.equals(mBackupAppName)) {
13811                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13812                return;
13813            }
13814        }
13815
13816        long oldIdent = Binder.clearCallingIdentity();
13817        try {
13818            IBackupManager bm = IBackupManager.Stub.asInterface(
13819                    ServiceManager.getService(Context.BACKUP_SERVICE));
13820            bm.agentConnected(agentPackageName, agent);
13821        } catch (RemoteException e) {
13822            // can't happen; the backup manager service is local
13823        } catch (Exception e) {
13824            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13825            e.printStackTrace();
13826        } finally {
13827            Binder.restoreCallingIdentity(oldIdent);
13828        }
13829    }
13830
13831    // done with this agent
13832    public void unbindBackupAgent(ApplicationInfo appInfo) {
13833        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13834        if (appInfo == null) {
13835            Slog.w(TAG, "unbind backup agent for null app");
13836            return;
13837        }
13838
13839        synchronized(this) {
13840            try {
13841                if (mBackupAppName == null) {
13842                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13843                    return;
13844                }
13845
13846                if (!mBackupAppName.equals(appInfo.packageName)) {
13847                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13848                    return;
13849                }
13850
13851                // Not backing this app up any more; reset its OOM adjustment
13852                final ProcessRecord proc = mBackupTarget.app;
13853                updateOomAdjLocked(proc);
13854
13855                // If the app crashed during backup, 'thread' will be null here
13856                if (proc.thread != null) {
13857                    try {
13858                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13859                                compatibilityInfoForPackageLocked(appInfo));
13860                    } catch (Exception e) {
13861                        Slog.e(TAG, "Exception when unbinding backup agent:");
13862                        e.printStackTrace();
13863                    }
13864                }
13865            } finally {
13866                mBackupTarget = null;
13867                mBackupAppName = null;
13868            }
13869        }
13870    }
13871    // =========================================================
13872    // BROADCASTS
13873    // =========================================================
13874
13875    private final List getStickiesLocked(String action, IntentFilter filter,
13876            List cur, int userId) {
13877        final ContentResolver resolver = mContext.getContentResolver();
13878        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13879        if (stickies == null) {
13880            return cur;
13881        }
13882        final ArrayList<Intent> list = stickies.get(action);
13883        if (list == null) {
13884            return cur;
13885        }
13886        int N = list.size();
13887        for (int i=0; i<N; i++) {
13888            Intent intent = list.get(i);
13889            if (filter.match(resolver, intent, true, TAG) >= 0) {
13890                if (cur == null) {
13891                    cur = new ArrayList<Intent>();
13892                }
13893                cur.add(intent);
13894            }
13895        }
13896        return cur;
13897    }
13898
13899    boolean isPendingBroadcastProcessLocked(int pid) {
13900        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13901                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13902    }
13903
13904    void skipPendingBroadcastLocked(int pid) {
13905            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13906            for (BroadcastQueue queue : mBroadcastQueues) {
13907                queue.skipPendingBroadcastLocked(pid);
13908            }
13909    }
13910
13911    // The app just attached; send any pending broadcasts that it should receive
13912    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13913        boolean didSomething = false;
13914        for (BroadcastQueue queue : mBroadcastQueues) {
13915            didSomething |= queue.sendPendingBroadcastsLocked(app);
13916        }
13917        return didSomething;
13918    }
13919
13920    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13921            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13922        enforceNotIsolatedCaller("registerReceiver");
13923        int callingUid;
13924        int callingPid;
13925        synchronized(this) {
13926            ProcessRecord callerApp = null;
13927            if (caller != null) {
13928                callerApp = getRecordForAppLocked(caller);
13929                if (callerApp == null) {
13930                    throw new SecurityException(
13931                            "Unable to find app for caller " + caller
13932                            + " (pid=" + Binder.getCallingPid()
13933                            + ") when registering receiver " + receiver);
13934                }
13935                if (callerApp.info.uid != Process.SYSTEM_UID &&
13936                        !callerApp.pkgList.containsKey(callerPackage) &&
13937                        !"android".equals(callerPackage)) {
13938                    throw new SecurityException("Given caller package " + callerPackage
13939                            + " is not running in process " + callerApp);
13940                }
13941                callingUid = callerApp.info.uid;
13942                callingPid = callerApp.pid;
13943            } else {
13944                callerPackage = null;
13945                callingUid = Binder.getCallingUid();
13946                callingPid = Binder.getCallingPid();
13947            }
13948
13949            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13950                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13951
13952            List allSticky = null;
13953
13954            // Look for any matching sticky broadcasts...
13955            Iterator actions = filter.actionsIterator();
13956            if (actions != null) {
13957                while (actions.hasNext()) {
13958                    String action = (String)actions.next();
13959                    allSticky = getStickiesLocked(action, filter, allSticky,
13960                            UserHandle.USER_ALL);
13961                    allSticky = getStickiesLocked(action, filter, allSticky,
13962                            UserHandle.getUserId(callingUid));
13963                }
13964            } else {
13965                allSticky = getStickiesLocked(null, filter, allSticky,
13966                        UserHandle.USER_ALL);
13967                allSticky = getStickiesLocked(null, filter, allSticky,
13968                        UserHandle.getUserId(callingUid));
13969            }
13970
13971            // The first sticky in the list is returned directly back to
13972            // the client.
13973            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13974
13975            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13976                    + ": " + sticky);
13977
13978            if (receiver == null) {
13979                return sticky;
13980            }
13981
13982            ReceiverList rl
13983                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13984            if (rl == null) {
13985                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13986                        userId, receiver);
13987                if (rl.app != null) {
13988                    rl.app.receivers.add(rl);
13989                } else {
13990                    try {
13991                        receiver.asBinder().linkToDeath(rl, 0);
13992                    } catch (RemoteException e) {
13993                        return sticky;
13994                    }
13995                    rl.linkedToDeath = true;
13996                }
13997                mRegisteredReceivers.put(receiver.asBinder(), rl);
13998            } else if (rl.uid != callingUid) {
13999                throw new IllegalArgumentException(
14000                        "Receiver requested to register for uid " + callingUid
14001                        + " was previously registered for uid " + rl.uid);
14002            } else if (rl.pid != callingPid) {
14003                throw new IllegalArgumentException(
14004                        "Receiver requested to register for pid " + callingPid
14005                        + " was previously registered for pid " + rl.pid);
14006            } else if (rl.userId != userId) {
14007                throw new IllegalArgumentException(
14008                        "Receiver requested to register for user " + userId
14009                        + " was previously registered for user " + rl.userId);
14010            }
14011            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14012                    permission, callingUid, userId);
14013            rl.add(bf);
14014            if (!bf.debugCheck()) {
14015                Slog.w(TAG, "==> For Dynamic broadast");
14016            }
14017            mReceiverResolver.addFilter(bf);
14018
14019            // Enqueue broadcasts for all existing stickies that match
14020            // this filter.
14021            if (allSticky != null) {
14022                ArrayList receivers = new ArrayList();
14023                receivers.add(bf);
14024
14025                int N = allSticky.size();
14026                for (int i=0; i<N; i++) {
14027                    Intent intent = (Intent)allSticky.get(i);
14028                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14029                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14030                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14031                            null, null, false, true, true, -1);
14032                    queue.enqueueParallelBroadcastLocked(r);
14033                    queue.scheduleBroadcastsLocked();
14034                }
14035            }
14036
14037            return sticky;
14038        }
14039    }
14040
14041    public void unregisterReceiver(IIntentReceiver receiver) {
14042        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14043
14044        final long origId = Binder.clearCallingIdentity();
14045        try {
14046            boolean doTrim = false;
14047
14048            synchronized(this) {
14049                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14050                if (rl != null) {
14051                    if (rl.curBroadcast != null) {
14052                        BroadcastRecord r = rl.curBroadcast;
14053                        final boolean doNext = finishReceiverLocked(
14054                                receiver.asBinder(), r.resultCode, r.resultData,
14055                                r.resultExtras, r.resultAbort);
14056                        if (doNext) {
14057                            doTrim = true;
14058                            r.queue.processNextBroadcast(false);
14059                        }
14060                    }
14061
14062                    if (rl.app != null) {
14063                        rl.app.receivers.remove(rl);
14064                    }
14065                    removeReceiverLocked(rl);
14066                    if (rl.linkedToDeath) {
14067                        rl.linkedToDeath = false;
14068                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14069                    }
14070                }
14071            }
14072
14073            // If we actually concluded any broadcasts, we might now be able
14074            // to trim the recipients' apps from our working set
14075            if (doTrim) {
14076                trimApplications();
14077                return;
14078            }
14079
14080        } finally {
14081            Binder.restoreCallingIdentity(origId);
14082        }
14083    }
14084
14085    void removeReceiverLocked(ReceiverList rl) {
14086        mRegisteredReceivers.remove(rl.receiver.asBinder());
14087        int N = rl.size();
14088        for (int i=0; i<N; i++) {
14089            mReceiverResolver.removeFilter(rl.get(i));
14090        }
14091    }
14092
14093    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14094        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14095            ProcessRecord r = mLruProcesses.get(i);
14096            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14097                try {
14098                    r.thread.dispatchPackageBroadcast(cmd, packages);
14099                } catch (RemoteException ex) {
14100                }
14101            }
14102        }
14103    }
14104
14105    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14106            int[] users) {
14107        List<ResolveInfo> receivers = null;
14108        try {
14109            HashSet<ComponentName> singleUserReceivers = null;
14110            boolean scannedFirstReceivers = false;
14111            for (int user : users) {
14112                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14113                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14114                if (user != 0 && newReceivers != null) {
14115                    // If this is not the primary user, we need to check for
14116                    // any receivers that should be filtered out.
14117                    for (int i=0; i<newReceivers.size(); i++) {
14118                        ResolveInfo ri = newReceivers.get(i);
14119                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14120                            newReceivers.remove(i);
14121                            i--;
14122                        }
14123                    }
14124                }
14125                if (newReceivers != null && newReceivers.size() == 0) {
14126                    newReceivers = null;
14127                }
14128                if (receivers == null) {
14129                    receivers = newReceivers;
14130                } else if (newReceivers != null) {
14131                    // We need to concatenate the additional receivers
14132                    // found with what we have do far.  This would be easy,
14133                    // but we also need to de-dup any receivers that are
14134                    // singleUser.
14135                    if (!scannedFirstReceivers) {
14136                        // Collect any single user receivers we had already retrieved.
14137                        scannedFirstReceivers = true;
14138                        for (int i=0; i<receivers.size(); i++) {
14139                            ResolveInfo ri = receivers.get(i);
14140                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14141                                ComponentName cn = new ComponentName(
14142                                        ri.activityInfo.packageName, ri.activityInfo.name);
14143                                if (singleUserReceivers == null) {
14144                                    singleUserReceivers = new HashSet<ComponentName>();
14145                                }
14146                                singleUserReceivers.add(cn);
14147                            }
14148                        }
14149                    }
14150                    // Add the new results to the existing results, tracking
14151                    // and de-dupping single user receivers.
14152                    for (int i=0; i<newReceivers.size(); i++) {
14153                        ResolveInfo ri = newReceivers.get(i);
14154                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14155                            ComponentName cn = new ComponentName(
14156                                    ri.activityInfo.packageName, ri.activityInfo.name);
14157                            if (singleUserReceivers == null) {
14158                                singleUserReceivers = new HashSet<ComponentName>();
14159                            }
14160                            if (!singleUserReceivers.contains(cn)) {
14161                                singleUserReceivers.add(cn);
14162                                receivers.add(ri);
14163                            }
14164                        } else {
14165                            receivers.add(ri);
14166                        }
14167                    }
14168                }
14169            }
14170        } catch (RemoteException ex) {
14171            // pm is in same process, this will never happen.
14172        }
14173        return receivers;
14174    }
14175
14176    private final int broadcastIntentLocked(ProcessRecord callerApp,
14177            String callerPackage, Intent intent, String resolvedType,
14178            IIntentReceiver resultTo, int resultCode, String resultData,
14179            Bundle map, String requiredPermission, int appOp,
14180            boolean ordered, boolean sticky, int callingPid, int callingUid,
14181            int userId) {
14182        intent = new Intent(intent);
14183
14184        // By default broadcasts do not go to stopped apps.
14185        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14186
14187        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14188            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14189            + " ordered=" + ordered + " userid=" + userId);
14190        if ((resultTo != null) && !ordered) {
14191            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14192        }
14193
14194        userId = handleIncomingUser(callingPid, callingUid, userId,
14195                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14196
14197        // Make sure that the user who is receiving this broadcast is started.
14198        // If not, we will just skip it.
14199
14200
14201        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14202            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14203                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14204                Slog.w(TAG, "Skipping broadcast of " + intent
14205                        + ": user " + userId + " is stopped");
14206                return ActivityManager.BROADCAST_SUCCESS;
14207            }
14208        }
14209
14210        /*
14211         * Prevent non-system code (defined here to be non-persistent
14212         * processes) from sending protected broadcasts.
14213         */
14214        int callingAppId = UserHandle.getAppId(callingUid);
14215        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14216            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14217            || callingAppId == Process.NFC_UID || callingUid == 0) {
14218            // Always okay.
14219        } else if (callerApp == null || !callerApp.persistent) {
14220            try {
14221                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14222                        intent.getAction())) {
14223                    String msg = "Permission Denial: not allowed to send broadcast "
14224                            + intent.getAction() + " from pid="
14225                            + callingPid + ", uid=" + callingUid;
14226                    Slog.w(TAG, msg);
14227                    throw new SecurityException(msg);
14228                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14229                    // Special case for compatibility: we don't want apps to send this,
14230                    // but historically it has not been protected and apps may be using it
14231                    // to poke their own app widget.  So, instead of making it protected,
14232                    // just limit it to the caller.
14233                    if (callerApp == null) {
14234                        String msg = "Permission Denial: not allowed to send broadcast "
14235                                + intent.getAction() + " from unknown caller.";
14236                        Slog.w(TAG, msg);
14237                        throw new SecurityException(msg);
14238                    } else if (intent.getComponent() != null) {
14239                        // They are good enough to send to an explicit component...  verify
14240                        // it is being sent to the calling app.
14241                        if (!intent.getComponent().getPackageName().equals(
14242                                callerApp.info.packageName)) {
14243                            String msg = "Permission Denial: not allowed to send broadcast "
14244                                    + intent.getAction() + " to "
14245                                    + intent.getComponent().getPackageName() + " from "
14246                                    + callerApp.info.packageName;
14247                            Slog.w(TAG, msg);
14248                            throw new SecurityException(msg);
14249                        }
14250                    } else {
14251                        // Limit broadcast to their own package.
14252                        intent.setPackage(callerApp.info.packageName);
14253                    }
14254                }
14255            } catch (RemoteException e) {
14256                Slog.w(TAG, "Remote exception", e);
14257                return ActivityManager.BROADCAST_SUCCESS;
14258            }
14259        }
14260
14261        // Handle special intents: if this broadcast is from the package
14262        // manager about a package being removed, we need to remove all of
14263        // its activities from the history stack.
14264        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14265                intent.getAction());
14266        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14267                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14268                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14269                || uidRemoved) {
14270            if (checkComponentPermission(
14271                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14272                    callingPid, callingUid, -1, true)
14273                    == PackageManager.PERMISSION_GRANTED) {
14274                if (uidRemoved) {
14275                    final Bundle intentExtras = intent.getExtras();
14276                    final int uid = intentExtras != null
14277                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14278                    if (uid >= 0) {
14279                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14280                        synchronized (bs) {
14281                            bs.removeUidStatsLocked(uid);
14282                        }
14283                        mAppOpsService.uidRemoved(uid);
14284                    }
14285                } else {
14286                    // If resources are unavailable just force stop all
14287                    // those packages and flush the attribute cache as well.
14288                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14289                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14290                        if (list != null && (list.length > 0)) {
14291                            for (String pkg : list) {
14292                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14293                                        "storage unmount");
14294                            }
14295                            sendPackageBroadcastLocked(
14296                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14297                        }
14298                    } else {
14299                        Uri data = intent.getData();
14300                        String ssp;
14301                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14302                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14303                                    intent.getAction());
14304                            boolean fullUninstall = removed &&
14305                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14306                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14307                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14308                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14309                                        false, fullUninstall, userId,
14310                                        removed ? "pkg removed" : "pkg changed");
14311                            }
14312                            if (removed) {
14313                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14314                                        new String[] {ssp}, userId);
14315                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14316                                    mAppOpsService.packageRemoved(
14317                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14318
14319                                    // Remove all permissions granted from/to this package
14320                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14321                                }
14322                            }
14323                        }
14324                    }
14325                }
14326            } else {
14327                String msg = "Permission Denial: " + intent.getAction()
14328                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14329                        + ", uid=" + callingUid + ")"
14330                        + " requires "
14331                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14332                Slog.w(TAG, msg);
14333                throw new SecurityException(msg);
14334            }
14335
14336        // Special case for adding a package: by default turn on compatibility
14337        // mode.
14338        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14339            Uri data = intent.getData();
14340            String ssp;
14341            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14342                mCompatModePackages.handlePackageAddedLocked(ssp,
14343                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14344            }
14345        }
14346
14347        /*
14348         * If this is the time zone changed action, queue up a message that will reset the timezone
14349         * of all currently running processes. This message will get queued up before the broadcast
14350         * happens.
14351         */
14352        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14353            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14354        }
14355
14356        /*
14357         * If the user set the time, let all running processes know.
14358         */
14359        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14360            final int is24Hour = intent.getBooleanExtra(
14361                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14362            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14363        }
14364
14365        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14366            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14367        }
14368
14369        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14370            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14371            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14372        }
14373
14374        // Add to the sticky list if requested.
14375        if (sticky) {
14376            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14377                    callingPid, callingUid)
14378                    != PackageManager.PERMISSION_GRANTED) {
14379                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14380                        + callingPid + ", uid=" + callingUid
14381                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14382                Slog.w(TAG, msg);
14383                throw new SecurityException(msg);
14384            }
14385            if (requiredPermission != null) {
14386                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14387                        + " and enforce permission " + requiredPermission);
14388                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14389            }
14390            if (intent.getComponent() != null) {
14391                throw new SecurityException(
14392                        "Sticky broadcasts can't target a specific component");
14393            }
14394            // We use userId directly here, since the "all" target is maintained
14395            // as a separate set of sticky broadcasts.
14396            if (userId != UserHandle.USER_ALL) {
14397                // But first, if this is not a broadcast to all users, then
14398                // make sure it doesn't conflict with an existing broadcast to
14399                // all users.
14400                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14401                        UserHandle.USER_ALL);
14402                if (stickies != null) {
14403                    ArrayList<Intent> list = stickies.get(intent.getAction());
14404                    if (list != null) {
14405                        int N = list.size();
14406                        int i;
14407                        for (i=0; i<N; i++) {
14408                            if (intent.filterEquals(list.get(i))) {
14409                                throw new IllegalArgumentException(
14410                                        "Sticky broadcast " + intent + " for user "
14411                                        + userId + " conflicts with existing global broadcast");
14412                            }
14413                        }
14414                    }
14415                }
14416            }
14417            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14418            if (stickies == null) {
14419                stickies = new ArrayMap<String, ArrayList<Intent>>();
14420                mStickyBroadcasts.put(userId, stickies);
14421            }
14422            ArrayList<Intent> list = stickies.get(intent.getAction());
14423            if (list == null) {
14424                list = new ArrayList<Intent>();
14425                stickies.put(intent.getAction(), list);
14426            }
14427            int N = list.size();
14428            int i;
14429            for (i=0; i<N; i++) {
14430                if (intent.filterEquals(list.get(i))) {
14431                    // This sticky already exists, replace it.
14432                    list.set(i, new Intent(intent));
14433                    break;
14434                }
14435            }
14436            if (i >= N) {
14437                list.add(new Intent(intent));
14438            }
14439        }
14440
14441        int[] users;
14442        if (userId == UserHandle.USER_ALL) {
14443            // Caller wants broadcast to go to all started users.
14444            users = mStartedUserArray;
14445        } else {
14446            // Caller wants broadcast to go to one specific user.
14447            users = new int[] {userId};
14448        }
14449
14450        // Figure out who all will receive this broadcast.
14451        List receivers = null;
14452        List<BroadcastFilter> registeredReceivers = null;
14453        // Need to resolve the intent to interested receivers...
14454        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14455                 == 0) {
14456            receivers = collectReceiverComponents(intent, resolvedType, users);
14457        }
14458        if (intent.getComponent() == null) {
14459            registeredReceivers = mReceiverResolver.queryIntent(intent,
14460                    resolvedType, false, userId);
14461        }
14462
14463        final boolean replacePending =
14464                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14465
14466        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14467                + " replacePending=" + replacePending);
14468
14469        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14470        if (!ordered && NR > 0) {
14471            // If we are not serializing this broadcast, then send the
14472            // registered receivers separately so they don't wait for the
14473            // components to be launched.
14474            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14475            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14476                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14477                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14478                    ordered, sticky, false, userId);
14479            if (DEBUG_BROADCAST) Slog.v(
14480                    TAG, "Enqueueing parallel broadcast " + r);
14481            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14482            if (!replaced) {
14483                queue.enqueueParallelBroadcastLocked(r);
14484                queue.scheduleBroadcastsLocked();
14485            }
14486            registeredReceivers = null;
14487            NR = 0;
14488        }
14489
14490        // Merge into one list.
14491        int ir = 0;
14492        if (receivers != null) {
14493            // A special case for PACKAGE_ADDED: do not allow the package
14494            // being added to see this broadcast.  This prevents them from
14495            // using this as a back door to get run as soon as they are
14496            // installed.  Maybe in the future we want to have a special install
14497            // broadcast or such for apps, but we'd like to deliberately make
14498            // this decision.
14499            String skipPackages[] = null;
14500            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14501                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14502                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14503                Uri data = intent.getData();
14504                if (data != null) {
14505                    String pkgName = data.getSchemeSpecificPart();
14506                    if (pkgName != null) {
14507                        skipPackages = new String[] { pkgName };
14508                    }
14509                }
14510            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14511                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14512            }
14513            if (skipPackages != null && (skipPackages.length > 0)) {
14514                for (String skipPackage : skipPackages) {
14515                    if (skipPackage != null) {
14516                        int NT = receivers.size();
14517                        for (int it=0; it<NT; it++) {
14518                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14519                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14520                                receivers.remove(it);
14521                                it--;
14522                                NT--;
14523                            }
14524                        }
14525                    }
14526                }
14527            }
14528
14529            int NT = receivers != null ? receivers.size() : 0;
14530            int it = 0;
14531            ResolveInfo curt = null;
14532            BroadcastFilter curr = null;
14533            while (it < NT && ir < NR) {
14534                if (curt == null) {
14535                    curt = (ResolveInfo)receivers.get(it);
14536                }
14537                if (curr == null) {
14538                    curr = registeredReceivers.get(ir);
14539                }
14540                if (curr.getPriority() >= curt.priority) {
14541                    // Insert this broadcast record into the final list.
14542                    receivers.add(it, curr);
14543                    ir++;
14544                    curr = null;
14545                    it++;
14546                    NT++;
14547                } else {
14548                    // Skip to the next ResolveInfo in the final list.
14549                    it++;
14550                    curt = null;
14551                }
14552            }
14553        }
14554        while (ir < NR) {
14555            if (receivers == null) {
14556                receivers = new ArrayList();
14557            }
14558            receivers.add(registeredReceivers.get(ir));
14559            ir++;
14560        }
14561
14562        if ((receivers != null && receivers.size() > 0)
14563                || resultTo != null) {
14564            BroadcastQueue queue = broadcastQueueForIntent(intent);
14565            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14566                    callerPackage, callingPid, callingUid, resolvedType,
14567                    requiredPermission, appOp, receivers, resultTo, resultCode,
14568                    resultData, map, ordered, sticky, false, userId);
14569            if (DEBUG_BROADCAST) Slog.v(
14570                    TAG, "Enqueueing ordered broadcast " + r
14571                    + ": prev had " + queue.mOrderedBroadcasts.size());
14572            if (DEBUG_BROADCAST) {
14573                int seq = r.intent.getIntExtra("seq", -1);
14574                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14575            }
14576            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14577            if (!replaced) {
14578                queue.enqueueOrderedBroadcastLocked(r);
14579                queue.scheduleBroadcastsLocked();
14580            }
14581        }
14582
14583        return ActivityManager.BROADCAST_SUCCESS;
14584    }
14585
14586    final Intent verifyBroadcastLocked(Intent intent) {
14587        // Refuse possible leaked file descriptors
14588        if (intent != null && intent.hasFileDescriptors() == true) {
14589            throw new IllegalArgumentException("File descriptors passed in Intent");
14590        }
14591
14592        int flags = intent.getFlags();
14593
14594        if (!mProcessesReady) {
14595            // if the caller really truly claims to know what they're doing, go
14596            // ahead and allow the broadcast without launching any receivers
14597            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14598                intent = new Intent(intent);
14599                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14600            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14601                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14602                        + " before boot completion");
14603                throw new IllegalStateException("Cannot broadcast before boot completed");
14604            }
14605        }
14606
14607        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14608            throw new IllegalArgumentException(
14609                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14610        }
14611
14612        return intent;
14613    }
14614
14615    public final int broadcastIntent(IApplicationThread caller,
14616            Intent intent, String resolvedType, IIntentReceiver resultTo,
14617            int resultCode, String resultData, Bundle map,
14618            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14619        enforceNotIsolatedCaller("broadcastIntent");
14620        synchronized(this) {
14621            intent = verifyBroadcastLocked(intent);
14622
14623            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14624            final int callingPid = Binder.getCallingPid();
14625            final int callingUid = Binder.getCallingUid();
14626            final long origId = Binder.clearCallingIdentity();
14627            int res = broadcastIntentLocked(callerApp,
14628                    callerApp != null ? callerApp.info.packageName : null,
14629                    intent, resolvedType, resultTo,
14630                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14631                    callingPid, callingUid, userId);
14632            Binder.restoreCallingIdentity(origId);
14633            return res;
14634        }
14635    }
14636
14637    int broadcastIntentInPackage(String packageName, int uid,
14638            Intent intent, String resolvedType, IIntentReceiver resultTo,
14639            int resultCode, String resultData, Bundle map,
14640            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14641        synchronized(this) {
14642            intent = verifyBroadcastLocked(intent);
14643
14644            final long origId = Binder.clearCallingIdentity();
14645            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14646                    resultTo, resultCode, resultData, map, requiredPermission,
14647                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14648            Binder.restoreCallingIdentity(origId);
14649            return res;
14650        }
14651    }
14652
14653    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14654        // Refuse possible leaked file descriptors
14655        if (intent != null && intent.hasFileDescriptors() == true) {
14656            throw new IllegalArgumentException("File descriptors passed in Intent");
14657        }
14658
14659        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14660                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14661
14662        synchronized(this) {
14663            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14664                    != PackageManager.PERMISSION_GRANTED) {
14665                String msg = "Permission Denial: unbroadcastIntent() from pid="
14666                        + Binder.getCallingPid()
14667                        + ", uid=" + Binder.getCallingUid()
14668                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14669                Slog.w(TAG, msg);
14670                throw new SecurityException(msg);
14671            }
14672            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14673            if (stickies != null) {
14674                ArrayList<Intent> list = stickies.get(intent.getAction());
14675                if (list != null) {
14676                    int N = list.size();
14677                    int i;
14678                    for (i=0; i<N; i++) {
14679                        if (intent.filterEquals(list.get(i))) {
14680                            list.remove(i);
14681                            break;
14682                        }
14683                    }
14684                    if (list.size() <= 0) {
14685                        stickies.remove(intent.getAction());
14686                    }
14687                }
14688                if (stickies.size() <= 0) {
14689                    mStickyBroadcasts.remove(userId);
14690                }
14691            }
14692        }
14693    }
14694
14695    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14696            String resultData, Bundle resultExtras, boolean resultAbort) {
14697        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14698        if (r == null) {
14699            Slog.w(TAG, "finishReceiver called but not found on queue");
14700            return false;
14701        }
14702
14703        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14704    }
14705
14706    void backgroundServicesFinishedLocked(int userId) {
14707        for (BroadcastQueue queue : mBroadcastQueues) {
14708            queue.backgroundServicesFinishedLocked(userId);
14709        }
14710    }
14711
14712    public void finishReceiver(IBinder who, int resultCode, String resultData,
14713            Bundle resultExtras, boolean resultAbort) {
14714        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14715
14716        // Refuse possible leaked file descriptors
14717        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14718            throw new IllegalArgumentException("File descriptors passed in Bundle");
14719        }
14720
14721        final long origId = Binder.clearCallingIdentity();
14722        try {
14723            boolean doNext = false;
14724            BroadcastRecord r;
14725
14726            synchronized(this) {
14727                r = broadcastRecordForReceiverLocked(who);
14728                if (r != null) {
14729                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14730                        resultData, resultExtras, resultAbort, true);
14731                }
14732            }
14733
14734            if (doNext) {
14735                r.queue.processNextBroadcast(false);
14736            }
14737            trimApplications();
14738        } finally {
14739            Binder.restoreCallingIdentity(origId);
14740        }
14741    }
14742
14743    // =========================================================
14744    // INSTRUMENTATION
14745    // =========================================================
14746
14747    public boolean startInstrumentation(ComponentName className,
14748            String profileFile, int flags, Bundle arguments,
14749            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14750            int userId, String abiOverride) {
14751        enforceNotIsolatedCaller("startInstrumentation");
14752        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14753                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14754        // Refuse possible leaked file descriptors
14755        if (arguments != null && arguments.hasFileDescriptors()) {
14756            throw new IllegalArgumentException("File descriptors passed in Bundle");
14757        }
14758
14759        synchronized(this) {
14760            InstrumentationInfo ii = null;
14761            ApplicationInfo ai = null;
14762            try {
14763                ii = mContext.getPackageManager().getInstrumentationInfo(
14764                    className, STOCK_PM_FLAGS);
14765                ai = AppGlobals.getPackageManager().getApplicationInfo(
14766                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14767            } catch (PackageManager.NameNotFoundException e) {
14768            } catch (RemoteException e) {
14769            }
14770            if (ii == null) {
14771                reportStartInstrumentationFailure(watcher, className,
14772                        "Unable to find instrumentation info for: " + className);
14773                return false;
14774            }
14775            if (ai == null) {
14776                reportStartInstrumentationFailure(watcher, className,
14777                        "Unable to find instrumentation target package: " + ii.targetPackage);
14778                return false;
14779            }
14780
14781            int match = mContext.getPackageManager().checkSignatures(
14782                    ii.targetPackage, ii.packageName);
14783            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14784                String msg = "Permission Denial: starting instrumentation "
14785                        + className + " from pid="
14786                        + Binder.getCallingPid()
14787                        + ", uid=" + Binder.getCallingPid()
14788                        + " not allowed because package " + ii.packageName
14789                        + " does not have a signature matching the target "
14790                        + ii.targetPackage;
14791                reportStartInstrumentationFailure(watcher, className, msg);
14792                throw new SecurityException(msg);
14793            }
14794
14795            final long origId = Binder.clearCallingIdentity();
14796            // Instrumentation can kill and relaunch even persistent processes
14797            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14798                    "start instr");
14799            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14800            app.instrumentationClass = className;
14801            app.instrumentationInfo = ai;
14802            app.instrumentationProfileFile = profileFile;
14803            app.instrumentationArguments = arguments;
14804            app.instrumentationWatcher = watcher;
14805            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14806            app.instrumentationResultClass = className;
14807            Binder.restoreCallingIdentity(origId);
14808        }
14809
14810        return true;
14811    }
14812
14813    /**
14814     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14815     * error to the logs, but if somebody is watching, send the report there too.  This enables
14816     * the "am" command to report errors with more information.
14817     *
14818     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14819     * @param cn The component name of the instrumentation.
14820     * @param report The error report.
14821     */
14822    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14823            ComponentName cn, String report) {
14824        Slog.w(TAG, report);
14825        try {
14826            if (watcher != null) {
14827                Bundle results = new Bundle();
14828                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14829                results.putString("Error", report);
14830                watcher.instrumentationStatus(cn, -1, results);
14831            }
14832        } catch (RemoteException e) {
14833            Slog.w(TAG, e);
14834        }
14835    }
14836
14837    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14838        if (app.instrumentationWatcher != null) {
14839            try {
14840                // NOTE:  IInstrumentationWatcher *must* be oneway here
14841                app.instrumentationWatcher.instrumentationFinished(
14842                    app.instrumentationClass,
14843                    resultCode,
14844                    results);
14845            } catch (RemoteException e) {
14846            }
14847        }
14848        if (app.instrumentationUiAutomationConnection != null) {
14849            try {
14850                app.instrumentationUiAutomationConnection.shutdown();
14851            } catch (RemoteException re) {
14852                /* ignore */
14853            }
14854            // Only a UiAutomation can set this flag and now that
14855            // it is finished we make sure it is reset to its default.
14856            mUserIsMonkey = false;
14857        }
14858        app.instrumentationWatcher = null;
14859        app.instrumentationUiAutomationConnection = null;
14860        app.instrumentationClass = null;
14861        app.instrumentationInfo = null;
14862        app.instrumentationProfileFile = null;
14863        app.instrumentationArguments = null;
14864
14865        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14866                "finished inst");
14867    }
14868
14869    public void finishInstrumentation(IApplicationThread target,
14870            int resultCode, Bundle results) {
14871        int userId = UserHandle.getCallingUserId();
14872        // Refuse possible leaked file descriptors
14873        if (results != null && results.hasFileDescriptors()) {
14874            throw new IllegalArgumentException("File descriptors passed in Intent");
14875        }
14876
14877        synchronized(this) {
14878            ProcessRecord app = getRecordForAppLocked(target);
14879            if (app == null) {
14880                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14881                return;
14882            }
14883            final long origId = Binder.clearCallingIdentity();
14884            finishInstrumentationLocked(app, resultCode, results);
14885            Binder.restoreCallingIdentity(origId);
14886        }
14887    }
14888
14889    // =========================================================
14890    // CONFIGURATION
14891    // =========================================================
14892
14893    public ConfigurationInfo getDeviceConfigurationInfo() {
14894        ConfigurationInfo config = new ConfigurationInfo();
14895        synchronized (this) {
14896            config.reqTouchScreen = mConfiguration.touchscreen;
14897            config.reqKeyboardType = mConfiguration.keyboard;
14898            config.reqNavigation = mConfiguration.navigation;
14899            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14900                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14901                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14902            }
14903            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14904                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14905                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14906            }
14907            config.reqGlEsVersion = GL_ES_VERSION;
14908        }
14909        return config;
14910    }
14911
14912    ActivityStack getFocusedStack() {
14913        return mStackSupervisor.getFocusedStack();
14914    }
14915
14916    public Configuration getConfiguration() {
14917        Configuration ci;
14918        synchronized(this) {
14919            ci = new Configuration(mConfiguration);
14920        }
14921        return ci;
14922    }
14923
14924    public void updatePersistentConfiguration(Configuration values) {
14925        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14926                "updateConfiguration()");
14927        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14928                "updateConfiguration()");
14929        if (values == null) {
14930            throw new NullPointerException("Configuration must not be null");
14931        }
14932
14933        synchronized(this) {
14934            final long origId = Binder.clearCallingIdentity();
14935            updateConfigurationLocked(values, null, true, false);
14936            Binder.restoreCallingIdentity(origId);
14937        }
14938    }
14939
14940    public void updateConfiguration(Configuration values) {
14941        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14942                "updateConfiguration()");
14943
14944        synchronized(this) {
14945            if (values == null && mWindowManager != null) {
14946                // sentinel: fetch the current configuration from the window manager
14947                values = mWindowManager.computeNewConfiguration();
14948            }
14949
14950            if (mWindowManager != null) {
14951                mProcessList.applyDisplaySize(mWindowManager);
14952            }
14953
14954            final long origId = Binder.clearCallingIdentity();
14955            if (values != null) {
14956                Settings.System.clearConfiguration(values);
14957            }
14958            updateConfigurationLocked(values, null, false, false);
14959            Binder.restoreCallingIdentity(origId);
14960        }
14961    }
14962
14963    /**
14964     * Do either or both things: (1) change the current configuration, and (2)
14965     * make sure the given activity is running with the (now) current
14966     * configuration.  Returns true if the activity has been left running, or
14967     * false if <var>starting</var> is being destroyed to match the new
14968     * configuration.
14969     * @param persistent TODO
14970     */
14971    boolean updateConfigurationLocked(Configuration values,
14972            ActivityRecord starting, boolean persistent, boolean initLocale) {
14973        int changes = 0;
14974
14975        if (values != null) {
14976            Configuration newConfig = new Configuration(mConfiguration);
14977            changes = newConfig.updateFrom(values);
14978            if (changes != 0) {
14979                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14980                    Slog.i(TAG, "Updating configuration to: " + values);
14981                }
14982
14983                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14984
14985                if (values.locale != null && !initLocale) {
14986                    saveLocaleLocked(values.locale,
14987                                     !values.locale.equals(mConfiguration.locale),
14988                                     values.userSetLocale);
14989                }
14990
14991                mConfigurationSeq++;
14992                if (mConfigurationSeq <= 0) {
14993                    mConfigurationSeq = 1;
14994                }
14995                newConfig.seq = mConfigurationSeq;
14996                mConfiguration = newConfig;
14997                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14998                //mUsageStatsService.noteStartConfig(newConfig);
14999
15000                final Configuration configCopy = new Configuration(mConfiguration);
15001
15002                // TODO: If our config changes, should we auto dismiss any currently
15003                // showing dialogs?
15004                mShowDialogs = shouldShowDialogs(newConfig);
15005
15006                AttributeCache ac = AttributeCache.instance();
15007                if (ac != null) {
15008                    ac.updateConfiguration(configCopy);
15009                }
15010
15011                // Make sure all resources in our process are updated
15012                // right now, so that anyone who is going to retrieve
15013                // resource values after we return will be sure to get
15014                // the new ones.  This is especially important during
15015                // boot, where the first config change needs to guarantee
15016                // all resources have that config before following boot
15017                // code is executed.
15018                mSystemThread.applyConfigurationToResources(configCopy);
15019
15020                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15021                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15022                    msg.obj = new Configuration(configCopy);
15023                    mHandler.sendMessage(msg);
15024                }
15025
15026                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15027                    ProcessRecord app = mLruProcesses.get(i);
15028                    try {
15029                        if (app.thread != null) {
15030                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15031                                    + app.processName + " new config " + mConfiguration);
15032                            app.thread.scheduleConfigurationChanged(configCopy);
15033                        }
15034                    } catch (Exception e) {
15035                    }
15036                }
15037                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15038                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15039                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15040                        | Intent.FLAG_RECEIVER_FOREGROUND);
15041                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15042                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15043                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15044                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15045                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15046                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15047                    broadcastIntentLocked(null, null, intent,
15048                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15049                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15050                }
15051            }
15052        }
15053
15054        boolean kept = true;
15055        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15056        // mainStack is null during startup.
15057        if (mainStack != null) {
15058            if (changes != 0 && starting == null) {
15059                // If the configuration changed, and the caller is not already
15060                // in the process of starting an activity, then find the top
15061                // activity to check if its configuration needs to change.
15062                starting = mainStack.topRunningActivityLocked(null);
15063            }
15064
15065            if (starting != null) {
15066                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15067                // And we need to make sure at this point that all other activities
15068                // are made visible with the correct configuration.
15069                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15070            }
15071        }
15072
15073        if (values != null && mWindowManager != null) {
15074            mWindowManager.setNewConfiguration(mConfiguration);
15075        }
15076
15077        return kept;
15078    }
15079
15080    /**
15081     * Decide based on the configuration whether we should shouw the ANR,
15082     * crash, etc dialogs.  The idea is that if there is no affordnace to
15083     * press the on-screen buttons, we shouldn't show the dialog.
15084     *
15085     * A thought: SystemUI might also want to get told about this, the Power
15086     * dialog / global actions also might want different behaviors.
15087     */
15088    private static final boolean shouldShowDialogs(Configuration config) {
15089        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15090                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15091    }
15092
15093    /**
15094     * Save the locale.  You must be inside a synchronized (this) block.
15095     */
15096    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15097        if(isDiff) {
15098            SystemProperties.set("user.language", l.getLanguage());
15099            SystemProperties.set("user.region", l.getCountry());
15100        }
15101
15102        if(isPersist) {
15103            SystemProperties.set("persist.sys.language", l.getLanguage());
15104            SystemProperties.set("persist.sys.country", l.getCountry());
15105            SystemProperties.set("persist.sys.localevar", l.getVariant());
15106        }
15107    }
15108
15109    @Override
15110    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15111        ActivityRecord srec = ActivityRecord.forToken(token);
15112        return srec != null && srec.task.affinity != null &&
15113                srec.task.affinity.equals(destAffinity);
15114    }
15115
15116    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15117            Intent resultData) {
15118
15119        synchronized (this) {
15120            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15121            if (stack != null) {
15122                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15123            }
15124            return false;
15125        }
15126    }
15127
15128    public int getLaunchedFromUid(IBinder activityToken) {
15129        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15130        if (srec == null) {
15131            return -1;
15132        }
15133        return srec.launchedFromUid;
15134    }
15135
15136    public String getLaunchedFromPackage(IBinder activityToken) {
15137        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15138        if (srec == null) {
15139            return null;
15140        }
15141        return srec.launchedFromPackage;
15142    }
15143
15144    // =========================================================
15145    // LIFETIME MANAGEMENT
15146    // =========================================================
15147
15148    // Returns which broadcast queue the app is the current [or imminent] receiver
15149    // on, or 'null' if the app is not an active broadcast recipient.
15150    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15151        BroadcastRecord r = app.curReceiver;
15152        if (r != null) {
15153            return r.queue;
15154        }
15155
15156        // It's not the current receiver, but it might be starting up to become one
15157        synchronized (this) {
15158            for (BroadcastQueue queue : mBroadcastQueues) {
15159                r = queue.mPendingBroadcast;
15160                if (r != null && r.curApp == app) {
15161                    // found it; report which queue it's in
15162                    return queue;
15163                }
15164            }
15165        }
15166
15167        return null;
15168    }
15169
15170    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15171            boolean doingAll, long now) {
15172        if (mAdjSeq == app.adjSeq) {
15173            // This adjustment has already been computed.
15174            return app.curRawAdj;
15175        }
15176
15177        if (app.thread == null) {
15178            app.adjSeq = mAdjSeq;
15179            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15180            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15181            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15182        }
15183
15184        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15185        app.adjSource = null;
15186        app.adjTarget = null;
15187        app.empty = false;
15188        app.cached = false;
15189
15190        final int activitiesSize = app.activities.size();
15191
15192        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15193            // The max adjustment doesn't allow this app to be anything
15194            // below foreground, so it is not worth doing work for it.
15195            app.adjType = "fixed";
15196            app.adjSeq = mAdjSeq;
15197            app.curRawAdj = app.maxAdj;
15198            app.foregroundActivities = false;
15199            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15200            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15201            // System processes can do UI, and when they do we want to have
15202            // them trim their memory after the user leaves the UI.  To
15203            // facilitate this, here we need to determine whether or not it
15204            // is currently showing UI.
15205            app.systemNoUi = true;
15206            if (app == TOP_APP) {
15207                app.systemNoUi = false;
15208            } else if (activitiesSize > 0) {
15209                for (int j = 0; j < activitiesSize; j++) {
15210                    final ActivityRecord r = app.activities.get(j);
15211                    if (r.visible) {
15212                        app.systemNoUi = false;
15213                    }
15214                }
15215            }
15216            if (!app.systemNoUi) {
15217                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15218            }
15219            return (app.curAdj=app.maxAdj);
15220        }
15221
15222        app.systemNoUi = false;
15223
15224        // Determine the importance of the process, starting with most
15225        // important to least, and assign an appropriate OOM adjustment.
15226        int adj;
15227        int schedGroup;
15228        int procState;
15229        boolean foregroundActivities = false;
15230        BroadcastQueue queue;
15231        if (app == TOP_APP) {
15232            // The last app on the list is the foreground app.
15233            adj = ProcessList.FOREGROUND_APP_ADJ;
15234            schedGroup = Process.THREAD_GROUP_DEFAULT;
15235            app.adjType = "top-activity";
15236            foregroundActivities = true;
15237            procState = ActivityManager.PROCESS_STATE_TOP;
15238        } else if (app.instrumentationClass != null) {
15239            // Don't want to kill running instrumentation.
15240            adj = ProcessList.FOREGROUND_APP_ADJ;
15241            schedGroup = Process.THREAD_GROUP_DEFAULT;
15242            app.adjType = "instrumentation";
15243            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15244        } else if ((queue = isReceivingBroadcast(app)) != null) {
15245            // An app that is currently receiving a broadcast also
15246            // counts as being in the foreground for OOM killer purposes.
15247            // It's placed in a sched group based on the nature of the
15248            // broadcast as reflected by which queue it's active in.
15249            adj = ProcessList.FOREGROUND_APP_ADJ;
15250            schedGroup = (queue == mFgBroadcastQueue)
15251                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15252            app.adjType = "broadcast";
15253            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15254        } else if (app.executingServices.size() > 0) {
15255            // An app that is currently executing a service callback also
15256            // counts as being in the foreground.
15257            adj = ProcessList.FOREGROUND_APP_ADJ;
15258            schedGroup = app.execServicesFg ?
15259                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15260            app.adjType = "exec-service";
15261            procState = ActivityManager.PROCESS_STATE_SERVICE;
15262            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15263        } else {
15264            // As far as we know the process is empty.  We may change our mind later.
15265            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15266            // At this point we don't actually know the adjustment.  Use the cached adj
15267            // value that the caller wants us to.
15268            adj = cachedAdj;
15269            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15270            app.cached = true;
15271            app.empty = true;
15272            app.adjType = "cch-empty";
15273        }
15274
15275        // Examine all activities if not already foreground.
15276        if (!foregroundActivities && activitiesSize > 0) {
15277            for (int j = 0; j < activitiesSize; j++) {
15278                final ActivityRecord r = app.activities.get(j);
15279                if (r.app != app) {
15280                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15281                            + app + "?!?");
15282                    continue;
15283                }
15284                if (r.visible) {
15285                    // App has a visible activity; only upgrade adjustment.
15286                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15287                        adj = ProcessList.VISIBLE_APP_ADJ;
15288                        app.adjType = "visible";
15289                    }
15290                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15291                        procState = ActivityManager.PROCESS_STATE_TOP;
15292                    }
15293                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15294                    app.cached = false;
15295                    app.empty = false;
15296                    foregroundActivities = true;
15297                    break;
15298                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15299                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15300                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15301                        app.adjType = "pausing";
15302                    }
15303                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15304                        procState = ActivityManager.PROCESS_STATE_TOP;
15305                    }
15306                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15307                    app.cached = false;
15308                    app.empty = false;
15309                    foregroundActivities = true;
15310                } else if (r.state == ActivityState.STOPPING) {
15311                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15312                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15313                        app.adjType = "stopping";
15314                    }
15315                    // For the process state, we will at this point consider the
15316                    // process to be cached.  It will be cached either as an activity
15317                    // or empty depending on whether the activity is finishing.  We do
15318                    // this so that we can treat the process as cached for purposes of
15319                    // memory trimming (determing current memory level, trim command to
15320                    // send to process) since there can be an arbitrary number of stopping
15321                    // processes and they should soon all go into the cached state.
15322                    if (!r.finishing) {
15323                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15324                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15325                        }
15326                    }
15327                    app.cached = false;
15328                    app.empty = false;
15329                    foregroundActivities = true;
15330                } else {
15331                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15332                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15333                        app.adjType = "cch-act";
15334                    }
15335                }
15336            }
15337        }
15338
15339        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15340            if (app.foregroundServices) {
15341                // The user is aware of this app, so make it visible.
15342                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15343                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15344                app.cached = false;
15345                app.adjType = "fg-service";
15346                schedGroup = Process.THREAD_GROUP_DEFAULT;
15347            } else if (app.forcingToForeground != null) {
15348                // The user is aware of this app, so make it visible.
15349                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15350                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15351                app.cached = false;
15352                app.adjType = "force-fg";
15353                app.adjSource = app.forcingToForeground;
15354                schedGroup = Process.THREAD_GROUP_DEFAULT;
15355            }
15356        }
15357
15358        if (app == mHeavyWeightProcess) {
15359            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15360                // We don't want to kill the current heavy-weight process.
15361                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15362                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15363                app.cached = false;
15364                app.adjType = "heavy";
15365            }
15366            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15367                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15368            }
15369        }
15370
15371        if (app == mHomeProcess) {
15372            if (adj > ProcessList.HOME_APP_ADJ) {
15373                // This process is hosting what we currently consider to be the
15374                // home app, so we don't want to let it go into the background.
15375                adj = ProcessList.HOME_APP_ADJ;
15376                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15377                app.cached = false;
15378                app.adjType = "home";
15379            }
15380            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15381                procState = ActivityManager.PROCESS_STATE_HOME;
15382            }
15383        }
15384
15385        if (app == mPreviousProcess && app.activities.size() > 0) {
15386            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15387                // This was the previous process that showed UI to the user.
15388                // We want to try to keep it around more aggressively, to give
15389                // a good experience around switching between two apps.
15390                adj = ProcessList.PREVIOUS_APP_ADJ;
15391                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15392                app.cached = false;
15393                app.adjType = "previous";
15394            }
15395            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15396                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15397            }
15398        }
15399
15400        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15401                + " reason=" + app.adjType);
15402
15403        // By default, we use the computed adjustment.  It may be changed if
15404        // there are applications dependent on our services or providers, but
15405        // this gives us a baseline and makes sure we don't get into an
15406        // infinite recursion.
15407        app.adjSeq = mAdjSeq;
15408        app.curRawAdj = adj;
15409        app.hasStartedServices = false;
15410
15411        if (mBackupTarget != null && app == mBackupTarget.app) {
15412            // If possible we want to avoid killing apps while they're being backed up
15413            if (adj > ProcessList.BACKUP_APP_ADJ) {
15414                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15415                adj = ProcessList.BACKUP_APP_ADJ;
15416                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15417                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15418                }
15419                app.adjType = "backup";
15420                app.cached = false;
15421            }
15422            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15423                procState = ActivityManager.PROCESS_STATE_BACKUP;
15424            }
15425        }
15426
15427        boolean mayBeTop = false;
15428
15429        for (int is = app.services.size()-1;
15430                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15431                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15432                        || procState > ActivityManager.PROCESS_STATE_TOP);
15433                is--) {
15434            ServiceRecord s = app.services.valueAt(is);
15435            if (s.startRequested) {
15436                app.hasStartedServices = true;
15437                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15438                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15439                }
15440                if (app.hasShownUi && app != mHomeProcess) {
15441                    // If this process has shown some UI, let it immediately
15442                    // go to the LRU list because it may be pretty heavy with
15443                    // UI stuff.  We'll tag it with a label just to help
15444                    // debug and understand what is going on.
15445                    if (adj > ProcessList.SERVICE_ADJ) {
15446                        app.adjType = "cch-started-ui-services";
15447                    }
15448                } else {
15449                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15450                        // This service has seen some activity within
15451                        // recent memory, so we will keep its process ahead
15452                        // of the background processes.
15453                        if (adj > ProcessList.SERVICE_ADJ) {
15454                            adj = ProcessList.SERVICE_ADJ;
15455                            app.adjType = "started-services";
15456                            app.cached = false;
15457                        }
15458                    }
15459                    // If we have let the service slide into the background
15460                    // state, still have some text describing what it is doing
15461                    // even though the service no longer has an impact.
15462                    if (adj > ProcessList.SERVICE_ADJ) {
15463                        app.adjType = "cch-started-services";
15464                    }
15465                }
15466            }
15467            for (int conni = s.connections.size()-1;
15468                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15469                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15470                            || procState > ActivityManager.PROCESS_STATE_TOP);
15471                    conni--) {
15472                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15473                for (int i = 0;
15474                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15475                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15476                                || procState > ActivityManager.PROCESS_STATE_TOP);
15477                        i++) {
15478                    // XXX should compute this based on the max of
15479                    // all connected clients.
15480                    ConnectionRecord cr = clist.get(i);
15481                    if (cr.binding.client == app) {
15482                        // Binding to ourself is not interesting.
15483                        continue;
15484                    }
15485                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15486                        ProcessRecord client = cr.binding.client;
15487                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15488                                TOP_APP, doingAll, now);
15489                        int clientProcState = client.curProcState;
15490                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15491                            // If the other app is cached for any reason, for purposes here
15492                            // we are going to consider it empty.  The specific cached state
15493                            // doesn't propagate except under certain conditions.
15494                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15495                        }
15496                        String adjType = null;
15497                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15498                            // Not doing bind OOM management, so treat
15499                            // this guy more like a started service.
15500                            if (app.hasShownUi && app != mHomeProcess) {
15501                                // If this process has shown some UI, let it immediately
15502                                // go to the LRU list because it may be pretty heavy with
15503                                // UI stuff.  We'll tag it with a label just to help
15504                                // debug and understand what is going on.
15505                                if (adj > clientAdj) {
15506                                    adjType = "cch-bound-ui-services";
15507                                }
15508                                app.cached = false;
15509                                clientAdj = adj;
15510                                clientProcState = procState;
15511                            } else {
15512                                if (now >= (s.lastActivity
15513                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15514                                    // This service has not seen activity within
15515                                    // recent memory, so allow it to drop to the
15516                                    // LRU list if there is no other reason to keep
15517                                    // it around.  We'll also tag it with a label just
15518                                    // to help debug and undertand what is going on.
15519                                    if (adj > clientAdj) {
15520                                        adjType = "cch-bound-services";
15521                                    }
15522                                    clientAdj = adj;
15523                                }
15524                            }
15525                        }
15526                        if (adj > clientAdj) {
15527                            // If this process has recently shown UI, and
15528                            // the process that is binding to it is less
15529                            // important than being visible, then we don't
15530                            // care about the binding as much as we care
15531                            // about letting this process get into the LRU
15532                            // list to be killed and restarted if needed for
15533                            // memory.
15534                            if (app.hasShownUi && app != mHomeProcess
15535                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15536                                adjType = "cch-bound-ui-services";
15537                            } else {
15538                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15539                                        |Context.BIND_IMPORTANT)) != 0) {
15540                                    adj = clientAdj;
15541                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15542                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15543                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15544                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15545                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15546                                    adj = clientAdj;
15547                                } else {
15548                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15549                                        adj = ProcessList.VISIBLE_APP_ADJ;
15550                                    }
15551                                }
15552                                if (!client.cached) {
15553                                    app.cached = false;
15554                                }
15555                                adjType = "service";
15556                            }
15557                        }
15558                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15559                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15560                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15561                            }
15562                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15563                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15564                                    // Special handling of clients who are in the top state.
15565                                    // We *may* want to consider this process to be in the
15566                                    // top state as well, but only if there is not another
15567                                    // reason for it to be running.  Being on the top is a
15568                                    // special state, meaning you are specifically running
15569                                    // for the current top app.  If the process is already
15570                                    // running in the background for some other reason, it
15571                                    // is more important to continue considering it to be
15572                                    // in the background state.
15573                                    mayBeTop = true;
15574                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15575                                } else {
15576                                    // Special handling for above-top states (persistent
15577                                    // processes).  These should not bring the current process
15578                                    // into the top state, since they are not on top.  Instead
15579                                    // give them the best state after that.
15580                                    clientProcState =
15581                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15582                                }
15583                            }
15584                        } else {
15585                            if (clientProcState <
15586                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15587                                clientProcState =
15588                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15589                            }
15590                        }
15591                        if (procState > clientProcState) {
15592                            procState = clientProcState;
15593                        }
15594                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15595                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15596                            app.pendingUiClean = true;
15597                        }
15598                        if (adjType != null) {
15599                            app.adjType = adjType;
15600                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15601                                    .REASON_SERVICE_IN_USE;
15602                            app.adjSource = cr.binding.client;
15603                            app.adjSourceProcState = clientProcState;
15604                            app.adjTarget = s.name;
15605                        }
15606                    }
15607                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15608                        app.treatLikeActivity = true;
15609                    }
15610                    final ActivityRecord a = cr.activity;
15611                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15612                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15613                                (a.visible || a.state == ActivityState.RESUMED
15614                                 || a.state == ActivityState.PAUSING)) {
15615                            adj = ProcessList.FOREGROUND_APP_ADJ;
15616                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15617                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15618                            }
15619                            app.cached = false;
15620                            app.adjType = "service";
15621                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15622                                    .REASON_SERVICE_IN_USE;
15623                            app.adjSource = a;
15624                            app.adjSourceProcState = procState;
15625                            app.adjTarget = s.name;
15626                        }
15627                    }
15628                }
15629            }
15630        }
15631
15632        for (int provi = app.pubProviders.size()-1;
15633                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15634                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15635                        || procState > ActivityManager.PROCESS_STATE_TOP);
15636                provi--) {
15637            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15638            for (int i = cpr.connections.size()-1;
15639                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15640                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15641                            || procState > ActivityManager.PROCESS_STATE_TOP);
15642                    i--) {
15643                ContentProviderConnection conn = cpr.connections.get(i);
15644                ProcessRecord client = conn.client;
15645                if (client == app) {
15646                    // Being our own client is not interesting.
15647                    continue;
15648                }
15649                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15650                int clientProcState = client.curProcState;
15651                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15652                    // If the other app is cached for any reason, for purposes here
15653                    // we are going to consider it empty.
15654                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15655                }
15656                if (adj > clientAdj) {
15657                    if (app.hasShownUi && app != mHomeProcess
15658                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15659                        app.adjType = "cch-ui-provider";
15660                    } else {
15661                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15662                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15663                        app.adjType = "provider";
15664                    }
15665                    app.cached &= client.cached;
15666                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15667                            .REASON_PROVIDER_IN_USE;
15668                    app.adjSource = client;
15669                    app.adjSourceProcState = clientProcState;
15670                    app.adjTarget = cpr.name;
15671                }
15672                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15673                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15674                        // Special handling of clients who are in the top state.
15675                        // We *may* want to consider this process to be in the
15676                        // top state as well, but only if there is not another
15677                        // reason for it to be running.  Being on the top is a
15678                        // special state, meaning you are specifically running
15679                        // for the current top app.  If the process is already
15680                        // running in the background for some other reason, it
15681                        // is more important to continue considering it to be
15682                        // in the background state.
15683                        mayBeTop = true;
15684                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15685                    } else {
15686                        // Special handling for above-top states (persistent
15687                        // processes).  These should not bring the current process
15688                        // into the top state, since they are not on top.  Instead
15689                        // give them the best state after that.
15690                        clientProcState =
15691                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15692                    }
15693                }
15694                if (procState > clientProcState) {
15695                    procState = clientProcState;
15696                }
15697                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15698                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15699                }
15700            }
15701            // If the provider has external (non-framework) process
15702            // dependencies, ensure that its adjustment is at least
15703            // FOREGROUND_APP_ADJ.
15704            if (cpr.hasExternalProcessHandles()) {
15705                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15706                    adj = ProcessList.FOREGROUND_APP_ADJ;
15707                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15708                    app.cached = false;
15709                    app.adjType = "provider";
15710                    app.adjTarget = cpr.name;
15711                }
15712                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15713                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15714                }
15715            }
15716        }
15717
15718        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15719            // A client of one of our services or providers is in the top state.  We
15720            // *may* want to be in the top state, but not if we are already running in
15721            // the background for some other reason.  For the decision here, we are going
15722            // to pick out a few specific states that we want to remain in when a client
15723            // is top (states that tend to be longer-term) and otherwise allow it to go
15724            // to the top state.
15725            switch (procState) {
15726                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15727                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15728                case ActivityManager.PROCESS_STATE_SERVICE:
15729                    // These all are longer-term states, so pull them up to the top
15730                    // of the background states, but not all the way to the top state.
15731                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15732                    break;
15733                default:
15734                    // Otherwise, top is a better choice, so take it.
15735                    procState = ActivityManager.PROCESS_STATE_TOP;
15736                    break;
15737            }
15738        }
15739
15740        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15741            if (app.hasClientActivities) {
15742                // This is a cached process, but with client activities.  Mark it so.
15743                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15744                app.adjType = "cch-client-act";
15745            } else if (app.treatLikeActivity) {
15746                // This is a cached process, but somebody wants us to treat it like it has
15747                // an activity, okay!
15748                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15749                app.adjType = "cch-as-act";
15750            }
15751        }
15752
15753        if (adj == ProcessList.SERVICE_ADJ) {
15754            if (doingAll) {
15755                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15756                mNewNumServiceProcs++;
15757                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15758                if (!app.serviceb) {
15759                    // This service isn't far enough down on the LRU list to
15760                    // normally be a B service, but if we are low on RAM and it
15761                    // is large we want to force it down since we would prefer to
15762                    // keep launcher over it.
15763                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15764                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15765                        app.serviceHighRam = true;
15766                        app.serviceb = true;
15767                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15768                    } else {
15769                        mNewNumAServiceProcs++;
15770                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15771                    }
15772                } else {
15773                    app.serviceHighRam = false;
15774                }
15775            }
15776            if (app.serviceb) {
15777                adj = ProcessList.SERVICE_B_ADJ;
15778            }
15779        }
15780
15781        app.curRawAdj = adj;
15782
15783        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15784        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15785        if (adj > app.maxAdj) {
15786            adj = app.maxAdj;
15787            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15788                schedGroup = Process.THREAD_GROUP_DEFAULT;
15789            }
15790        }
15791
15792        // Do final modification to adj.  Everything we do between here and applying
15793        // the final setAdj must be done in this function, because we will also use
15794        // it when computing the final cached adj later.  Note that we don't need to
15795        // worry about this for max adj above, since max adj will always be used to
15796        // keep it out of the cached vaues.
15797        app.curAdj = app.modifyRawOomAdj(adj);
15798        app.curSchedGroup = schedGroup;
15799        app.curProcState = procState;
15800        app.foregroundActivities = foregroundActivities;
15801
15802        return app.curRawAdj;
15803    }
15804
15805    /**
15806     * Schedule PSS collection of a process.
15807     */
15808    void requestPssLocked(ProcessRecord proc, int procState) {
15809        if (mPendingPssProcesses.contains(proc)) {
15810            return;
15811        }
15812        if (mPendingPssProcesses.size() == 0) {
15813            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15814        }
15815        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15816        proc.pssProcState = procState;
15817        mPendingPssProcesses.add(proc);
15818    }
15819
15820    /**
15821     * Schedule PSS collection of all processes.
15822     */
15823    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15824        if (!always) {
15825            if (now < (mLastFullPssTime +
15826                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15827                return;
15828            }
15829        }
15830        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15831        mLastFullPssTime = now;
15832        mFullPssPending = true;
15833        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15834        mPendingPssProcesses.clear();
15835        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15836            ProcessRecord app = mLruProcesses.get(i);
15837            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15838                app.pssProcState = app.setProcState;
15839                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15840                        isSleeping(), now);
15841                mPendingPssProcesses.add(app);
15842            }
15843        }
15844        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15845    }
15846
15847    /**
15848     * Ask a given process to GC right now.
15849     */
15850    final void performAppGcLocked(ProcessRecord app) {
15851        try {
15852            app.lastRequestedGc = SystemClock.uptimeMillis();
15853            if (app.thread != null) {
15854                if (app.reportLowMemory) {
15855                    app.reportLowMemory = false;
15856                    app.thread.scheduleLowMemory();
15857                } else {
15858                    app.thread.processInBackground();
15859                }
15860            }
15861        } catch (Exception e) {
15862            // whatever.
15863        }
15864    }
15865
15866    /**
15867     * Returns true if things are idle enough to perform GCs.
15868     */
15869    private final boolean canGcNowLocked() {
15870        boolean processingBroadcasts = false;
15871        for (BroadcastQueue q : mBroadcastQueues) {
15872            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15873                processingBroadcasts = true;
15874            }
15875        }
15876        return !processingBroadcasts
15877                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15878    }
15879
15880    /**
15881     * Perform GCs on all processes that are waiting for it, but only
15882     * if things are idle.
15883     */
15884    final void performAppGcsLocked() {
15885        final int N = mProcessesToGc.size();
15886        if (N <= 0) {
15887            return;
15888        }
15889        if (canGcNowLocked()) {
15890            while (mProcessesToGc.size() > 0) {
15891                ProcessRecord proc = mProcessesToGc.remove(0);
15892                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15893                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15894                            <= SystemClock.uptimeMillis()) {
15895                        // To avoid spamming the system, we will GC processes one
15896                        // at a time, waiting a few seconds between each.
15897                        performAppGcLocked(proc);
15898                        scheduleAppGcsLocked();
15899                        return;
15900                    } else {
15901                        // It hasn't been long enough since we last GCed this
15902                        // process...  put it in the list to wait for its time.
15903                        addProcessToGcListLocked(proc);
15904                        break;
15905                    }
15906                }
15907            }
15908
15909            scheduleAppGcsLocked();
15910        }
15911    }
15912
15913    /**
15914     * If all looks good, perform GCs on all processes waiting for them.
15915     */
15916    final void performAppGcsIfAppropriateLocked() {
15917        if (canGcNowLocked()) {
15918            performAppGcsLocked();
15919            return;
15920        }
15921        // Still not idle, wait some more.
15922        scheduleAppGcsLocked();
15923    }
15924
15925    /**
15926     * Schedule the execution of all pending app GCs.
15927     */
15928    final void scheduleAppGcsLocked() {
15929        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15930
15931        if (mProcessesToGc.size() > 0) {
15932            // Schedule a GC for the time to the next process.
15933            ProcessRecord proc = mProcessesToGc.get(0);
15934            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15935
15936            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15937            long now = SystemClock.uptimeMillis();
15938            if (when < (now+GC_TIMEOUT)) {
15939                when = now + GC_TIMEOUT;
15940            }
15941            mHandler.sendMessageAtTime(msg, when);
15942        }
15943    }
15944
15945    /**
15946     * Add a process to the array of processes waiting to be GCed.  Keeps the
15947     * list in sorted order by the last GC time.  The process can't already be
15948     * on the list.
15949     */
15950    final void addProcessToGcListLocked(ProcessRecord proc) {
15951        boolean added = false;
15952        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15953            if (mProcessesToGc.get(i).lastRequestedGc <
15954                    proc.lastRequestedGc) {
15955                added = true;
15956                mProcessesToGc.add(i+1, proc);
15957                break;
15958            }
15959        }
15960        if (!added) {
15961            mProcessesToGc.add(0, proc);
15962        }
15963    }
15964
15965    /**
15966     * Set up to ask a process to GC itself.  This will either do it
15967     * immediately, or put it on the list of processes to gc the next
15968     * time things are idle.
15969     */
15970    final void scheduleAppGcLocked(ProcessRecord app) {
15971        long now = SystemClock.uptimeMillis();
15972        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15973            return;
15974        }
15975        if (!mProcessesToGc.contains(app)) {
15976            addProcessToGcListLocked(app);
15977            scheduleAppGcsLocked();
15978        }
15979    }
15980
15981    final void checkExcessivePowerUsageLocked(boolean doKills) {
15982        updateCpuStatsNow();
15983
15984        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15985        boolean doWakeKills = doKills;
15986        boolean doCpuKills = doKills;
15987        if (mLastPowerCheckRealtime == 0) {
15988            doWakeKills = false;
15989        }
15990        if (mLastPowerCheckUptime == 0) {
15991            doCpuKills = false;
15992        }
15993        if (stats.isScreenOn()) {
15994            doWakeKills = false;
15995        }
15996        final long curRealtime = SystemClock.elapsedRealtime();
15997        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15998        final long curUptime = SystemClock.uptimeMillis();
15999        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16000        mLastPowerCheckRealtime = curRealtime;
16001        mLastPowerCheckUptime = curUptime;
16002        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16003            doWakeKills = false;
16004        }
16005        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16006            doCpuKills = false;
16007        }
16008        int i = mLruProcesses.size();
16009        while (i > 0) {
16010            i--;
16011            ProcessRecord app = mLruProcesses.get(i);
16012            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16013                long wtime;
16014                synchronized (stats) {
16015                    wtime = stats.getProcessWakeTime(app.info.uid,
16016                            app.pid, curRealtime);
16017                }
16018                long wtimeUsed = wtime - app.lastWakeTime;
16019                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16020                if (DEBUG_POWER) {
16021                    StringBuilder sb = new StringBuilder(128);
16022                    sb.append("Wake for ");
16023                    app.toShortString(sb);
16024                    sb.append(": over ");
16025                    TimeUtils.formatDuration(realtimeSince, sb);
16026                    sb.append(" used ");
16027                    TimeUtils.formatDuration(wtimeUsed, sb);
16028                    sb.append(" (");
16029                    sb.append((wtimeUsed*100)/realtimeSince);
16030                    sb.append("%)");
16031                    Slog.i(TAG, sb.toString());
16032                    sb.setLength(0);
16033                    sb.append("CPU for ");
16034                    app.toShortString(sb);
16035                    sb.append(": over ");
16036                    TimeUtils.formatDuration(uptimeSince, sb);
16037                    sb.append(" used ");
16038                    TimeUtils.formatDuration(cputimeUsed, sb);
16039                    sb.append(" (");
16040                    sb.append((cputimeUsed*100)/uptimeSince);
16041                    sb.append("%)");
16042                    Slog.i(TAG, sb.toString());
16043                }
16044                // If a process has held a wake lock for more
16045                // than 50% of the time during this period,
16046                // that sounds bad.  Kill!
16047                if (doWakeKills && realtimeSince > 0
16048                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16049                    synchronized (stats) {
16050                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16051                                realtimeSince, wtimeUsed);
16052                    }
16053                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16054                            + " during " + realtimeSince);
16055                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16056                } else if (doCpuKills && uptimeSince > 0
16057                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16058                    synchronized (stats) {
16059                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16060                                uptimeSince, cputimeUsed);
16061                    }
16062                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16063                            + " during " + uptimeSince);
16064                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16065                } else {
16066                    app.lastWakeTime = wtime;
16067                    app.lastCpuTime = app.curCpuTime;
16068                }
16069            }
16070        }
16071    }
16072
16073    private final boolean applyOomAdjLocked(ProcessRecord app,
16074            ProcessRecord TOP_APP, boolean doingAll, long now) {
16075        boolean success = true;
16076
16077        if (app.curRawAdj != app.setRawAdj) {
16078            app.setRawAdj = app.curRawAdj;
16079        }
16080
16081        int changes = 0;
16082
16083        if (app.curAdj != app.setAdj) {
16084            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16085            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16086                TAG, "Set " + app.pid + " " + app.processName +
16087                " adj " + app.curAdj + ": " + app.adjType);
16088            app.setAdj = app.curAdj;
16089        }
16090
16091        if (app.setSchedGroup != app.curSchedGroup) {
16092            app.setSchedGroup = app.curSchedGroup;
16093            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16094                    "Setting process group of " + app.processName
16095                    + " to " + app.curSchedGroup);
16096            if (app.waitingToKill != null &&
16097                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16098                killUnneededProcessLocked(app, app.waitingToKill);
16099                success = false;
16100            } else {
16101                if (true) {
16102                    long oldId = Binder.clearCallingIdentity();
16103                    try {
16104                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16105                    } catch (Exception e) {
16106                        Slog.w(TAG, "Failed setting process group of " + app.pid
16107                                + " to " + app.curSchedGroup);
16108                        e.printStackTrace();
16109                    } finally {
16110                        Binder.restoreCallingIdentity(oldId);
16111                    }
16112                } else {
16113                    if (app.thread != null) {
16114                        try {
16115                            app.thread.setSchedulingGroup(app.curSchedGroup);
16116                        } catch (RemoteException e) {
16117                        }
16118                    }
16119                }
16120                Process.setSwappiness(app.pid,
16121                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16122            }
16123        }
16124        if (app.repForegroundActivities != app.foregroundActivities) {
16125            app.repForegroundActivities = app.foregroundActivities;
16126            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16127        }
16128        if (app.repProcState != app.curProcState) {
16129            app.repProcState = app.curProcState;
16130            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16131            if (app.thread != null) {
16132                try {
16133                    if (false) {
16134                        //RuntimeException h = new RuntimeException("here");
16135                        Slog.i(TAG, "Sending new process state " + app.repProcState
16136                                + " to " + app /*, h*/);
16137                    }
16138                    app.thread.setProcessState(app.repProcState);
16139                } catch (RemoteException e) {
16140                }
16141            }
16142        }
16143        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16144                app.setProcState)) {
16145            app.lastStateTime = now;
16146            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16147                    isSleeping(), now);
16148            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16149                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16150                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16151                    + (app.nextPssTime-now) + ": " + app);
16152        } else {
16153            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16154                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16155                requestPssLocked(app, app.setProcState);
16156                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16157                        isSleeping(), now);
16158            } else if (false && DEBUG_PSS) {
16159                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16160            }
16161        }
16162        if (app.setProcState != app.curProcState) {
16163            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16164                    "Proc state change of " + app.processName
16165                    + " to " + app.curProcState);
16166            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16167            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16168            if (setImportant && !curImportant) {
16169                // This app is no longer something we consider important enough to allow to
16170                // use arbitrary amounts of battery power.  Note
16171                // its current wake lock time to later know to kill it if
16172                // it is not behaving well.
16173                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16174                synchronized (stats) {
16175                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16176                            app.pid, SystemClock.elapsedRealtime());
16177                }
16178                app.lastCpuTime = app.curCpuTime;
16179
16180            }
16181            app.setProcState = app.curProcState;
16182            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16183                app.notCachedSinceIdle = false;
16184            }
16185            if (!doingAll) {
16186                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16187            } else {
16188                app.procStateChanged = true;
16189            }
16190        }
16191
16192        if (changes != 0) {
16193            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16194            int i = mPendingProcessChanges.size()-1;
16195            ProcessChangeItem item = null;
16196            while (i >= 0) {
16197                item = mPendingProcessChanges.get(i);
16198                if (item.pid == app.pid) {
16199                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16200                    break;
16201                }
16202                i--;
16203            }
16204            if (i < 0) {
16205                // No existing item in pending changes; need a new one.
16206                final int NA = mAvailProcessChanges.size();
16207                if (NA > 0) {
16208                    item = mAvailProcessChanges.remove(NA-1);
16209                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16210                } else {
16211                    item = new ProcessChangeItem();
16212                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16213                }
16214                item.changes = 0;
16215                item.pid = app.pid;
16216                item.uid = app.info.uid;
16217                if (mPendingProcessChanges.size() == 0) {
16218                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16219                            "*** Enqueueing dispatch processes changed!");
16220                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16221                }
16222                mPendingProcessChanges.add(item);
16223            }
16224            item.changes |= changes;
16225            item.processState = app.repProcState;
16226            item.foregroundActivities = app.repForegroundActivities;
16227            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16228                    + Integer.toHexString(System.identityHashCode(item))
16229                    + " " + app.toShortString() + ": changes=" + item.changes
16230                    + " procState=" + item.processState
16231                    + " foreground=" + item.foregroundActivities
16232                    + " type=" + app.adjType + " source=" + app.adjSource
16233                    + " target=" + app.adjTarget);
16234        }
16235
16236        return success;
16237    }
16238
16239    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16240        if (proc.thread != null) {
16241            if (proc.baseProcessTracker != null) {
16242                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16243            }
16244            if (proc.repProcState >= 0) {
16245                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16246                        proc.repProcState);
16247            }
16248        }
16249    }
16250
16251    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16252            ProcessRecord TOP_APP, boolean doingAll, long now) {
16253        if (app.thread == null) {
16254            return false;
16255        }
16256
16257        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16258
16259        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16260    }
16261
16262    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16263            boolean oomAdj) {
16264        if (isForeground != proc.foregroundServices) {
16265            proc.foregroundServices = isForeground;
16266            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16267                    proc.info.uid);
16268            if (isForeground) {
16269                if (curProcs == null) {
16270                    curProcs = new ArrayList<ProcessRecord>();
16271                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16272                }
16273                if (!curProcs.contains(proc)) {
16274                    curProcs.add(proc);
16275                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16276                            proc.info.packageName, proc.info.uid);
16277                }
16278            } else {
16279                if (curProcs != null) {
16280                    if (curProcs.remove(proc)) {
16281                        mBatteryStatsService.noteEvent(
16282                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16283                                proc.info.packageName, proc.info.uid);
16284                        if (curProcs.size() <= 0) {
16285                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16286                        }
16287                    }
16288                }
16289            }
16290            if (oomAdj) {
16291                updateOomAdjLocked();
16292            }
16293        }
16294    }
16295
16296    private final ActivityRecord resumedAppLocked() {
16297        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16298        String pkg;
16299        int uid;
16300        if (act != null) {
16301            pkg = act.packageName;
16302            uid = act.info.applicationInfo.uid;
16303        } else {
16304            pkg = null;
16305            uid = -1;
16306        }
16307        // Has the UID or resumed package name changed?
16308        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16309                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16310            if (mCurResumedPackage != null) {
16311                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16312                        mCurResumedPackage, mCurResumedUid);
16313            }
16314            mCurResumedPackage = pkg;
16315            mCurResumedUid = uid;
16316            if (mCurResumedPackage != null) {
16317                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16318                        mCurResumedPackage, mCurResumedUid);
16319            }
16320        }
16321        return act;
16322    }
16323
16324    final boolean updateOomAdjLocked(ProcessRecord app) {
16325        final ActivityRecord TOP_ACT = resumedAppLocked();
16326        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16327        final boolean wasCached = app.cached;
16328
16329        mAdjSeq++;
16330
16331        // This is the desired cached adjusment we want to tell it to use.
16332        // If our app is currently cached, we know it, and that is it.  Otherwise,
16333        // we don't know it yet, and it needs to now be cached we will then
16334        // need to do a complete oom adj.
16335        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16336                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16337        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16338                SystemClock.uptimeMillis());
16339        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16340            // Changed to/from cached state, so apps after it in the LRU
16341            // list may also be changed.
16342            updateOomAdjLocked();
16343        }
16344        return success;
16345    }
16346
16347    final void updateOomAdjLocked() {
16348        final ActivityRecord TOP_ACT = resumedAppLocked();
16349        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16350        final long now = SystemClock.uptimeMillis();
16351        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16352        final int N = mLruProcesses.size();
16353
16354        if (false) {
16355            RuntimeException e = new RuntimeException();
16356            e.fillInStackTrace();
16357            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16358        }
16359
16360        mAdjSeq++;
16361        mNewNumServiceProcs = 0;
16362        mNewNumAServiceProcs = 0;
16363
16364        final int emptyProcessLimit;
16365        final int cachedProcessLimit;
16366        if (mProcessLimit <= 0) {
16367            emptyProcessLimit = cachedProcessLimit = 0;
16368        } else if (mProcessLimit == 1) {
16369            emptyProcessLimit = 1;
16370            cachedProcessLimit = 0;
16371        } else {
16372            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16373            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16374        }
16375
16376        // Let's determine how many processes we have running vs.
16377        // how many slots we have for background processes; we may want
16378        // to put multiple processes in a slot of there are enough of
16379        // them.
16380        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16381                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16382        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16383        if (numEmptyProcs > cachedProcessLimit) {
16384            // If there are more empty processes than our limit on cached
16385            // processes, then use the cached process limit for the factor.
16386            // This ensures that the really old empty processes get pushed
16387            // down to the bottom, so if we are running low on memory we will
16388            // have a better chance at keeping around more cached processes
16389            // instead of a gazillion empty processes.
16390            numEmptyProcs = cachedProcessLimit;
16391        }
16392        int emptyFactor = numEmptyProcs/numSlots;
16393        if (emptyFactor < 1) emptyFactor = 1;
16394        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16395        if (cachedFactor < 1) cachedFactor = 1;
16396        int stepCached = 0;
16397        int stepEmpty = 0;
16398        int numCached = 0;
16399        int numEmpty = 0;
16400        int numTrimming = 0;
16401
16402        mNumNonCachedProcs = 0;
16403        mNumCachedHiddenProcs = 0;
16404
16405        // First update the OOM adjustment for each of the
16406        // application processes based on their current state.
16407        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16408        int nextCachedAdj = curCachedAdj+1;
16409        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16410        int nextEmptyAdj = curEmptyAdj+2;
16411        for (int i=N-1; i>=0; i--) {
16412            ProcessRecord app = mLruProcesses.get(i);
16413            if (!app.killedByAm && app.thread != null) {
16414                app.procStateChanged = false;
16415                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16416
16417                // If we haven't yet assigned the final cached adj
16418                // to the process, do that now.
16419                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16420                    switch (app.curProcState) {
16421                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16422                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16423                            // This process is a cached process holding activities...
16424                            // assign it the next cached value for that type, and then
16425                            // step that cached level.
16426                            app.curRawAdj = curCachedAdj;
16427                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16428                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16429                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16430                                    + ")");
16431                            if (curCachedAdj != nextCachedAdj) {
16432                                stepCached++;
16433                                if (stepCached >= cachedFactor) {
16434                                    stepCached = 0;
16435                                    curCachedAdj = nextCachedAdj;
16436                                    nextCachedAdj += 2;
16437                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16438                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16439                                    }
16440                                }
16441                            }
16442                            break;
16443                        default:
16444                            // For everything else, assign next empty cached process
16445                            // level and bump that up.  Note that this means that
16446                            // long-running services that have dropped down to the
16447                            // cached level will be treated as empty (since their process
16448                            // state is still as a service), which is what we want.
16449                            app.curRawAdj = curEmptyAdj;
16450                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16451                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16452                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16453                                    + ")");
16454                            if (curEmptyAdj != nextEmptyAdj) {
16455                                stepEmpty++;
16456                                if (stepEmpty >= emptyFactor) {
16457                                    stepEmpty = 0;
16458                                    curEmptyAdj = nextEmptyAdj;
16459                                    nextEmptyAdj += 2;
16460                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16461                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16462                                    }
16463                                }
16464                            }
16465                            break;
16466                    }
16467                }
16468
16469                applyOomAdjLocked(app, TOP_APP, true, now);
16470
16471                // Count the number of process types.
16472                switch (app.curProcState) {
16473                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16474                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16475                        mNumCachedHiddenProcs++;
16476                        numCached++;
16477                        if (numCached > cachedProcessLimit) {
16478                            killUnneededProcessLocked(app, "cached #" + numCached);
16479                        }
16480                        break;
16481                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16482                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16483                                && app.lastActivityTime < oldTime) {
16484                            killUnneededProcessLocked(app, "empty for "
16485                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16486                                    / 1000) + "s");
16487                        } else {
16488                            numEmpty++;
16489                            if (numEmpty > emptyProcessLimit) {
16490                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16491                            }
16492                        }
16493                        break;
16494                    default:
16495                        mNumNonCachedProcs++;
16496                        break;
16497                }
16498
16499                if (app.isolated && app.services.size() <= 0) {
16500                    // If this is an isolated process, and there are no
16501                    // services running in it, then the process is no longer
16502                    // needed.  We agressively kill these because we can by
16503                    // definition not re-use the same process again, and it is
16504                    // good to avoid having whatever code was running in them
16505                    // left sitting around after no longer needed.
16506                    killUnneededProcessLocked(app, "isolated not needed");
16507                }
16508
16509                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16510                        && !app.killedByAm) {
16511                    numTrimming++;
16512                }
16513            }
16514        }
16515
16516        mNumServiceProcs = mNewNumServiceProcs;
16517
16518        // Now determine the memory trimming level of background processes.
16519        // Unfortunately we need to start at the back of the list to do this
16520        // properly.  We only do this if the number of background apps we
16521        // are managing to keep around is less than half the maximum we desire;
16522        // if we are keeping a good number around, we'll let them use whatever
16523        // memory they want.
16524        final int numCachedAndEmpty = numCached + numEmpty;
16525        int memFactor;
16526        if (numCached <= ProcessList.TRIM_CACHED_APPS
16527                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16528            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16529                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16530            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16531                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16532            } else {
16533                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16534            }
16535        } else {
16536            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16537        }
16538        // We always allow the memory level to go up (better).  We only allow it to go
16539        // down if we are in a state where that is allowed, *and* the total number of processes
16540        // has gone down since last time.
16541        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16542                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16543                + " last=" + mLastNumProcesses);
16544        if (memFactor > mLastMemoryLevel) {
16545            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16546                memFactor = mLastMemoryLevel;
16547                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16548            }
16549        }
16550        mLastMemoryLevel = memFactor;
16551        mLastNumProcesses = mLruProcesses.size();
16552        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16553        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16554        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16555            if (mLowRamStartTime == 0) {
16556                mLowRamStartTime = now;
16557            }
16558            int step = 0;
16559            int fgTrimLevel;
16560            switch (memFactor) {
16561                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16562                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16563                    break;
16564                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16565                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16566                    break;
16567                default:
16568                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16569                    break;
16570            }
16571            int factor = numTrimming/3;
16572            int minFactor = 2;
16573            if (mHomeProcess != null) minFactor++;
16574            if (mPreviousProcess != null) minFactor++;
16575            if (factor < minFactor) factor = minFactor;
16576            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16577            for (int i=N-1; i>=0; i--) {
16578                ProcessRecord app = mLruProcesses.get(i);
16579                if (allChanged || app.procStateChanged) {
16580                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16581                    app.procStateChanged = false;
16582                }
16583                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16584                        && !app.killedByAm) {
16585                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16586                        try {
16587                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16588                                    "Trimming memory of " + app.processName
16589                                    + " to " + curLevel);
16590                            app.thread.scheduleTrimMemory(curLevel);
16591                        } catch (RemoteException e) {
16592                        }
16593                        if (false) {
16594                            // For now we won't do this; our memory trimming seems
16595                            // to be good enough at this point that destroying
16596                            // activities causes more harm than good.
16597                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16598                                    && app != mHomeProcess && app != mPreviousProcess) {
16599                                // Need to do this on its own message because the stack may not
16600                                // be in a consistent state at this point.
16601                                // For these apps we will also finish their activities
16602                                // to help them free memory.
16603                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16604                            }
16605                        }
16606                    }
16607                    app.trimMemoryLevel = curLevel;
16608                    step++;
16609                    if (step >= factor) {
16610                        step = 0;
16611                        switch (curLevel) {
16612                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16613                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16614                                break;
16615                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16616                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16617                                break;
16618                        }
16619                    }
16620                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16621                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16622                            && app.thread != null) {
16623                        try {
16624                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16625                                    "Trimming memory of heavy-weight " + app.processName
16626                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16627                            app.thread.scheduleTrimMemory(
16628                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16629                        } catch (RemoteException e) {
16630                        }
16631                    }
16632                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16633                } else {
16634                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16635                            || app.systemNoUi) && app.pendingUiClean) {
16636                        // If this application is now in the background and it
16637                        // had done UI, then give it the special trim level to
16638                        // have it free UI resources.
16639                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16640                        if (app.trimMemoryLevel < level && app.thread != null) {
16641                            try {
16642                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16643                                        "Trimming memory of bg-ui " + app.processName
16644                                        + " to " + level);
16645                                app.thread.scheduleTrimMemory(level);
16646                            } catch (RemoteException e) {
16647                            }
16648                        }
16649                        app.pendingUiClean = false;
16650                    }
16651                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16652                        try {
16653                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16654                                    "Trimming memory of fg " + app.processName
16655                                    + " to " + fgTrimLevel);
16656                            app.thread.scheduleTrimMemory(fgTrimLevel);
16657                        } catch (RemoteException e) {
16658                        }
16659                    }
16660                    app.trimMemoryLevel = fgTrimLevel;
16661                }
16662            }
16663        } else {
16664            if (mLowRamStartTime != 0) {
16665                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16666                mLowRamStartTime = 0;
16667            }
16668            for (int i=N-1; i>=0; i--) {
16669                ProcessRecord app = mLruProcesses.get(i);
16670                if (allChanged || app.procStateChanged) {
16671                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16672                    app.procStateChanged = false;
16673                }
16674                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16675                        || app.systemNoUi) && app.pendingUiClean) {
16676                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16677                            && app.thread != null) {
16678                        try {
16679                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16680                                    "Trimming memory of ui hidden " + app.processName
16681                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16682                            app.thread.scheduleTrimMemory(
16683                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16684                        } catch (RemoteException e) {
16685                        }
16686                    }
16687                    app.pendingUiClean = false;
16688                }
16689                app.trimMemoryLevel = 0;
16690            }
16691        }
16692
16693        if (mAlwaysFinishActivities) {
16694            // Need to do this on its own message because the stack may not
16695            // be in a consistent state at this point.
16696            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16697        }
16698
16699        if (allChanged) {
16700            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16701        }
16702
16703        if (mProcessStats.shouldWriteNowLocked(now)) {
16704            mHandler.post(new Runnable() {
16705                @Override public void run() {
16706                    synchronized (ActivityManagerService.this) {
16707                        mProcessStats.writeStateAsyncLocked();
16708                    }
16709                }
16710            });
16711        }
16712
16713        if (DEBUG_OOM_ADJ) {
16714            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16715        }
16716    }
16717
16718    final void trimApplications() {
16719        synchronized (this) {
16720            int i;
16721
16722            // First remove any unused application processes whose package
16723            // has been removed.
16724            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16725                final ProcessRecord app = mRemovedProcesses.get(i);
16726                if (app.activities.size() == 0
16727                        && app.curReceiver == null && app.services.size() == 0) {
16728                    Slog.i(
16729                        TAG, "Exiting empty application process "
16730                        + app.processName + " ("
16731                        + (app.thread != null ? app.thread.asBinder() : null)
16732                        + ")\n");
16733                    if (app.pid > 0 && app.pid != MY_PID) {
16734                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16735                                app.processName, app.setAdj, "empty");
16736                        app.killedByAm = true;
16737                        Process.killProcessQuiet(app.pid);
16738                        Process.killProcessGroup(app.info.uid, app.pid);
16739                    } else {
16740                        try {
16741                            app.thread.scheduleExit();
16742                        } catch (Exception e) {
16743                            // Ignore exceptions.
16744                        }
16745                    }
16746                    cleanUpApplicationRecordLocked(app, false, true, -1);
16747                    mRemovedProcesses.remove(i);
16748
16749                    if (app.persistent) {
16750                        addAppLocked(app.info, false, null /* ABI override */);
16751                    }
16752                }
16753            }
16754
16755            // Now update the oom adj for all processes.
16756            updateOomAdjLocked();
16757        }
16758    }
16759
16760    /** This method sends the specified signal to each of the persistent apps */
16761    public void signalPersistentProcesses(int sig) throws RemoteException {
16762        if (sig != Process.SIGNAL_USR1) {
16763            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16764        }
16765
16766        synchronized (this) {
16767            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16768                    != PackageManager.PERMISSION_GRANTED) {
16769                throw new SecurityException("Requires permission "
16770                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16771            }
16772
16773            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16774                ProcessRecord r = mLruProcesses.get(i);
16775                if (r.thread != null && r.persistent) {
16776                    Process.sendSignal(r.pid, sig);
16777                }
16778            }
16779        }
16780    }
16781
16782    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16783        if (proc == null || proc == mProfileProc) {
16784            proc = mProfileProc;
16785            path = mProfileFile;
16786            profileType = mProfileType;
16787            clearProfilerLocked();
16788        }
16789        if (proc == null) {
16790            return;
16791        }
16792        try {
16793            proc.thread.profilerControl(false, path, null, profileType);
16794        } catch (RemoteException e) {
16795            throw new IllegalStateException("Process disappeared");
16796        }
16797    }
16798
16799    private void clearProfilerLocked() {
16800        if (mProfileFd != null) {
16801            try {
16802                mProfileFd.close();
16803            } catch (IOException e) {
16804            }
16805        }
16806        mProfileApp = null;
16807        mProfileProc = null;
16808        mProfileFile = null;
16809        mProfileType = 0;
16810        mAutoStopProfiler = false;
16811    }
16812
16813    public boolean profileControl(String process, int userId, boolean start,
16814            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16815
16816        try {
16817            synchronized (this) {
16818                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16819                // its own permission.
16820                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16821                        != PackageManager.PERMISSION_GRANTED) {
16822                    throw new SecurityException("Requires permission "
16823                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16824                }
16825
16826                if (start && fd == null) {
16827                    throw new IllegalArgumentException("null fd");
16828                }
16829
16830                ProcessRecord proc = null;
16831                if (process != null) {
16832                    proc = findProcessLocked(process, userId, "profileControl");
16833                }
16834
16835                if (start && (proc == null || proc.thread == null)) {
16836                    throw new IllegalArgumentException("Unknown process: " + process);
16837                }
16838
16839                if (start) {
16840                    stopProfilerLocked(null, null, 0);
16841                    setProfileApp(proc.info, proc.processName, path, fd, false);
16842                    mProfileProc = proc;
16843                    mProfileType = profileType;
16844                    try {
16845                        fd = fd.dup();
16846                    } catch (IOException e) {
16847                        fd = null;
16848                    }
16849                    proc.thread.profilerControl(start, path, fd, profileType);
16850                    fd = null;
16851                    mProfileFd = null;
16852                } else {
16853                    stopProfilerLocked(proc, path, profileType);
16854                    if (fd != null) {
16855                        try {
16856                            fd.close();
16857                        } catch (IOException e) {
16858                        }
16859                    }
16860                }
16861
16862                return true;
16863            }
16864        } catch (RemoteException e) {
16865            throw new IllegalStateException("Process disappeared");
16866        } finally {
16867            if (fd != null) {
16868                try {
16869                    fd.close();
16870                } catch (IOException e) {
16871                }
16872            }
16873        }
16874    }
16875
16876    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16877        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16878                userId, true, ALLOW_FULL_ONLY, callName, null);
16879        ProcessRecord proc = null;
16880        try {
16881            int pid = Integer.parseInt(process);
16882            synchronized (mPidsSelfLocked) {
16883                proc = mPidsSelfLocked.get(pid);
16884            }
16885        } catch (NumberFormatException e) {
16886        }
16887
16888        if (proc == null) {
16889            ArrayMap<String, SparseArray<ProcessRecord>> all
16890                    = mProcessNames.getMap();
16891            SparseArray<ProcessRecord> procs = all.get(process);
16892            if (procs != null && procs.size() > 0) {
16893                proc = procs.valueAt(0);
16894                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16895                    for (int i=1; i<procs.size(); i++) {
16896                        ProcessRecord thisProc = procs.valueAt(i);
16897                        if (thisProc.userId == userId) {
16898                            proc = thisProc;
16899                            break;
16900                        }
16901                    }
16902                }
16903            }
16904        }
16905
16906        return proc;
16907    }
16908
16909    public boolean dumpHeap(String process, int userId, boolean managed,
16910            String path, ParcelFileDescriptor fd) throws RemoteException {
16911
16912        try {
16913            synchronized (this) {
16914                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16915                // its own permission (same as profileControl).
16916                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16917                        != PackageManager.PERMISSION_GRANTED) {
16918                    throw new SecurityException("Requires permission "
16919                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16920                }
16921
16922                if (fd == null) {
16923                    throw new IllegalArgumentException("null fd");
16924                }
16925
16926                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16927                if (proc == null || proc.thread == null) {
16928                    throw new IllegalArgumentException("Unknown process: " + process);
16929                }
16930
16931                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16932                if (!isDebuggable) {
16933                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16934                        throw new SecurityException("Process not debuggable: " + proc);
16935                    }
16936                }
16937
16938                proc.thread.dumpHeap(managed, path, fd);
16939                fd = null;
16940                return true;
16941            }
16942        } catch (RemoteException e) {
16943            throw new IllegalStateException("Process disappeared");
16944        } finally {
16945            if (fd != null) {
16946                try {
16947                    fd.close();
16948                } catch (IOException e) {
16949                }
16950            }
16951        }
16952    }
16953
16954    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16955    public void monitor() {
16956        synchronized (this) { }
16957    }
16958
16959    void onCoreSettingsChange(Bundle settings) {
16960        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16961            ProcessRecord processRecord = mLruProcesses.get(i);
16962            try {
16963                if (processRecord.thread != null) {
16964                    processRecord.thread.setCoreSettings(settings);
16965                }
16966            } catch (RemoteException re) {
16967                /* ignore */
16968            }
16969        }
16970    }
16971
16972    // Multi-user methods
16973
16974    /**
16975     * Start user, if its not already running, but don't bring it to foreground.
16976     */
16977    @Override
16978    public boolean startUserInBackground(final int userId) {
16979        return startUser(userId, /* foreground */ false);
16980    }
16981
16982    /**
16983     * Refreshes the list of users related to the current user when either a
16984     * user switch happens or when a new related user is started in the
16985     * background.
16986     */
16987    private void updateCurrentProfileIdsLocked() {
16988        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16989                mCurrentUserId, false /* enabledOnly */);
16990        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16991        for (int i = 0; i < currentProfileIds.length; i++) {
16992            currentProfileIds[i] = profiles.get(i).id;
16993        }
16994        mCurrentProfileIds = currentProfileIds;
16995
16996        synchronized (mUserProfileGroupIdsSelfLocked) {
16997            mUserProfileGroupIdsSelfLocked.clear();
16998            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
16999            for (int i = 0; i < users.size(); i++) {
17000                UserInfo user = users.get(i);
17001                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17002                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17003                }
17004            }
17005        }
17006    }
17007
17008    private Set getProfileIdsLocked(int userId) {
17009        Set userIds = new HashSet<Integer>();
17010        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17011                userId, false /* enabledOnly */);
17012        for (UserInfo user : profiles) {
17013            userIds.add(Integer.valueOf(user.id));
17014        }
17015        return userIds;
17016    }
17017
17018    @Override
17019    public boolean switchUser(final int userId) {
17020        return startUser(userId, /* foregound */ true);
17021    }
17022
17023    private boolean startUser(final int userId, boolean foreground) {
17024        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17025                != PackageManager.PERMISSION_GRANTED) {
17026            String msg = "Permission Denial: switchUser() from pid="
17027                    + Binder.getCallingPid()
17028                    + ", uid=" + Binder.getCallingUid()
17029                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17030            Slog.w(TAG, msg);
17031            throw new SecurityException(msg);
17032        }
17033
17034        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17035
17036        final long ident = Binder.clearCallingIdentity();
17037        try {
17038            synchronized (this) {
17039                final int oldUserId = mCurrentUserId;
17040                if (oldUserId == userId) {
17041                    return true;
17042                }
17043
17044                mStackSupervisor.setLockTaskModeLocked(null, false);
17045
17046                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17047                if (userInfo == null) {
17048                    Slog.w(TAG, "No user info for user #" + userId);
17049                    return false;
17050                }
17051
17052                if (foreground) {
17053                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17054                            R.anim.screen_user_enter);
17055                }
17056
17057                boolean needStart = false;
17058
17059                // If the user we are switching to is not currently started, then
17060                // we need to start it now.
17061                if (mStartedUsers.get(userId) == null) {
17062                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17063                    updateStartedUserArrayLocked();
17064                    needStart = true;
17065                }
17066
17067                final Integer userIdInt = Integer.valueOf(userId);
17068                mUserLru.remove(userIdInt);
17069                mUserLru.add(userIdInt);
17070
17071                if (foreground) {
17072                    mCurrentUserId = userId;
17073                    updateCurrentProfileIdsLocked();
17074                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17075                    // Once the internal notion of the active user has switched, we lock the device
17076                    // with the option to show the user switcher on the keyguard.
17077                    mWindowManager.lockNow(null);
17078                } else {
17079                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17080                    updateCurrentProfileIdsLocked();
17081                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17082                    mUserLru.remove(currentUserIdInt);
17083                    mUserLru.add(currentUserIdInt);
17084                }
17085
17086                final UserStartedState uss = mStartedUsers.get(userId);
17087
17088                // Make sure user is in the started state.  If it is currently
17089                // stopping, we need to knock that off.
17090                if (uss.mState == UserStartedState.STATE_STOPPING) {
17091                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17092                    // so we can just fairly silently bring the user back from
17093                    // the almost-dead.
17094                    uss.mState = UserStartedState.STATE_RUNNING;
17095                    updateStartedUserArrayLocked();
17096                    needStart = true;
17097                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17098                    // This means ACTION_SHUTDOWN has been sent, so we will
17099                    // need to treat this as a new boot of the user.
17100                    uss.mState = UserStartedState.STATE_BOOTING;
17101                    updateStartedUserArrayLocked();
17102                    needStart = true;
17103                }
17104
17105                if (uss.mState == UserStartedState.STATE_BOOTING) {
17106                    // Booting up a new user, need to tell system services about it.
17107                    // Note that this is on the same handler as scheduling of broadcasts,
17108                    // which is important because it needs to go first.
17109                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17110                }
17111
17112                if (foreground) {
17113                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17114                            oldUserId));
17115                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17116                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17117                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17118                            oldUserId, userId, uss));
17119                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17120                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17121                }
17122
17123                if (needStart) {
17124                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17125                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17126                            | Intent.FLAG_RECEIVER_FOREGROUND);
17127                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17128                    broadcastIntentLocked(null, null, intent,
17129                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17130                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17131                }
17132
17133                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17134                    if (userId != UserHandle.USER_OWNER) {
17135                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17136                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17137                        broadcastIntentLocked(null, null, intent, null,
17138                                new IIntentReceiver.Stub() {
17139                                    public void performReceive(Intent intent, int resultCode,
17140                                            String data, Bundle extras, boolean ordered,
17141                                            boolean sticky, int sendingUser) {
17142                                        userInitialized(uss, userId);
17143                                    }
17144                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17145                                true, false, MY_PID, Process.SYSTEM_UID,
17146                                userId);
17147                        uss.initializing = true;
17148                    } else {
17149                        getUserManagerLocked().makeInitialized(userInfo.id);
17150                    }
17151                }
17152
17153                if (foreground) {
17154                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17155                    if (homeInFront) {
17156                        startHomeActivityLocked(userId);
17157                    } else {
17158                        mStackSupervisor.resumeTopActivitiesLocked();
17159                    }
17160                    EventLogTags.writeAmSwitchUser(userId);
17161                    getUserManagerLocked().userForeground(userId);
17162                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17163                } else {
17164                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17165                }
17166
17167                if (needStart) {
17168                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17169                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17170                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17171                    broadcastIntentLocked(null, null, intent,
17172                            null, new IIntentReceiver.Stub() {
17173                                @Override
17174                                public void performReceive(Intent intent, int resultCode, String data,
17175                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17176                                        throws RemoteException {
17177                                }
17178                            }, 0, null, null,
17179                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17180                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17181                }
17182            }
17183        } finally {
17184            Binder.restoreCallingIdentity(ident);
17185        }
17186
17187        return true;
17188    }
17189
17190    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17191        long ident = Binder.clearCallingIdentity();
17192        try {
17193            Intent intent;
17194            if (oldUserId >= 0) {
17195                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17196                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17197                int count = profiles.size();
17198                for (int i = 0; i < count; i++) {
17199                    int profileUserId = profiles.get(i).id;
17200                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17201                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17202                            | Intent.FLAG_RECEIVER_FOREGROUND);
17203                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17204                    broadcastIntentLocked(null, null, intent,
17205                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17206                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17207                }
17208            }
17209            if (newUserId >= 0) {
17210                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17211                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17212                int count = profiles.size();
17213                for (int i = 0; i < count; i++) {
17214                    int profileUserId = profiles.get(i).id;
17215                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17216                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17217                            | Intent.FLAG_RECEIVER_FOREGROUND);
17218                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17219                    broadcastIntentLocked(null, null, intent,
17220                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17221                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17222                }
17223                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17224                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17225                        | Intent.FLAG_RECEIVER_FOREGROUND);
17226                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17227                broadcastIntentLocked(null, null, intent,
17228                        null, null, 0, null, null,
17229                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17230                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17231            }
17232        } finally {
17233            Binder.restoreCallingIdentity(ident);
17234        }
17235    }
17236
17237    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17238            final int newUserId) {
17239        final int N = mUserSwitchObservers.beginBroadcast();
17240        if (N > 0) {
17241            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17242                int mCount = 0;
17243                @Override
17244                public void sendResult(Bundle data) throws RemoteException {
17245                    synchronized (ActivityManagerService.this) {
17246                        if (mCurUserSwitchCallback == this) {
17247                            mCount++;
17248                            if (mCount == N) {
17249                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17250                            }
17251                        }
17252                    }
17253                }
17254            };
17255            synchronized (this) {
17256                uss.switching = true;
17257                mCurUserSwitchCallback = callback;
17258            }
17259            for (int i=0; i<N; i++) {
17260                try {
17261                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17262                            newUserId, callback);
17263                } catch (RemoteException e) {
17264                }
17265            }
17266        } else {
17267            synchronized (this) {
17268                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17269            }
17270        }
17271        mUserSwitchObservers.finishBroadcast();
17272    }
17273
17274    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17275        synchronized (this) {
17276            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17277            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17278        }
17279    }
17280
17281    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17282        mCurUserSwitchCallback = null;
17283        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17284        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17285                oldUserId, newUserId, uss));
17286    }
17287
17288    void userInitialized(UserStartedState uss, int newUserId) {
17289        completeSwitchAndInitalize(uss, newUserId, true, false);
17290    }
17291
17292    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17293        completeSwitchAndInitalize(uss, newUserId, false, true);
17294    }
17295
17296    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17297            boolean clearInitializing, boolean clearSwitching) {
17298        boolean unfrozen = false;
17299        synchronized (this) {
17300            if (clearInitializing) {
17301                uss.initializing = false;
17302                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17303            }
17304            if (clearSwitching) {
17305                uss.switching = false;
17306            }
17307            if (!uss.switching && !uss.initializing) {
17308                mWindowManager.stopFreezingScreen();
17309                unfrozen = true;
17310            }
17311        }
17312        if (unfrozen) {
17313            final int N = mUserSwitchObservers.beginBroadcast();
17314            for (int i=0; i<N; i++) {
17315                try {
17316                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17317                } catch (RemoteException e) {
17318                }
17319            }
17320            mUserSwitchObservers.finishBroadcast();
17321        }
17322    }
17323
17324    void scheduleStartProfilesLocked() {
17325        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17326            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17327                    DateUtils.SECOND_IN_MILLIS);
17328        }
17329    }
17330
17331    void startProfilesLocked() {
17332        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17333        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17334                mCurrentUserId, false /* enabledOnly */);
17335        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17336        for (UserInfo user : profiles) {
17337            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17338                    && user.id != mCurrentUserId) {
17339                toStart.add(user);
17340            }
17341        }
17342        final int n = toStart.size();
17343        int i = 0;
17344        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17345            startUserInBackground(toStart.get(i).id);
17346        }
17347        if (i < n) {
17348            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17349        }
17350    }
17351
17352    void finishUserBoot(UserStartedState uss) {
17353        synchronized (this) {
17354            if (uss.mState == UserStartedState.STATE_BOOTING
17355                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17356                uss.mState = UserStartedState.STATE_RUNNING;
17357                final int userId = uss.mHandle.getIdentifier();
17358                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17359                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17360                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17361                broadcastIntentLocked(null, null, intent,
17362                        null, null, 0, null, null,
17363                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17364                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17365            }
17366        }
17367    }
17368
17369    void finishUserSwitch(UserStartedState uss) {
17370        synchronized (this) {
17371            finishUserBoot(uss);
17372
17373            startProfilesLocked();
17374
17375            int num = mUserLru.size();
17376            int i = 0;
17377            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17378                Integer oldUserId = mUserLru.get(i);
17379                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17380                if (oldUss == null) {
17381                    // Shouldn't happen, but be sane if it does.
17382                    mUserLru.remove(i);
17383                    num--;
17384                    continue;
17385                }
17386                if (oldUss.mState == UserStartedState.STATE_STOPPING
17387                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17388                    // This user is already stopping, doesn't count.
17389                    num--;
17390                    i++;
17391                    continue;
17392                }
17393                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17394                    // Owner and current can't be stopped, but count as running.
17395                    i++;
17396                    continue;
17397                }
17398                // This is a user to be stopped.
17399                stopUserLocked(oldUserId, null);
17400                num--;
17401                i++;
17402            }
17403        }
17404    }
17405
17406    @Override
17407    public int stopUser(final int userId, final IStopUserCallback callback) {
17408        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17409                != PackageManager.PERMISSION_GRANTED) {
17410            String msg = "Permission Denial: switchUser() from pid="
17411                    + Binder.getCallingPid()
17412                    + ", uid=" + Binder.getCallingUid()
17413                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17414            Slog.w(TAG, msg);
17415            throw new SecurityException(msg);
17416        }
17417        if (userId <= 0) {
17418            throw new IllegalArgumentException("Can't stop primary user " + userId);
17419        }
17420        synchronized (this) {
17421            return stopUserLocked(userId, callback);
17422        }
17423    }
17424
17425    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17426        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17427        if (mCurrentUserId == userId) {
17428            return ActivityManager.USER_OP_IS_CURRENT;
17429        }
17430
17431        final UserStartedState uss = mStartedUsers.get(userId);
17432        if (uss == null) {
17433            // User is not started, nothing to do...  but we do need to
17434            // callback if requested.
17435            if (callback != null) {
17436                mHandler.post(new Runnable() {
17437                    @Override
17438                    public void run() {
17439                        try {
17440                            callback.userStopped(userId);
17441                        } catch (RemoteException e) {
17442                        }
17443                    }
17444                });
17445            }
17446            return ActivityManager.USER_OP_SUCCESS;
17447        }
17448
17449        if (callback != null) {
17450            uss.mStopCallbacks.add(callback);
17451        }
17452
17453        if (uss.mState != UserStartedState.STATE_STOPPING
17454                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17455            uss.mState = UserStartedState.STATE_STOPPING;
17456            updateStartedUserArrayLocked();
17457
17458            long ident = Binder.clearCallingIdentity();
17459            try {
17460                // We are going to broadcast ACTION_USER_STOPPING and then
17461                // once that is done send a final ACTION_SHUTDOWN and then
17462                // stop the user.
17463                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17464                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17465                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17466                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17467                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17468                // This is the result receiver for the final shutdown broadcast.
17469                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17470                    @Override
17471                    public void performReceive(Intent intent, int resultCode, String data,
17472                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17473                        finishUserStop(uss);
17474                    }
17475                };
17476                // This is the result receiver for the initial stopping broadcast.
17477                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17478                    @Override
17479                    public void performReceive(Intent intent, int resultCode, String data,
17480                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17481                        // On to the next.
17482                        synchronized (ActivityManagerService.this) {
17483                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17484                                // Whoops, we are being started back up.  Abort, abort!
17485                                return;
17486                            }
17487                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17488                        }
17489                        mBatteryStatsService.noteEvent(
17490                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17491                                Integer.toString(userId), userId);
17492                        mSystemServiceManager.stopUser(userId);
17493                        broadcastIntentLocked(null, null, shutdownIntent,
17494                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17495                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17496                    }
17497                };
17498                // Kick things off.
17499                broadcastIntentLocked(null, null, stoppingIntent,
17500                        null, stoppingReceiver, 0, null, null,
17501                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17502                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17503            } finally {
17504                Binder.restoreCallingIdentity(ident);
17505            }
17506        }
17507
17508        return ActivityManager.USER_OP_SUCCESS;
17509    }
17510
17511    void finishUserStop(UserStartedState uss) {
17512        final int userId = uss.mHandle.getIdentifier();
17513        boolean stopped;
17514        ArrayList<IStopUserCallback> callbacks;
17515        synchronized (this) {
17516            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17517            if (mStartedUsers.get(userId) != uss) {
17518                stopped = false;
17519            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17520                stopped = false;
17521            } else {
17522                stopped = true;
17523                // User can no longer run.
17524                mStartedUsers.remove(userId);
17525                mUserLru.remove(Integer.valueOf(userId));
17526                updateStartedUserArrayLocked();
17527
17528                // Clean up all state and processes associated with the user.
17529                // Kill all the processes for the user.
17530                forceStopUserLocked(userId, "finish user");
17531            }
17532        }
17533
17534        for (int i=0; i<callbacks.size(); i++) {
17535            try {
17536                if (stopped) callbacks.get(i).userStopped(userId);
17537                else callbacks.get(i).userStopAborted(userId);
17538            } catch (RemoteException e) {
17539            }
17540        }
17541
17542        if (stopped) {
17543            mSystemServiceManager.cleanupUser(userId);
17544            synchronized (this) {
17545                mStackSupervisor.removeUserLocked(userId);
17546            }
17547        }
17548    }
17549
17550    @Override
17551    public UserInfo getCurrentUser() {
17552        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17553                != PackageManager.PERMISSION_GRANTED) && (
17554                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17555                != PackageManager.PERMISSION_GRANTED)) {
17556            String msg = "Permission Denial: getCurrentUser() from pid="
17557                    + Binder.getCallingPid()
17558                    + ", uid=" + Binder.getCallingUid()
17559                    + " requires " + INTERACT_ACROSS_USERS;
17560            Slog.w(TAG, msg);
17561            throw new SecurityException(msg);
17562        }
17563        synchronized (this) {
17564            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17565        }
17566    }
17567
17568    int getCurrentUserIdLocked() {
17569        return mCurrentUserId;
17570    }
17571
17572    @Override
17573    public boolean isUserRunning(int userId, boolean orStopped) {
17574        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17575                != PackageManager.PERMISSION_GRANTED) {
17576            String msg = "Permission Denial: isUserRunning() from pid="
17577                    + Binder.getCallingPid()
17578                    + ", uid=" + Binder.getCallingUid()
17579                    + " requires " + INTERACT_ACROSS_USERS;
17580            Slog.w(TAG, msg);
17581            throw new SecurityException(msg);
17582        }
17583        synchronized (this) {
17584            return isUserRunningLocked(userId, orStopped);
17585        }
17586    }
17587
17588    boolean isUserRunningLocked(int userId, boolean orStopped) {
17589        UserStartedState state = mStartedUsers.get(userId);
17590        if (state == null) {
17591            return false;
17592        }
17593        if (orStopped) {
17594            return true;
17595        }
17596        return state.mState != UserStartedState.STATE_STOPPING
17597                && state.mState != UserStartedState.STATE_SHUTDOWN;
17598    }
17599
17600    @Override
17601    public int[] getRunningUserIds() {
17602        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17603                != PackageManager.PERMISSION_GRANTED) {
17604            String msg = "Permission Denial: isUserRunning() from pid="
17605                    + Binder.getCallingPid()
17606                    + ", uid=" + Binder.getCallingUid()
17607                    + " requires " + INTERACT_ACROSS_USERS;
17608            Slog.w(TAG, msg);
17609            throw new SecurityException(msg);
17610        }
17611        synchronized (this) {
17612            return mStartedUserArray;
17613        }
17614    }
17615
17616    private void updateStartedUserArrayLocked() {
17617        int num = 0;
17618        for (int i=0; i<mStartedUsers.size();  i++) {
17619            UserStartedState uss = mStartedUsers.valueAt(i);
17620            // This list does not include stopping users.
17621            if (uss.mState != UserStartedState.STATE_STOPPING
17622                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17623                num++;
17624            }
17625        }
17626        mStartedUserArray = new int[num];
17627        num = 0;
17628        for (int i=0; i<mStartedUsers.size();  i++) {
17629            UserStartedState uss = mStartedUsers.valueAt(i);
17630            if (uss.mState != UserStartedState.STATE_STOPPING
17631                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17632                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17633                num++;
17634            }
17635        }
17636    }
17637
17638    @Override
17639    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17640        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17641                != PackageManager.PERMISSION_GRANTED) {
17642            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17643                    + Binder.getCallingPid()
17644                    + ", uid=" + Binder.getCallingUid()
17645                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17646            Slog.w(TAG, msg);
17647            throw new SecurityException(msg);
17648        }
17649
17650        mUserSwitchObservers.register(observer);
17651    }
17652
17653    @Override
17654    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17655        mUserSwitchObservers.unregister(observer);
17656    }
17657
17658    private boolean userExists(int userId) {
17659        if (userId == 0) {
17660            return true;
17661        }
17662        UserManagerService ums = getUserManagerLocked();
17663        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17664    }
17665
17666    int[] getUsersLocked() {
17667        UserManagerService ums = getUserManagerLocked();
17668        return ums != null ? ums.getUserIds() : new int[] { 0 };
17669    }
17670
17671    UserManagerService getUserManagerLocked() {
17672        if (mUserManager == null) {
17673            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17674            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17675        }
17676        return mUserManager;
17677    }
17678
17679    private int applyUserId(int uid, int userId) {
17680        return UserHandle.getUid(userId, uid);
17681    }
17682
17683    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17684        if (info == null) return null;
17685        ApplicationInfo newInfo = new ApplicationInfo(info);
17686        newInfo.uid = applyUserId(info.uid, userId);
17687        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17688                + info.packageName;
17689        return newInfo;
17690    }
17691
17692    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17693        if (aInfo == null
17694                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17695            return aInfo;
17696        }
17697
17698        ActivityInfo info = new ActivityInfo(aInfo);
17699        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17700        return info;
17701    }
17702
17703    private final class LocalService extends ActivityManagerInternal {
17704        @Override
17705        public void goingToSleep() {
17706            ActivityManagerService.this.goingToSleep();
17707        }
17708
17709        @Override
17710        public void wakingUp() {
17711            ActivityManagerService.this.wakingUp();
17712        }
17713    }
17714
17715    /**
17716     * An implementation of IAppTask, that allows an app to manage its own tasks via
17717     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17718     * only the process that calls getAppTasks() can call the AppTask methods.
17719     */
17720    class AppTaskImpl extends IAppTask.Stub {
17721        private int mTaskId;
17722        private int mCallingUid;
17723
17724        public AppTaskImpl(int taskId, int callingUid) {
17725            mTaskId = taskId;
17726            mCallingUid = callingUid;
17727        }
17728
17729        @Override
17730        public void finishAndRemoveTask() {
17731            // Ensure that we are called from the same process that created this AppTask
17732            if (mCallingUid != Binder.getCallingUid()) {
17733                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17734                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17735                return;
17736            }
17737
17738            synchronized (ActivityManagerService.this) {
17739                long origId = Binder.clearCallingIdentity();
17740                try {
17741                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17742                    if (tr != null) {
17743                        // Only kill the process if we are not a new document
17744                        int flags = tr.getBaseIntent().getFlags();
17745                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17746                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17747                        removeTaskByIdLocked(mTaskId,
17748                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17749                    }
17750                } finally {
17751                    Binder.restoreCallingIdentity(origId);
17752                }
17753            }
17754        }
17755
17756        @Override
17757        public ActivityManager.RecentTaskInfo getTaskInfo() {
17758            // Ensure that we are called from the same process that created this AppTask
17759            if (mCallingUid != Binder.getCallingUid()) {
17760                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17761                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17762                return null;
17763            }
17764
17765            synchronized (ActivityManagerService.this) {
17766                long origId = Binder.clearCallingIdentity();
17767                try {
17768                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17769                    if (tr != null) {
17770                        return createRecentTaskInfoFromTaskRecord(tr);
17771                    }
17772                } finally {
17773                    Binder.restoreCallingIdentity(origId);
17774                }
17775                return null;
17776            }
17777        }
17778    }
17779}
17780