ActivityManagerService.java revision 0debc9aff4c0cbc28e083a948081d91b0f171319
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.intent != null &&
7427                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7428                            != 0 && tr.getTopActivity() == null) {
7429                        // Don't include auto remove tasks that are finished or finishing.
7430                        continue;
7431                    }
7432
7433                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7434                    if (!detailed) {
7435                        rti.baseIntent.replaceExtras((Bundle)null);
7436                    }
7437
7438                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7439                        // Check whether this activity is currently available.
7440                        try {
7441                            if (rti.origActivity != null) {
7442                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7443                                        == null) {
7444                                    continue;
7445                                }
7446                            } else if (rti.baseIntent != null) {
7447                                if (pm.queryIntentActivities(rti.baseIntent,
7448                                        null, 0, userId) == null) {
7449                                    continue;
7450                                }
7451                            }
7452                        } catch (RemoteException e) {
7453                            // Will never happen.
7454                        }
7455                    }
7456
7457                    res.add(rti);
7458                    maxNum--;
7459                }
7460            }
7461            return res;
7462        }
7463    }
7464
7465    private TaskRecord recentTaskForIdLocked(int id) {
7466        final int N = mRecentTasks.size();
7467            for (int i=0; i<N; i++) {
7468                TaskRecord tr = mRecentTasks.get(i);
7469                if (tr.taskId == id) {
7470                    return tr;
7471                }
7472            }
7473            return null;
7474    }
7475
7476    @Override
7477    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7478        synchronized (this) {
7479            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7480                    "getTaskThumbnail()");
7481            TaskRecord tr = recentTaskForIdLocked(id);
7482            if (tr != null) {
7483                return tr.getTaskThumbnailLocked();
7484            }
7485        }
7486        return null;
7487    }
7488
7489    @Override
7490    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7491        synchronized (this) {
7492            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7493            if (r != null) {
7494                r.taskDescription = td;
7495                r.task.updateTaskDescription();
7496            }
7497        }
7498    }
7499
7500    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7501        if (!pr.killedByAm) {
7502            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7503            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7504                    pr.processName, pr.setAdj, reason);
7505            pr.killedByAm = true;
7506            Process.killProcessQuiet(pr.pid);
7507            Process.killProcessGroup(pr.info.uid, pr.pid);
7508        }
7509    }
7510
7511    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7512        tr.disposeThumbnail();
7513        mRecentTasks.remove(tr);
7514        tr.closeRecentsChain();
7515        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7516        Intent baseIntent = new Intent(
7517                tr.intent != null ? tr.intent : tr.affinityIntent);
7518        ComponentName component = baseIntent.getComponent();
7519        if (component == null) {
7520            Slog.w(TAG, "Now component for base intent of task: " + tr);
7521            return;
7522        }
7523
7524        // Find any running services associated with this app.
7525        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7526
7527        if (killProcesses) {
7528            // Find any running processes associated with this app.
7529            final String pkg = component.getPackageName();
7530            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7531            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7532            for (int i=0; i<pmap.size(); i++) {
7533                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7534                for (int j=0; j<uids.size(); j++) {
7535                    ProcessRecord proc = uids.valueAt(j);
7536                    if (proc.userId != tr.userId) {
7537                        continue;
7538                    }
7539                    if (!proc.pkgList.containsKey(pkg)) {
7540                        continue;
7541                    }
7542                    procs.add(proc);
7543                }
7544            }
7545
7546            // Kill the running processes.
7547            for (int i=0; i<procs.size(); i++) {
7548                ProcessRecord pr = procs.get(i);
7549                if (pr == mHomeProcess) {
7550                    // Don't kill the home process along with tasks from the same package.
7551                    continue;
7552                }
7553                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7554                    killUnneededProcessLocked(pr, "remove task");
7555                } else {
7556                    pr.waitingToKill = "remove task";
7557                }
7558            }
7559        }
7560    }
7561
7562    /**
7563     * Removes the task with the specified task id.
7564     *
7565     * @param taskId Identifier of the task to be removed.
7566     * @param flags Additional operational flags.  May be 0 or
7567     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7568     * @return Returns true if the given task was found and removed.
7569     */
7570    private boolean removeTaskByIdLocked(int taskId, int flags) {
7571        TaskRecord tr = recentTaskForIdLocked(taskId);
7572        if (tr != null) {
7573            tr.removeTaskActivitiesLocked();
7574            cleanUpRemovedTaskLocked(tr, flags);
7575            if (tr.isPersistable) {
7576                notifyTaskPersisterLocked(tr, true);
7577            }
7578            return true;
7579        }
7580        return false;
7581    }
7582
7583    @Override
7584    public boolean removeTask(int taskId, int flags) {
7585        synchronized (this) {
7586            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7587                    "removeTask()");
7588            long ident = Binder.clearCallingIdentity();
7589            try {
7590                return removeTaskByIdLocked(taskId, flags);
7591            } finally {
7592                Binder.restoreCallingIdentity(ident);
7593            }
7594        }
7595    }
7596
7597    /**
7598     * TODO: Add mController hook
7599     */
7600    @Override
7601    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7602        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7603                "moveTaskToFront()");
7604
7605        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7606        synchronized(this) {
7607            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7608                    Binder.getCallingUid(), "Task to front")) {
7609                ActivityOptions.abort(options);
7610                return;
7611            }
7612            final long origId = Binder.clearCallingIdentity();
7613            try {
7614                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7615                if (task == null) {
7616                    return;
7617                }
7618                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7619                    mStackSupervisor.showLockTaskToast();
7620                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7621                    return;
7622                }
7623                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7624                if (prev != null && prev.isRecentsActivity()) {
7625                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7626                }
7627                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7628            } finally {
7629                Binder.restoreCallingIdentity(origId);
7630            }
7631            ActivityOptions.abort(options);
7632        }
7633    }
7634
7635    @Override
7636    public void moveTaskToBack(int taskId) {
7637        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7638                "moveTaskToBack()");
7639
7640        synchronized(this) {
7641            TaskRecord tr = recentTaskForIdLocked(taskId);
7642            if (tr != null) {
7643                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7644                ActivityStack stack = tr.stack;
7645                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7646                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7647                            Binder.getCallingUid(), "Task to back")) {
7648                        return;
7649                    }
7650                }
7651                final long origId = Binder.clearCallingIdentity();
7652                try {
7653                    stack.moveTaskToBackLocked(taskId, null);
7654                } finally {
7655                    Binder.restoreCallingIdentity(origId);
7656                }
7657            }
7658        }
7659    }
7660
7661    /**
7662     * Moves an activity, and all of the other activities within the same task, to the bottom
7663     * of the history stack.  The activity's order within the task is unchanged.
7664     *
7665     * @param token A reference to the activity we wish to move
7666     * @param nonRoot If false then this only works if the activity is the root
7667     *                of a task; if true it will work for any activity in a task.
7668     * @return Returns true if the move completed, false if not.
7669     */
7670    @Override
7671    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7672        enforceNotIsolatedCaller("moveActivityTaskToBack");
7673        synchronized(this) {
7674            final long origId = Binder.clearCallingIdentity();
7675            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7676            if (taskId >= 0) {
7677                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7678            }
7679            Binder.restoreCallingIdentity(origId);
7680        }
7681        return false;
7682    }
7683
7684    @Override
7685    public void moveTaskBackwards(int task) {
7686        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7687                "moveTaskBackwards()");
7688
7689        synchronized(this) {
7690            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7691                    Binder.getCallingUid(), "Task backwards")) {
7692                return;
7693            }
7694            final long origId = Binder.clearCallingIdentity();
7695            moveTaskBackwardsLocked(task);
7696            Binder.restoreCallingIdentity(origId);
7697        }
7698    }
7699
7700    private final void moveTaskBackwardsLocked(int task) {
7701        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7702    }
7703
7704    @Override
7705    public IBinder getHomeActivityToken() throws RemoteException {
7706        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7707                "getHomeActivityToken()");
7708        synchronized (this) {
7709            return mStackSupervisor.getHomeActivityToken();
7710        }
7711    }
7712
7713    @Override
7714    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7715            IActivityContainerCallback callback) throws RemoteException {
7716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7717                "createActivityContainer()");
7718        synchronized (this) {
7719            if (parentActivityToken == null) {
7720                throw new IllegalArgumentException("parent token must not be null");
7721            }
7722            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7723            if (r == null) {
7724                return null;
7725            }
7726            if (callback == null) {
7727                throw new IllegalArgumentException("callback must not be null");
7728            }
7729            return mStackSupervisor.createActivityContainer(r, callback);
7730        }
7731    }
7732
7733    @Override
7734    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7735        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7736                "deleteActivityContainer()");
7737        synchronized (this) {
7738            mStackSupervisor.deleteActivityContainer(container);
7739        }
7740    }
7741
7742    @Override
7743    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7744            throws RemoteException {
7745        synchronized (this) {
7746            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7747            if (stack != null) {
7748                return stack.mActivityContainer;
7749            }
7750            return null;
7751        }
7752    }
7753
7754    @Override
7755    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7756        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7757                "moveTaskToStack()");
7758        if (stackId == HOME_STACK_ID) {
7759            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7760                    new RuntimeException("here").fillInStackTrace());
7761        }
7762        synchronized (this) {
7763            long ident = Binder.clearCallingIdentity();
7764            try {
7765                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7766                        + stackId + " toTop=" + toTop);
7767                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7768            } finally {
7769                Binder.restoreCallingIdentity(ident);
7770            }
7771        }
7772    }
7773
7774    @Override
7775    public void resizeStack(int stackBoxId, Rect bounds) {
7776        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7777                "resizeStackBox()");
7778        long ident = Binder.clearCallingIdentity();
7779        try {
7780            mWindowManager.resizeStack(stackBoxId, bounds);
7781        } finally {
7782            Binder.restoreCallingIdentity(ident);
7783        }
7784    }
7785
7786    @Override
7787    public List<StackInfo> getAllStackInfos() {
7788        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7789                "getAllStackInfos()");
7790        long ident = Binder.clearCallingIdentity();
7791        try {
7792            synchronized (this) {
7793                return mStackSupervisor.getAllStackInfosLocked();
7794            }
7795        } finally {
7796            Binder.restoreCallingIdentity(ident);
7797        }
7798    }
7799
7800    @Override
7801    public StackInfo getStackInfo(int stackId) {
7802        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7803                "getStackInfo()");
7804        long ident = Binder.clearCallingIdentity();
7805        try {
7806            synchronized (this) {
7807                return mStackSupervisor.getStackInfoLocked(stackId);
7808            }
7809        } finally {
7810            Binder.restoreCallingIdentity(ident);
7811        }
7812    }
7813
7814    @Override
7815    public boolean isInHomeStack(int taskId) {
7816        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7817                "getStackInfo()");
7818        long ident = Binder.clearCallingIdentity();
7819        try {
7820            synchronized (this) {
7821                TaskRecord tr = recentTaskForIdLocked(taskId);
7822                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7823            }
7824        } finally {
7825            Binder.restoreCallingIdentity(ident);
7826        }
7827    }
7828
7829    @Override
7830    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7831        synchronized(this) {
7832            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7833        }
7834    }
7835
7836    private boolean isLockTaskAuthorized(String pkg) {
7837        final DevicePolicyManager dpm = (DevicePolicyManager)
7838                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7839        try {
7840            int uid = mContext.getPackageManager().getPackageUid(pkg,
7841                    Binder.getCallingUserHandle().getIdentifier());
7842            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7843        } catch (NameNotFoundException e) {
7844            return false;
7845        }
7846    }
7847
7848    void startLockTaskMode(TaskRecord task) {
7849        final String pkg;
7850        synchronized (this) {
7851            pkg = task.intent.getComponent().getPackageName();
7852        }
7853        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7854        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7855            final TaskRecord taskRecord = task;
7856            mHandler.post(new Runnable() {
7857                @Override
7858                public void run() {
7859                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7860                }
7861            });
7862            return;
7863        }
7864        long ident = Binder.clearCallingIdentity();
7865        try {
7866            synchronized (this) {
7867                // Since we lost lock on task, make sure it is still there.
7868                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7869                if (task != null) {
7870                    if (!isSystemInitiated
7871                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7872                        throw new IllegalArgumentException("Invalid task, not in foreground");
7873                    }
7874                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7875                }
7876            }
7877        } finally {
7878            Binder.restoreCallingIdentity(ident);
7879        }
7880    }
7881
7882    @Override
7883    public void startLockTaskMode(int taskId) {
7884        final TaskRecord task;
7885        long ident = Binder.clearCallingIdentity();
7886        try {
7887            synchronized (this) {
7888                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7889            }
7890        } finally {
7891            Binder.restoreCallingIdentity(ident);
7892        }
7893        if (task != null) {
7894            startLockTaskMode(task);
7895        }
7896    }
7897
7898    @Override
7899    public void startLockTaskMode(IBinder token) {
7900        final TaskRecord task;
7901        long ident = Binder.clearCallingIdentity();
7902        try {
7903            synchronized (this) {
7904                final ActivityRecord r = ActivityRecord.forToken(token);
7905                if (r == null) {
7906                    return;
7907                }
7908                task = r.task;
7909            }
7910        } finally {
7911            Binder.restoreCallingIdentity(ident);
7912        }
7913        if (task != null) {
7914            startLockTaskMode(task);
7915        }
7916    }
7917
7918    @Override
7919    public void startLockTaskModeOnCurrent() throws RemoteException {
7920        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7921        ActivityRecord r = null;
7922        synchronized (this) {
7923            r = mStackSupervisor.topRunningActivityLocked();
7924        }
7925        startLockTaskMode(r.task);
7926    }
7927
7928    @Override
7929    public void stopLockTaskMode() {
7930        // Verify that the user matches the package of the intent for the TaskRecord
7931        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7932        // and stopLockTaskMode.
7933        final int callingUid = Binder.getCallingUid();
7934        if (callingUid != Process.SYSTEM_UID) {
7935            try {
7936                String pkg =
7937                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7938                int uid = mContext.getPackageManager().getPackageUid(pkg,
7939                        Binder.getCallingUserHandle().getIdentifier());
7940                if (uid != callingUid) {
7941                    throw new SecurityException("Invalid uid, expected " + uid);
7942                }
7943            } catch (NameNotFoundException e) {
7944                Log.d(TAG, "stopLockTaskMode " + e);
7945                return;
7946            }
7947        }
7948        long ident = Binder.clearCallingIdentity();
7949        try {
7950            Log.d(TAG, "stopLockTaskMode");
7951            // Stop lock task
7952            synchronized (this) {
7953                mStackSupervisor.setLockTaskModeLocked(null, false);
7954            }
7955        } finally {
7956            Binder.restoreCallingIdentity(ident);
7957        }
7958    }
7959
7960    @Override
7961    public void stopLockTaskModeOnCurrent() throws RemoteException {
7962        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7963        long ident = Binder.clearCallingIdentity();
7964        try {
7965            stopLockTaskMode();
7966        } finally {
7967            Binder.restoreCallingIdentity(ident);
7968        }
7969    }
7970
7971    @Override
7972    public boolean isInLockTaskMode() {
7973        synchronized (this) {
7974            return mStackSupervisor.isInLockTaskMode();
7975        }
7976    }
7977
7978    // =========================================================
7979    // CONTENT PROVIDERS
7980    // =========================================================
7981
7982    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7983        List<ProviderInfo> providers = null;
7984        try {
7985            providers = AppGlobals.getPackageManager().
7986                queryContentProviders(app.processName, app.uid,
7987                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7988        } catch (RemoteException ex) {
7989        }
7990        if (DEBUG_MU)
7991            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7992        int userId = app.userId;
7993        if (providers != null) {
7994            int N = providers.size();
7995            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7996            for (int i=0; i<N; i++) {
7997                ProviderInfo cpi =
7998                    (ProviderInfo)providers.get(i);
7999                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8000                        cpi.name, cpi.flags);
8001                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8002                    // This is a singleton provider, but a user besides the
8003                    // default user is asking to initialize a process it runs
8004                    // in...  well, no, it doesn't actually run in this process,
8005                    // it runs in the process of the default user.  Get rid of it.
8006                    providers.remove(i);
8007                    N--;
8008                    i--;
8009                    continue;
8010                }
8011
8012                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8013                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8014                if (cpr == null) {
8015                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8016                    mProviderMap.putProviderByClass(comp, cpr);
8017                }
8018                if (DEBUG_MU)
8019                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8020                app.pubProviders.put(cpi.name, cpr);
8021                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8022                    // Don't add this if it is a platform component that is marked
8023                    // to run in multiple processes, because this is actually
8024                    // part of the framework so doesn't make sense to track as a
8025                    // separate apk in the process.
8026                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8027                            mProcessStats);
8028                }
8029                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8030            }
8031        }
8032        return providers;
8033    }
8034
8035    /**
8036     * Check if {@link ProcessRecord} has a possible chance at accessing the
8037     * given {@link ProviderInfo}. Final permission checking is always done
8038     * in {@link ContentProvider}.
8039     */
8040    private final String checkContentProviderPermissionLocked(
8041            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8042        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8043        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8044        boolean checkedGrants = false;
8045        if (checkUser) {
8046            // Looking for cross-user grants before enforcing the typical cross-users permissions
8047            int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid));
8048            if (tmpTargetUserId != userId) {
8049                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8050                    return null;
8051                }
8052                checkedGrants = true;
8053            }
8054            userId = handleIncomingUser(callingPid, callingUid, userId,
8055                    false, ALLOW_NON_FULL,
8056                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8057            if (userId != tmpTargetUserId) {
8058                // When we actually went to determine the final targer user ID, this ended
8059                // up different than our initial check for the authority.  This is because
8060                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8061                // SELF.  So we need to re-check the grants again.
8062                checkedGrants = false;
8063            }
8064        }
8065        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8066                cpi.applicationInfo.uid, cpi.exported)
8067                == PackageManager.PERMISSION_GRANTED) {
8068            return null;
8069        }
8070        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8071                cpi.applicationInfo.uid, cpi.exported)
8072                == PackageManager.PERMISSION_GRANTED) {
8073            return null;
8074        }
8075
8076        PathPermission[] pps = cpi.pathPermissions;
8077        if (pps != null) {
8078            int i = pps.length;
8079            while (i > 0) {
8080                i--;
8081                PathPermission pp = pps[i];
8082                String pprperm = pp.getReadPermission();
8083                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8084                        cpi.applicationInfo.uid, cpi.exported)
8085                        == PackageManager.PERMISSION_GRANTED) {
8086                    return null;
8087                }
8088                String ppwperm = pp.getWritePermission();
8089                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8090                        cpi.applicationInfo.uid, cpi.exported)
8091                        == PackageManager.PERMISSION_GRANTED) {
8092                    return null;
8093                }
8094            }
8095        }
8096        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8097            return null;
8098        }
8099
8100        String msg;
8101        if (!cpi.exported) {
8102            msg = "Permission Denial: opening provider " + cpi.name
8103                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8104                    + ", uid=" + callingUid + ") that is not exported from uid "
8105                    + cpi.applicationInfo.uid;
8106        } else {
8107            msg = "Permission Denial: opening provider " + cpi.name
8108                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8109                    + ", uid=" + callingUid + ") requires "
8110                    + cpi.readPermission + " or " + cpi.writePermission;
8111        }
8112        Slog.w(TAG, msg);
8113        return msg;
8114    }
8115
8116    /**
8117     * Returns if the ContentProvider has granted a uri to callingUid
8118     */
8119    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8120        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8121        if (perms != null) {
8122            for (int i=perms.size()-1; i>=0; i--) {
8123                GrantUri grantUri = perms.keyAt(i);
8124                if (grantUri.sourceUserId == userId || !checkUser) {
8125                    if (matchesProvider(grantUri.uri, cpi)) {
8126                        return true;
8127                    }
8128                }
8129            }
8130        }
8131        return false;
8132    }
8133
8134    /**
8135     * Returns true if the uri authority is one of the authorities specified in the provider.
8136     */
8137    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8138        String uriAuth = uri.getAuthority();
8139        String cpiAuth = cpi.authority;
8140        if (cpiAuth.indexOf(';') == -1) {
8141            return cpiAuth.equals(uriAuth);
8142        }
8143        String[] cpiAuths = cpiAuth.split(";");
8144        int length = cpiAuths.length;
8145        for (int i = 0; i < length; i++) {
8146            if (cpiAuths[i].equals(uriAuth)) return true;
8147        }
8148        return false;
8149    }
8150
8151    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8152            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8153        if (r != null) {
8154            for (int i=0; i<r.conProviders.size(); i++) {
8155                ContentProviderConnection conn = r.conProviders.get(i);
8156                if (conn.provider == cpr) {
8157                    if (DEBUG_PROVIDER) Slog.v(TAG,
8158                            "Adding provider requested by "
8159                            + r.processName + " from process "
8160                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8161                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8162                    if (stable) {
8163                        conn.stableCount++;
8164                        conn.numStableIncs++;
8165                    } else {
8166                        conn.unstableCount++;
8167                        conn.numUnstableIncs++;
8168                    }
8169                    return conn;
8170                }
8171            }
8172            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8173            if (stable) {
8174                conn.stableCount = 1;
8175                conn.numStableIncs = 1;
8176            } else {
8177                conn.unstableCount = 1;
8178                conn.numUnstableIncs = 1;
8179            }
8180            cpr.connections.add(conn);
8181            r.conProviders.add(conn);
8182            return conn;
8183        }
8184        cpr.addExternalProcessHandleLocked(externalProcessToken);
8185        return null;
8186    }
8187
8188    boolean decProviderCountLocked(ContentProviderConnection conn,
8189            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8190        if (conn != null) {
8191            cpr = conn.provider;
8192            if (DEBUG_PROVIDER) Slog.v(TAG,
8193                    "Removing provider requested by "
8194                    + conn.client.processName + " from process "
8195                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8196                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8197            if (stable) {
8198                conn.stableCount--;
8199            } else {
8200                conn.unstableCount--;
8201            }
8202            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8203                cpr.connections.remove(conn);
8204                conn.client.conProviders.remove(conn);
8205                return true;
8206            }
8207            return false;
8208        }
8209        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8210        return false;
8211    }
8212
8213    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8214            String name, IBinder token, boolean stable, int userId) {
8215        ContentProviderRecord cpr;
8216        ContentProviderConnection conn = null;
8217        ProviderInfo cpi = null;
8218
8219        synchronized(this) {
8220            ProcessRecord r = null;
8221            if (caller != null) {
8222                r = getRecordForAppLocked(caller);
8223                if (r == null) {
8224                    throw new SecurityException(
8225                            "Unable to find app for caller " + caller
8226                          + " (pid=" + Binder.getCallingPid()
8227                          + ") when getting content provider " + name);
8228                }
8229            }
8230
8231            boolean checkCrossUser = true;
8232
8233            // First check if this content provider has been published...
8234            cpr = mProviderMap.getProviderByName(name, userId);
8235            // If that didn't work, check if it exists for user 0 and then
8236            // verify that it's a singleton provider before using it.
8237            if (cpr == null && userId != UserHandle.USER_OWNER) {
8238                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8239                if (cpr != null) {
8240                    cpi = cpr.info;
8241                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8242                            cpi.name, cpi.flags)
8243                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8244                        userId = UserHandle.USER_OWNER;
8245                        checkCrossUser = false;
8246                    } else {
8247                        cpr = null;
8248                        cpi = null;
8249                    }
8250                }
8251            }
8252
8253            boolean providerRunning = cpr != null;
8254            if (providerRunning) {
8255                cpi = cpr.info;
8256                String msg;
8257                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8258                        != null) {
8259                    throw new SecurityException(msg);
8260                }
8261
8262                if (r != null && cpr.canRunHere(r)) {
8263                    // This provider has been published or is in the process
8264                    // of being published...  but it is also allowed to run
8265                    // in the caller's process, so don't make a connection
8266                    // and just let the caller instantiate its own instance.
8267                    ContentProviderHolder holder = cpr.newHolder(null);
8268                    // don't give caller the provider object, it needs
8269                    // to make its own.
8270                    holder.provider = null;
8271                    return holder;
8272                }
8273
8274                final long origId = Binder.clearCallingIdentity();
8275
8276                // In this case the provider instance already exists, so we can
8277                // return it right away.
8278                conn = incProviderCountLocked(r, cpr, token, stable);
8279                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8280                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8281                        // If this is a perceptible app accessing the provider,
8282                        // make sure to count it as being accessed and thus
8283                        // back up on the LRU list.  This is good because
8284                        // content providers are often expensive to start.
8285                        updateLruProcessLocked(cpr.proc, false, null);
8286                    }
8287                }
8288
8289                if (cpr.proc != null) {
8290                    if (false) {
8291                        if (cpr.name.flattenToShortString().equals(
8292                                "com.android.providers.calendar/.CalendarProvider2")) {
8293                            Slog.v(TAG, "****************** KILLING "
8294                                + cpr.name.flattenToShortString());
8295                            Process.killProcess(cpr.proc.pid);
8296                        }
8297                    }
8298                    boolean success = updateOomAdjLocked(cpr.proc);
8299                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8300                    // NOTE: there is still a race here where a signal could be
8301                    // pending on the process even though we managed to update its
8302                    // adj level.  Not sure what to do about this, but at least
8303                    // the race is now smaller.
8304                    if (!success) {
8305                        // Uh oh...  it looks like the provider's process
8306                        // has been killed on us.  We need to wait for a new
8307                        // process to be started, and make sure its death
8308                        // doesn't kill our process.
8309                        Slog.i(TAG,
8310                                "Existing provider " + cpr.name.flattenToShortString()
8311                                + " is crashing; detaching " + r);
8312                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8313                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8314                        if (!lastRef) {
8315                            // This wasn't the last ref our process had on
8316                            // the provider...  we have now been killed, bail.
8317                            return null;
8318                        }
8319                        providerRunning = false;
8320                        conn = null;
8321                    }
8322                }
8323
8324                Binder.restoreCallingIdentity(origId);
8325            }
8326
8327            boolean singleton;
8328            if (!providerRunning) {
8329                try {
8330                    cpi = AppGlobals.getPackageManager().
8331                        resolveContentProvider(name,
8332                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8333                } catch (RemoteException ex) {
8334                }
8335                if (cpi == null) {
8336                    return null;
8337                }
8338                // If the provider is a singleton AND
8339                // (it's a call within the same user || the provider is a
8340                // privileged app)
8341                // Then allow connecting to the singleton provider
8342                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8343                        cpi.name, cpi.flags)
8344                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8345                if (singleton) {
8346                    userId = UserHandle.USER_OWNER;
8347                }
8348                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8349
8350                String msg;
8351                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8352                        != null) {
8353                    throw new SecurityException(msg);
8354                }
8355
8356                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8357                        && !cpi.processName.equals("system")) {
8358                    // If this content provider does not run in the system
8359                    // process, and the system is not yet ready to run other
8360                    // processes, then fail fast instead of hanging.
8361                    throw new IllegalArgumentException(
8362                            "Attempt to launch content provider before system ready");
8363                }
8364
8365                // Make sure that the user who owns this provider is started.  If not,
8366                // we don't want to allow it to run.
8367                if (mStartedUsers.get(userId) == null) {
8368                    Slog.w(TAG, "Unable to launch app "
8369                            + cpi.applicationInfo.packageName + "/"
8370                            + cpi.applicationInfo.uid + " for provider "
8371                            + name + ": user " + userId + " is stopped");
8372                    return null;
8373                }
8374
8375                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8376                cpr = mProviderMap.getProviderByClass(comp, userId);
8377                final boolean firstClass = cpr == null;
8378                if (firstClass) {
8379                    try {
8380                        ApplicationInfo ai =
8381                            AppGlobals.getPackageManager().
8382                                getApplicationInfo(
8383                                        cpi.applicationInfo.packageName,
8384                                        STOCK_PM_FLAGS, userId);
8385                        if (ai == null) {
8386                            Slog.w(TAG, "No package info for content provider "
8387                                    + cpi.name);
8388                            return null;
8389                        }
8390                        ai = getAppInfoForUser(ai, userId);
8391                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8392                    } catch (RemoteException ex) {
8393                        // pm is in same process, this will never happen.
8394                    }
8395                }
8396
8397                if (r != null && cpr.canRunHere(r)) {
8398                    // If this is a multiprocess provider, then just return its
8399                    // info and allow the caller to instantiate it.  Only do
8400                    // this if the provider is the same user as the caller's
8401                    // process, or can run as root (so can be in any process).
8402                    return cpr.newHolder(null);
8403                }
8404
8405                if (DEBUG_PROVIDER) {
8406                    RuntimeException e = new RuntimeException("here");
8407                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8408                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8409                }
8410
8411                // This is single process, and our app is now connecting to it.
8412                // See if we are already in the process of launching this
8413                // provider.
8414                final int N = mLaunchingProviders.size();
8415                int i;
8416                for (i=0; i<N; i++) {
8417                    if (mLaunchingProviders.get(i) == cpr) {
8418                        break;
8419                    }
8420                }
8421
8422                // If the provider is not already being launched, then get it
8423                // started.
8424                if (i >= N) {
8425                    final long origId = Binder.clearCallingIdentity();
8426
8427                    try {
8428                        // Content provider is now in use, its package can't be stopped.
8429                        try {
8430                            AppGlobals.getPackageManager().setPackageStoppedState(
8431                                    cpr.appInfo.packageName, false, userId);
8432                        } catch (RemoteException e) {
8433                        } catch (IllegalArgumentException e) {
8434                            Slog.w(TAG, "Failed trying to unstop package "
8435                                    + cpr.appInfo.packageName + ": " + e);
8436                        }
8437
8438                        // Use existing process if already started
8439                        ProcessRecord proc = getProcessRecordLocked(
8440                                cpi.processName, cpr.appInfo.uid, false);
8441                        if (proc != null && proc.thread != null) {
8442                            if (DEBUG_PROVIDER) {
8443                                Slog.d(TAG, "Installing in existing process " + proc);
8444                            }
8445                            proc.pubProviders.put(cpi.name, cpr);
8446                            try {
8447                                proc.thread.scheduleInstallProvider(cpi);
8448                            } catch (RemoteException e) {
8449                            }
8450                        } else {
8451                            proc = startProcessLocked(cpi.processName,
8452                                    cpr.appInfo, false, 0, "content provider",
8453                                    new ComponentName(cpi.applicationInfo.packageName,
8454                                            cpi.name), false, false, false);
8455                            if (proc == null) {
8456                                Slog.w(TAG, "Unable to launch app "
8457                                        + cpi.applicationInfo.packageName + "/"
8458                                        + cpi.applicationInfo.uid + " for provider "
8459                                        + name + ": process is bad");
8460                                return null;
8461                            }
8462                        }
8463                        cpr.launchingApp = proc;
8464                        mLaunchingProviders.add(cpr);
8465                    } finally {
8466                        Binder.restoreCallingIdentity(origId);
8467                    }
8468                }
8469
8470                // Make sure the provider is published (the same provider class
8471                // may be published under multiple names).
8472                if (firstClass) {
8473                    mProviderMap.putProviderByClass(comp, cpr);
8474                }
8475
8476                mProviderMap.putProviderByName(name, cpr);
8477                conn = incProviderCountLocked(r, cpr, token, stable);
8478                if (conn != null) {
8479                    conn.waiting = true;
8480                }
8481            }
8482        }
8483
8484        // Wait for the provider to be published...
8485        synchronized (cpr) {
8486            while (cpr.provider == null) {
8487                if (cpr.launchingApp == null) {
8488                    Slog.w(TAG, "Unable to launch app "
8489                            + cpi.applicationInfo.packageName + "/"
8490                            + cpi.applicationInfo.uid + " for provider "
8491                            + name + ": launching app became null");
8492                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8493                            UserHandle.getUserId(cpi.applicationInfo.uid),
8494                            cpi.applicationInfo.packageName,
8495                            cpi.applicationInfo.uid, name);
8496                    return null;
8497                }
8498                try {
8499                    if (DEBUG_MU) {
8500                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8501                                + cpr.launchingApp);
8502                    }
8503                    if (conn != null) {
8504                        conn.waiting = true;
8505                    }
8506                    cpr.wait();
8507                } catch (InterruptedException ex) {
8508                } finally {
8509                    if (conn != null) {
8510                        conn.waiting = false;
8511                    }
8512                }
8513            }
8514        }
8515        return cpr != null ? cpr.newHolder(conn) : null;
8516    }
8517
8518    @Override
8519    public final ContentProviderHolder getContentProvider(
8520            IApplicationThread caller, String name, int userId, boolean stable) {
8521        enforceNotIsolatedCaller("getContentProvider");
8522        if (caller == null) {
8523            String msg = "null IApplicationThread when getting content provider "
8524                    + name;
8525            Slog.w(TAG, msg);
8526            throw new SecurityException(msg);
8527        }
8528        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8529        // with cross-user grant.
8530        return getContentProviderImpl(caller, name, null, stable, userId);
8531    }
8532
8533    public ContentProviderHolder getContentProviderExternal(
8534            String name, int userId, IBinder token) {
8535        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8536            "Do not have permission in call getContentProviderExternal()");
8537        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8538                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8539        return getContentProviderExternalUnchecked(name, token, userId);
8540    }
8541
8542    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8543            IBinder token, int userId) {
8544        return getContentProviderImpl(null, name, token, true, userId);
8545    }
8546
8547    /**
8548     * Drop a content provider from a ProcessRecord's bookkeeping
8549     */
8550    public void removeContentProvider(IBinder connection, boolean stable) {
8551        enforceNotIsolatedCaller("removeContentProvider");
8552        long ident = Binder.clearCallingIdentity();
8553        try {
8554            synchronized (this) {
8555                ContentProviderConnection conn;
8556                try {
8557                    conn = (ContentProviderConnection)connection;
8558                } catch (ClassCastException e) {
8559                    String msg ="removeContentProvider: " + connection
8560                            + " not a ContentProviderConnection";
8561                    Slog.w(TAG, msg);
8562                    throw new IllegalArgumentException(msg);
8563                }
8564                if (conn == null) {
8565                    throw new NullPointerException("connection is null");
8566                }
8567                if (decProviderCountLocked(conn, null, null, stable)) {
8568                    updateOomAdjLocked();
8569                }
8570            }
8571        } finally {
8572            Binder.restoreCallingIdentity(ident);
8573        }
8574    }
8575
8576    public void removeContentProviderExternal(String name, IBinder token) {
8577        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8578            "Do not have permission in call removeContentProviderExternal()");
8579        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8580    }
8581
8582    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8583        synchronized (this) {
8584            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8585            if(cpr == null) {
8586                //remove from mProvidersByClass
8587                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8588                return;
8589            }
8590
8591            //update content provider record entry info
8592            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8593            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8594            if (localCpr.hasExternalProcessHandles()) {
8595                if (localCpr.removeExternalProcessHandleLocked(token)) {
8596                    updateOomAdjLocked();
8597                } else {
8598                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8599                            + " with no external reference for token: "
8600                            + token + ".");
8601                }
8602            } else {
8603                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8604                        + " with no external references.");
8605            }
8606        }
8607    }
8608
8609    public final void publishContentProviders(IApplicationThread caller,
8610            List<ContentProviderHolder> providers) {
8611        if (providers == null) {
8612            return;
8613        }
8614
8615        enforceNotIsolatedCaller("publishContentProviders");
8616        synchronized (this) {
8617            final ProcessRecord r = getRecordForAppLocked(caller);
8618            if (DEBUG_MU)
8619                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8620            if (r == null) {
8621                throw new SecurityException(
8622                        "Unable to find app for caller " + caller
8623                      + " (pid=" + Binder.getCallingPid()
8624                      + ") when publishing content providers");
8625            }
8626
8627            final long origId = Binder.clearCallingIdentity();
8628
8629            final int N = providers.size();
8630            for (int i=0; i<N; i++) {
8631                ContentProviderHolder src = providers.get(i);
8632                if (src == null || src.info == null || src.provider == null) {
8633                    continue;
8634                }
8635                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8636                if (DEBUG_MU)
8637                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8638                if (dst != null) {
8639                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8640                    mProviderMap.putProviderByClass(comp, dst);
8641                    String names[] = dst.info.authority.split(";");
8642                    for (int j = 0; j < names.length; j++) {
8643                        mProviderMap.putProviderByName(names[j], dst);
8644                    }
8645
8646                    int NL = mLaunchingProviders.size();
8647                    int j;
8648                    for (j=0; j<NL; j++) {
8649                        if (mLaunchingProviders.get(j) == dst) {
8650                            mLaunchingProviders.remove(j);
8651                            j--;
8652                            NL--;
8653                        }
8654                    }
8655                    synchronized (dst) {
8656                        dst.provider = src.provider;
8657                        dst.proc = r;
8658                        dst.notifyAll();
8659                    }
8660                    updateOomAdjLocked(r);
8661                }
8662            }
8663
8664            Binder.restoreCallingIdentity(origId);
8665        }
8666    }
8667
8668    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8669        ContentProviderConnection conn;
8670        try {
8671            conn = (ContentProviderConnection)connection;
8672        } catch (ClassCastException e) {
8673            String msg ="refContentProvider: " + connection
8674                    + " not a ContentProviderConnection";
8675            Slog.w(TAG, msg);
8676            throw new IllegalArgumentException(msg);
8677        }
8678        if (conn == null) {
8679            throw new NullPointerException("connection is null");
8680        }
8681
8682        synchronized (this) {
8683            if (stable > 0) {
8684                conn.numStableIncs += stable;
8685            }
8686            stable = conn.stableCount + stable;
8687            if (stable < 0) {
8688                throw new IllegalStateException("stableCount < 0: " + stable);
8689            }
8690
8691            if (unstable > 0) {
8692                conn.numUnstableIncs += unstable;
8693            }
8694            unstable = conn.unstableCount + unstable;
8695            if (unstable < 0) {
8696                throw new IllegalStateException("unstableCount < 0: " + unstable);
8697            }
8698
8699            if ((stable+unstable) <= 0) {
8700                throw new IllegalStateException("ref counts can't go to zero here: stable="
8701                        + stable + " unstable=" + unstable);
8702            }
8703            conn.stableCount = stable;
8704            conn.unstableCount = unstable;
8705            return !conn.dead;
8706        }
8707    }
8708
8709    public void unstableProviderDied(IBinder connection) {
8710        ContentProviderConnection conn;
8711        try {
8712            conn = (ContentProviderConnection)connection;
8713        } catch (ClassCastException e) {
8714            String msg ="refContentProvider: " + connection
8715                    + " not a ContentProviderConnection";
8716            Slog.w(TAG, msg);
8717            throw new IllegalArgumentException(msg);
8718        }
8719        if (conn == null) {
8720            throw new NullPointerException("connection is null");
8721        }
8722
8723        // Safely retrieve the content provider associated with the connection.
8724        IContentProvider provider;
8725        synchronized (this) {
8726            provider = conn.provider.provider;
8727        }
8728
8729        if (provider == null) {
8730            // Um, yeah, we're way ahead of you.
8731            return;
8732        }
8733
8734        // Make sure the caller is being honest with us.
8735        if (provider.asBinder().pingBinder()) {
8736            // Er, no, still looks good to us.
8737            synchronized (this) {
8738                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8739                        + " says " + conn + " died, but we don't agree");
8740                return;
8741            }
8742        }
8743
8744        // Well look at that!  It's dead!
8745        synchronized (this) {
8746            if (conn.provider.provider != provider) {
8747                // But something changed...  good enough.
8748                return;
8749            }
8750
8751            ProcessRecord proc = conn.provider.proc;
8752            if (proc == null || proc.thread == null) {
8753                // Seems like the process is already cleaned up.
8754                return;
8755            }
8756
8757            // As far as we're concerned, this is just like receiving a
8758            // death notification...  just a bit prematurely.
8759            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8760                    + ") early provider death");
8761            final long ident = Binder.clearCallingIdentity();
8762            try {
8763                appDiedLocked(proc, proc.pid, proc.thread);
8764            } finally {
8765                Binder.restoreCallingIdentity(ident);
8766            }
8767        }
8768    }
8769
8770    @Override
8771    public void appNotRespondingViaProvider(IBinder connection) {
8772        enforceCallingPermission(
8773                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8774
8775        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8776        if (conn == null) {
8777            Slog.w(TAG, "ContentProviderConnection is null");
8778            return;
8779        }
8780
8781        final ProcessRecord host = conn.provider.proc;
8782        if (host == null) {
8783            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8784            return;
8785        }
8786
8787        final long token = Binder.clearCallingIdentity();
8788        try {
8789            appNotResponding(host, null, null, false, "ContentProvider not responding");
8790        } finally {
8791            Binder.restoreCallingIdentity(token);
8792        }
8793    }
8794
8795    public final void installSystemProviders() {
8796        List<ProviderInfo> providers;
8797        synchronized (this) {
8798            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8799            providers = generateApplicationProvidersLocked(app);
8800            if (providers != null) {
8801                for (int i=providers.size()-1; i>=0; i--) {
8802                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8803                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8804                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8805                                + ": not system .apk");
8806                        providers.remove(i);
8807                    }
8808                }
8809            }
8810        }
8811        if (providers != null) {
8812            mSystemThread.installSystemProviders(providers);
8813        }
8814
8815        mCoreSettingsObserver = new CoreSettingsObserver(this);
8816
8817        //mUsageStatsService.monitorPackages();
8818    }
8819
8820    /**
8821     * Allows app to retrieve the MIME type of a URI without having permission
8822     * to access its content provider.
8823     *
8824     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8825     *
8826     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8827     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8828     */
8829    public String getProviderMimeType(Uri uri, int userId) {
8830        enforceNotIsolatedCaller("getProviderMimeType");
8831        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8832                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8833        final String name = uri.getAuthority();
8834        final long ident = Binder.clearCallingIdentity();
8835        ContentProviderHolder holder = null;
8836
8837        try {
8838            holder = getContentProviderExternalUnchecked(name, null, userId);
8839            if (holder != null) {
8840                return holder.provider.getType(uri);
8841            }
8842        } catch (RemoteException e) {
8843            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8844            return null;
8845        } finally {
8846            if (holder != null) {
8847                removeContentProviderExternalUnchecked(name, null, userId);
8848            }
8849            Binder.restoreCallingIdentity(ident);
8850        }
8851
8852        return null;
8853    }
8854
8855    // =========================================================
8856    // GLOBAL MANAGEMENT
8857    // =========================================================
8858
8859    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8860            boolean isolated) {
8861        String proc = customProcess != null ? customProcess : info.processName;
8862        BatteryStatsImpl.Uid.Proc ps = null;
8863        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8864        int uid = info.uid;
8865        if (isolated) {
8866            int userId = UserHandle.getUserId(uid);
8867            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8868            while (true) {
8869                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8870                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8871                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8872                }
8873                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8874                mNextIsolatedProcessUid++;
8875                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8876                    // No process for this uid, use it.
8877                    break;
8878                }
8879                stepsLeft--;
8880                if (stepsLeft <= 0) {
8881                    return null;
8882                }
8883            }
8884        }
8885        return new ProcessRecord(stats, info, proc, uid);
8886    }
8887
8888    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8889            String abiOverride) {
8890        ProcessRecord app;
8891        if (!isolated) {
8892            app = getProcessRecordLocked(info.processName, info.uid, true);
8893        } else {
8894            app = null;
8895        }
8896
8897        if (app == null) {
8898            app = newProcessRecordLocked(info, null, isolated);
8899            mProcessNames.put(info.processName, app.uid, app);
8900            if (isolated) {
8901                mIsolatedProcesses.put(app.uid, app);
8902            }
8903            updateLruProcessLocked(app, false, null);
8904            updateOomAdjLocked();
8905        }
8906
8907        // This package really, really can not be stopped.
8908        try {
8909            AppGlobals.getPackageManager().setPackageStoppedState(
8910                    info.packageName, false, UserHandle.getUserId(app.uid));
8911        } catch (RemoteException e) {
8912        } catch (IllegalArgumentException e) {
8913            Slog.w(TAG, "Failed trying to unstop package "
8914                    + info.packageName + ": " + e);
8915        }
8916
8917        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8918                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8919            app.persistent = true;
8920            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8921        }
8922        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8923            mPersistentStartingProcesses.add(app);
8924            startProcessLocked(app, "added application", app.processName,
8925                    abiOverride);
8926        }
8927
8928        return app;
8929    }
8930
8931    public void unhandledBack() {
8932        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8933                "unhandledBack()");
8934
8935        synchronized(this) {
8936            final long origId = Binder.clearCallingIdentity();
8937            try {
8938                getFocusedStack().unhandledBackLocked();
8939            } finally {
8940                Binder.restoreCallingIdentity(origId);
8941            }
8942        }
8943    }
8944
8945    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8946        enforceNotIsolatedCaller("openContentUri");
8947        final int userId = UserHandle.getCallingUserId();
8948        String name = uri.getAuthority();
8949        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8950        ParcelFileDescriptor pfd = null;
8951        if (cph != null) {
8952            // We record the binder invoker's uid in thread-local storage before
8953            // going to the content provider to open the file.  Later, in the code
8954            // that handles all permissions checks, we look for this uid and use
8955            // that rather than the Activity Manager's own uid.  The effect is that
8956            // we do the check against the caller's permissions even though it looks
8957            // to the content provider like the Activity Manager itself is making
8958            // the request.
8959            sCallerIdentity.set(new Identity(
8960                    Binder.getCallingPid(), Binder.getCallingUid()));
8961            try {
8962                pfd = cph.provider.openFile(null, uri, "r", null);
8963            } catch (FileNotFoundException e) {
8964                // do nothing; pfd will be returned null
8965            } finally {
8966                // Ensure that whatever happens, we clean up the identity state
8967                sCallerIdentity.remove();
8968            }
8969
8970            // We've got the fd now, so we're done with the provider.
8971            removeContentProviderExternalUnchecked(name, null, userId);
8972        } else {
8973            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8974        }
8975        return pfd;
8976    }
8977
8978    // Actually is sleeping or shutting down or whatever else in the future
8979    // is an inactive state.
8980    public boolean isSleepingOrShuttingDown() {
8981        return mSleeping || mShuttingDown;
8982    }
8983
8984    public boolean isSleeping() {
8985        return mSleeping;
8986    }
8987
8988    void goingToSleep() {
8989        synchronized(this) {
8990            mWentToSleep = true;
8991            updateEventDispatchingLocked();
8992            goToSleepIfNeededLocked();
8993        }
8994    }
8995
8996    void finishRunningVoiceLocked() {
8997        if (mRunningVoice) {
8998            mRunningVoice = false;
8999            goToSleepIfNeededLocked();
9000        }
9001    }
9002
9003    void goToSleepIfNeededLocked() {
9004        if (mWentToSleep && !mRunningVoice) {
9005            if (!mSleeping) {
9006                mSleeping = true;
9007                mStackSupervisor.goingToSleepLocked();
9008
9009                // Initialize the wake times of all processes.
9010                checkExcessivePowerUsageLocked(false);
9011                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9012                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9013                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9014            }
9015        }
9016    }
9017
9018    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9019        mTaskPersister.notify(task, flush);
9020    }
9021
9022    @Override
9023    public boolean shutdown(int timeout) {
9024        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9025                != PackageManager.PERMISSION_GRANTED) {
9026            throw new SecurityException("Requires permission "
9027                    + android.Manifest.permission.SHUTDOWN);
9028        }
9029
9030        boolean timedout = false;
9031
9032        synchronized(this) {
9033            mShuttingDown = true;
9034            updateEventDispatchingLocked();
9035            timedout = mStackSupervisor.shutdownLocked(timeout);
9036        }
9037
9038        mAppOpsService.shutdown();
9039        if (mUsageStatsService != null) {
9040            mUsageStatsService.prepareShutdown();
9041        }
9042        mBatteryStatsService.shutdown();
9043        synchronized (this) {
9044            mProcessStats.shutdownLocked();
9045        }
9046        notifyTaskPersisterLocked(null, true);
9047
9048        return timedout;
9049    }
9050
9051    public final void activitySlept(IBinder token) {
9052        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9053
9054        final long origId = Binder.clearCallingIdentity();
9055
9056        synchronized (this) {
9057            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9058            if (r != null) {
9059                mStackSupervisor.activitySleptLocked(r);
9060            }
9061        }
9062
9063        Binder.restoreCallingIdentity(origId);
9064    }
9065
9066    void logLockScreen(String msg) {
9067        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9068                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9069                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9070                mStackSupervisor.mDismissKeyguardOnNextActivity);
9071    }
9072
9073    private void comeOutOfSleepIfNeededLocked() {
9074        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9075            if (mSleeping) {
9076                mSleeping = false;
9077                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9078            }
9079        }
9080    }
9081
9082    void wakingUp() {
9083        synchronized(this) {
9084            mWentToSleep = false;
9085            updateEventDispatchingLocked();
9086            comeOutOfSleepIfNeededLocked();
9087        }
9088    }
9089
9090    void startRunningVoiceLocked() {
9091        if (!mRunningVoice) {
9092            mRunningVoice = true;
9093            comeOutOfSleepIfNeededLocked();
9094        }
9095    }
9096
9097    private void updateEventDispatchingLocked() {
9098        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9099    }
9100
9101    public void setLockScreenShown(boolean shown) {
9102        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9103                != PackageManager.PERMISSION_GRANTED) {
9104            throw new SecurityException("Requires permission "
9105                    + android.Manifest.permission.DEVICE_POWER);
9106        }
9107
9108        synchronized(this) {
9109            long ident = Binder.clearCallingIdentity();
9110            try {
9111                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9112                mLockScreenShown = shown;
9113                comeOutOfSleepIfNeededLocked();
9114            } finally {
9115                Binder.restoreCallingIdentity(ident);
9116            }
9117        }
9118    }
9119
9120    @Override
9121    public void stopAppSwitches() {
9122        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9123                != PackageManager.PERMISSION_GRANTED) {
9124            throw new SecurityException("Requires permission "
9125                    + android.Manifest.permission.STOP_APP_SWITCHES);
9126        }
9127
9128        synchronized(this) {
9129            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9130                    + APP_SWITCH_DELAY_TIME;
9131            mDidAppSwitch = false;
9132            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9133            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9134            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9135        }
9136    }
9137
9138    public void resumeAppSwitches() {
9139        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9140                != PackageManager.PERMISSION_GRANTED) {
9141            throw new SecurityException("Requires permission "
9142                    + android.Manifest.permission.STOP_APP_SWITCHES);
9143        }
9144
9145        synchronized(this) {
9146            // Note that we don't execute any pending app switches... we will
9147            // let those wait until either the timeout, or the next start
9148            // activity request.
9149            mAppSwitchesAllowedTime = 0;
9150        }
9151    }
9152
9153    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9154            String name) {
9155        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9156            return true;
9157        }
9158
9159        final int perm = checkComponentPermission(
9160                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9161                callingUid, -1, true);
9162        if (perm == PackageManager.PERMISSION_GRANTED) {
9163            return true;
9164        }
9165
9166        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9167        return false;
9168    }
9169
9170    public void setDebugApp(String packageName, boolean waitForDebugger,
9171            boolean persistent) {
9172        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9173                "setDebugApp()");
9174
9175        long ident = Binder.clearCallingIdentity();
9176        try {
9177            // Note that this is not really thread safe if there are multiple
9178            // callers into it at the same time, but that's not a situation we
9179            // care about.
9180            if (persistent) {
9181                final ContentResolver resolver = mContext.getContentResolver();
9182                Settings.Global.putString(
9183                    resolver, Settings.Global.DEBUG_APP,
9184                    packageName);
9185                Settings.Global.putInt(
9186                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9187                    waitForDebugger ? 1 : 0);
9188            }
9189
9190            synchronized (this) {
9191                if (!persistent) {
9192                    mOrigDebugApp = mDebugApp;
9193                    mOrigWaitForDebugger = mWaitForDebugger;
9194                }
9195                mDebugApp = packageName;
9196                mWaitForDebugger = waitForDebugger;
9197                mDebugTransient = !persistent;
9198                if (packageName != null) {
9199                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9200                            false, UserHandle.USER_ALL, "set debug app");
9201                }
9202            }
9203        } finally {
9204            Binder.restoreCallingIdentity(ident);
9205        }
9206    }
9207
9208    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9209        synchronized (this) {
9210            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9211            if (!isDebuggable) {
9212                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9213                    throw new SecurityException("Process not debuggable: " + app.packageName);
9214                }
9215            }
9216
9217            mOpenGlTraceApp = processName;
9218        }
9219    }
9220
9221    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9222            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9223        synchronized (this) {
9224            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9225            if (!isDebuggable) {
9226                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9227                    throw new SecurityException("Process not debuggable: " + app.packageName);
9228                }
9229            }
9230            mProfileApp = processName;
9231            mProfileFile = profileFile;
9232            if (mProfileFd != null) {
9233                try {
9234                    mProfileFd.close();
9235                } catch (IOException e) {
9236                }
9237                mProfileFd = null;
9238            }
9239            mProfileFd = profileFd;
9240            mProfileType = 0;
9241            mAutoStopProfiler = autoStopProfiler;
9242        }
9243    }
9244
9245    @Override
9246    public void setAlwaysFinish(boolean enabled) {
9247        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9248                "setAlwaysFinish()");
9249
9250        Settings.Global.putInt(
9251                mContext.getContentResolver(),
9252                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9253
9254        synchronized (this) {
9255            mAlwaysFinishActivities = enabled;
9256        }
9257    }
9258
9259    @Override
9260    public void setActivityController(IActivityController controller) {
9261        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9262                "setActivityController()");
9263        synchronized (this) {
9264            mController = controller;
9265            Watchdog.getInstance().setActivityController(controller);
9266        }
9267    }
9268
9269    @Override
9270    public void setUserIsMonkey(boolean userIsMonkey) {
9271        synchronized (this) {
9272            synchronized (mPidsSelfLocked) {
9273                final int callingPid = Binder.getCallingPid();
9274                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9275                if (precessRecord == null) {
9276                    throw new SecurityException("Unknown process: " + callingPid);
9277                }
9278                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9279                    throw new SecurityException("Only an instrumentation process "
9280                            + "with a UiAutomation can call setUserIsMonkey");
9281                }
9282            }
9283            mUserIsMonkey = userIsMonkey;
9284        }
9285    }
9286
9287    @Override
9288    public boolean isUserAMonkey() {
9289        synchronized (this) {
9290            // If there is a controller also implies the user is a monkey.
9291            return (mUserIsMonkey || mController != null);
9292        }
9293    }
9294
9295    public void requestBugReport() {
9296        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9297        SystemProperties.set("ctl.start", "bugreport");
9298    }
9299
9300    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9301        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9302    }
9303
9304    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9305        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9306            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9307        }
9308        return KEY_DISPATCHING_TIMEOUT;
9309    }
9310
9311    @Override
9312    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9313        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9314                != PackageManager.PERMISSION_GRANTED) {
9315            throw new SecurityException("Requires permission "
9316                    + android.Manifest.permission.FILTER_EVENTS);
9317        }
9318        ProcessRecord proc;
9319        long timeout;
9320        synchronized (this) {
9321            synchronized (mPidsSelfLocked) {
9322                proc = mPidsSelfLocked.get(pid);
9323            }
9324            timeout = getInputDispatchingTimeoutLocked(proc);
9325        }
9326
9327        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9328            return -1;
9329        }
9330
9331        return timeout;
9332    }
9333
9334    /**
9335     * Handle input dispatching timeouts.
9336     * Returns whether input dispatching should be aborted or not.
9337     */
9338    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9339            final ActivityRecord activity, final ActivityRecord parent,
9340            final boolean aboveSystem, String reason) {
9341        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9342                != PackageManager.PERMISSION_GRANTED) {
9343            throw new SecurityException("Requires permission "
9344                    + android.Manifest.permission.FILTER_EVENTS);
9345        }
9346
9347        final String annotation;
9348        if (reason == null) {
9349            annotation = "Input dispatching timed out";
9350        } else {
9351            annotation = "Input dispatching timed out (" + reason + ")";
9352        }
9353
9354        if (proc != null) {
9355            synchronized (this) {
9356                if (proc.debugging) {
9357                    return false;
9358                }
9359
9360                if (mDidDexOpt) {
9361                    // Give more time since we were dexopting.
9362                    mDidDexOpt = false;
9363                    return false;
9364                }
9365
9366                if (proc.instrumentationClass != null) {
9367                    Bundle info = new Bundle();
9368                    info.putString("shortMsg", "keyDispatchingTimedOut");
9369                    info.putString("longMsg", annotation);
9370                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9371                    return true;
9372                }
9373            }
9374            mHandler.post(new Runnable() {
9375                @Override
9376                public void run() {
9377                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9378                }
9379            });
9380        }
9381
9382        return true;
9383    }
9384
9385    public Bundle getAssistContextExtras(int requestType) {
9386        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9387                "getAssistContextExtras()");
9388        PendingAssistExtras pae;
9389        Bundle extras = new Bundle();
9390        synchronized (this) {
9391            ActivityRecord activity = getFocusedStack().mResumedActivity;
9392            if (activity == null) {
9393                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9394                return null;
9395            }
9396            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9397            if (activity.app == null || activity.app.thread == null) {
9398                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9399                return extras;
9400            }
9401            if (activity.app.pid == Binder.getCallingPid()) {
9402                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9403                return extras;
9404            }
9405            pae = new PendingAssistExtras(activity);
9406            try {
9407                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9408                        requestType);
9409                mPendingAssistExtras.add(pae);
9410                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9411            } catch (RemoteException e) {
9412                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9413                return extras;
9414            }
9415        }
9416        synchronized (pae) {
9417            while (!pae.haveResult) {
9418                try {
9419                    pae.wait();
9420                } catch (InterruptedException e) {
9421                }
9422            }
9423            if (pae.result != null) {
9424                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9425            }
9426        }
9427        synchronized (this) {
9428            mPendingAssistExtras.remove(pae);
9429            mHandler.removeCallbacks(pae);
9430        }
9431        return extras;
9432    }
9433
9434    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9435        PendingAssistExtras pae = (PendingAssistExtras)token;
9436        synchronized (pae) {
9437            pae.result = extras;
9438            pae.haveResult = true;
9439            pae.notifyAll();
9440        }
9441    }
9442
9443    public void registerProcessObserver(IProcessObserver observer) {
9444        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9445                "registerProcessObserver()");
9446        synchronized (this) {
9447            mProcessObservers.register(observer);
9448        }
9449    }
9450
9451    @Override
9452    public void unregisterProcessObserver(IProcessObserver observer) {
9453        synchronized (this) {
9454            mProcessObservers.unregister(observer);
9455        }
9456    }
9457
9458    @Override
9459    public boolean convertFromTranslucent(IBinder token) {
9460        final long origId = Binder.clearCallingIdentity();
9461        try {
9462            synchronized (this) {
9463                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9464                if (r == null) {
9465                    return false;
9466                }
9467                if (r.changeWindowTranslucency(true)) {
9468                    mWindowManager.setAppFullscreen(token, true);
9469                    r.task.stack.releaseMediaResources();
9470                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9471                    return true;
9472                }
9473                return false;
9474            }
9475        } finally {
9476            Binder.restoreCallingIdentity(origId);
9477        }
9478    }
9479
9480    @Override
9481    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9482        final long origId = Binder.clearCallingIdentity();
9483        try {
9484            synchronized (this) {
9485                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9486                if (r == null) {
9487                    return false;
9488                }
9489                if (r.changeWindowTranslucency(false)) {
9490                    r.task.stack.convertToTranslucent(r, options);
9491                    mWindowManager.setAppFullscreen(token, false);
9492                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9493                    return true;
9494                } else {
9495                    r.task.stack.mReturningActivityOptions = options;
9496                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9497                    return false;
9498                }
9499            }
9500        } finally {
9501            Binder.restoreCallingIdentity(origId);
9502        }
9503    }
9504
9505    @Override
9506    public boolean setMediaPlaying(IBinder token, boolean playing) {
9507        final long origId = Binder.clearCallingIdentity();
9508        try {
9509            synchronized (this) {
9510                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9511                if (r != null) {
9512                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9513                }
9514            }
9515            return false;
9516        } finally {
9517            Binder.restoreCallingIdentity(origId);
9518        }
9519    }
9520
9521    @Override
9522    public boolean isBackgroundMediaPlaying(IBinder token) {
9523        final long origId = Binder.clearCallingIdentity();
9524        try {
9525            synchronized (this) {
9526                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9527                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9528                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9529                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9530                return playing;
9531            }
9532        } finally {
9533            Binder.restoreCallingIdentity(origId);
9534        }
9535    }
9536
9537    @Override
9538    public ActivityOptions getActivityOptions(IBinder token) {
9539        final long origId = Binder.clearCallingIdentity();
9540        try {
9541            synchronized (this) {
9542                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9543                if (r != null) {
9544                    final ActivityOptions activityOptions = r.pendingOptions;
9545                    r.pendingOptions = null;
9546                    return activityOptions;
9547                }
9548                return null;
9549            }
9550        } finally {
9551            Binder.restoreCallingIdentity(origId);
9552        }
9553    }
9554
9555    @Override
9556    public void setImmersive(IBinder token, boolean immersive) {
9557        synchronized(this) {
9558            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9559            if (r == null) {
9560                throw new IllegalArgumentException();
9561            }
9562            r.immersive = immersive;
9563
9564            // update associated state if we're frontmost
9565            if (r == mFocusedActivity) {
9566                if (DEBUG_IMMERSIVE) {
9567                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9568                }
9569                applyUpdateLockStateLocked(r);
9570            }
9571        }
9572    }
9573
9574    @Override
9575    public boolean isImmersive(IBinder token) {
9576        synchronized (this) {
9577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9578            if (r == null) {
9579                throw new IllegalArgumentException();
9580            }
9581            return r.immersive;
9582        }
9583    }
9584
9585    public boolean isTopActivityImmersive() {
9586        enforceNotIsolatedCaller("startActivity");
9587        synchronized (this) {
9588            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9589            return (r != null) ? r.immersive : false;
9590        }
9591    }
9592
9593    @Override
9594    public boolean isTopOfTask(IBinder token) {
9595        synchronized (this) {
9596            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9597            if (r == null) {
9598                throw new IllegalArgumentException();
9599            }
9600            return r.task.getTopActivity() == r;
9601        }
9602    }
9603
9604    public final void enterSafeMode() {
9605        synchronized(this) {
9606            // It only makes sense to do this before the system is ready
9607            // and started launching other packages.
9608            if (!mSystemReady) {
9609                try {
9610                    AppGlobals.getPackageManager().enterSafeMode();
9611                } catch (RemoteException e) {
9612                }
9613            }
9614
9615            mSafeMode = true;
9616        }
9617    }
9618
9619    public final void showSafeModeOverlay() {
9620        View v = LayoutInflater.from(mContext).inflate(
9621                com.android.internal.R.layout.safe_mode, null);
9622        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9623        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9624        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9625        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9626        lp.gravity = Gravity.BOTTOM | Gravity.START;
9627        lp.format = v.getBackground().getOpacity();
9628        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9629                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9630        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9631        ((WindowManager)mContext.getSystemService(
9632                Context.WINDOW_SERVICE)).addView(v, lp);
9633    }
9634
9635    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9636        if (!(sender instanceof PendingIntentRecord)) {
9637            return;
9638        }
9639        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9640        synchronized (stats) {
9641            if (mBatteryStatsService.isOnBattery()) {
9642                mBatteryStatsService.enforceCallingPermission();
9643                PendingIntentRecord rec = (PendingIntentRecord)sender;
9644                int MY_UID = Binder.getCallingUid();
9645                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9646                BatteryStatsImpl.Uid.Pkg pkg =
9647                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9648                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9649                pkg.incWakeupsLocked();
9650            }
9651        }
9652    }
9653
9654    public boolean killPids(int[] pids, String pReason, boolean secure) {
9655        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9656            throw new SecurityException("killPids only available to the system");
9657        }
9658        String reason = (pReason == null) ? "Unknown" : pReason;
9659        // XXX Note: don't acquire main activity lock here, because the window
9660        // manager calls in with its locks held.
9661
9662        boolean killed = false;
9663        synchronized (mPidsSelfLocked) {
9664            int[] types = new int[pids.length];
9665            int worstType = 0;
9666            for (int i=0; i<pids.length; i++) {
9667                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9668                if (proc != null) {
9669                    int type = proc.setAdj;
9670                    types[i] = type;
9671                    if (type > worstType) {
9672                        worstType = type;
9673                    }
9674                }
9675            }
9676
9677            // If the worst oom_adj is somewhere in the cached proc LRU range,
9678            // then constrain it so we will kill all cached procs.
9679            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9680                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9681                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9682            }
9683
9684            // If this is not a secure call, don't let it kill processes that
9685            // are important.
9686            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9687                worstType = ProcessList.SERVICE_ADJ;
9688            }
9689
9690            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9691            for (int i=0; i<pids.length; i++) {
9692                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9693                if (proc == null) {
9694                    continue;
9695                }
9696                int adj = proc.setAdj;
9697                if (adj >= worstType && !proc.killedByAm) {
9698                    killUnneededProcessLocked(proc, reason);
9699                    killed = true;
9700                }
9701            }
9702        }
9703        return killed;
9704    }
9705
9706    @Override
9707    public void killUid(int uid, String reason) {
9708        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9709            throw new SecurityException("killUid only available to the system");
9710        }
9711        synchronized (this) {
9712            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9713                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9714                    reason != null ? reason : "kill uid");
9715        }
9716    }
9717
9718    @Override
9719    public boolean killProcessesBelowForeground(String reason) {
9720        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9721            throw new SecurityException("killProcessesBelowForeground() only available to system");
9722        }
9723
9724        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9725    }
9726
9727    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9728        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9729            throw new SecurityException("killProcessesBelowAdj() only available to system");
9730        }
9731
9732        boolean killed = false;
9733        synchronized (mPidsSelfLocked) {
9734            final int size = mPidsSelfLocked.size();
9735            for (int i = 0; i < size; i++) {
9736                final int pid = mPidsSelfLocked.keyAt(i);
9737                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9738                if (proc == null) continue;
9739
9740                final int adj = proc.setAdj;
9741                if (adj > belowAdj && !proc.killedByAm) {
9742                    killUnneededProcessLocked(proc, reason);
9743                    killed = true;
9744                }
9745            }
9746        }
9747        return killed;
9748    }
9749
9750    @Override
9751    public void hang(final IBinder who, boolean allowRestart) {
9752        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9753                != PackageManager.PERMISSION_GRANTED) {
9754            throw new SecurityException("Requires permission "
9755                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9756        }
9757
9758        final IBinder.DeathRecipient death = new DeathRecipient() {
9759            @Override
9760            public void binderDied() {
9761                synchronized (this) {
9762                    notifyAll();
9763                }
9764            }
9765        };
9766
9767        try {
9768            who.linkToDeath(death, 0);
9769        } catch (RemoteException e) {
9770            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9771            return;
9772        }
9773
9774        synchronized (this) {
9775            Watchdog.getInstance().setAllowRestart(allowRestart);
9776            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9777            synchronized (death) {
9778                while (who.isBinderAlive()) {
9779                    try {
9780                        death.wait();
9781                    } catch (InterruptedException e) {
9782                    }
9783                }
9784            }
9785            Watchdog.getInstance().setAllowRestart(true);
9786        }
9787    }
9788
9789    @Override
9790    public void restart() {
9791        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9792                != PackageManager.PERMISSION_GRANTED) {
9793            throw new SecurityException("Requires permission "
9794                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9795        }
9796
9797        Log.i(TAG, "Sending shutdown broadcast...");
9798
9799        BroadcastReceiver br = new BroadcastReceiver() {
9800            @Override public void onReceive(Context context, Intent intent) {
9801                // Now the broadcast is done, finish up the low-level shutdown.
9802                Log.i(TAG, "Shutting down activity manager...");
9803                shutdown(10000);
9804                Log.i(TAG, "Shutdown complete, restarting!");
9805                Process.killProcess(Process.myPid());
9806                System.exit(10);
9807            }
9808        };
9809
9810        // First send the high-level shut down broadcast.
9811        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9812        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9813        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9814        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9815        mContext.sendOrderedBroadcastAsUser(intent,
9816                UserHandle.ALL, null, br, mHandler, 0, null, null);
9817        */
9818        br.onReceive(mContext, intent);
9819    }
9820
9821    private long getLowRamTimeSinceIdle(long now) {
9822        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9823    }
9824
9825    @Override
9826    public void performIdleMaintenance() {
9827        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9828                != PackageManager.PERMISSION_GRANTED) {
9829            throw new SecurityException("Requires permission "
9830                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9831        }
9832
9833        synchronized (this) {
9834            final long now = SystemClock.uptimeMillis();
9835            final long timeSinceLastIdle = now - mLastIdleTime;
9836            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9837            mLastIdleTime = now;
9838            mLowRamTimeSinceLastIdle = 0;
9839            if (mLowRamStartTime != 0) {
9840                mLowRamStartTime = now;
9841            }
9842
9843            StringBuilder sb = new StringBuilder(128);
9844            sb.append("Idle maintenance over ");
9845            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9846            sb.append(" low RAM for ");
9847            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9848            Slog.i(TAG, sb.toString());
9849
9850            // If at least 1/3 of our time since the last idle period has been spent
9851            // with RAM low, then we want to kill processes.
9852            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9853
9854            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9855                ProcessRecord proc = mLruProcesses.get(i);
9856                if (proc.notCachedSinceIdle) {
9857                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9858                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9859                        if (doKilling && proc.initialIdlePss != 0
9860                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9861                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9862                                    + " from " + proc.initialIdlePss + ")");
9863                        }
9864                    }
9865                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9866                    proc.notCachedSinceIdle = true;
9867                    proc.initialIdlePss = 0;
9868                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9869                            isSleeping(), now);
9870                }
9871            }
9872
9873            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9874            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9875        }
9876    }
9877
9878    private void retrieveSettings() {
9879        final ContentResolver resolver = mContext.getContentResolver();
9880        String debugApp = Settings.Global.getString(
9881            resolver, Settings.Global.DEBUG_APP);
9882        boolean waitForDebugger = Settings.Global.getInt(
9883            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9884        boolean alwaysFinishActivities = Settings.Global.getInt(
9885            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9886        boolean forceRtl = Settings.Global.getInt(
9887                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9888        // Transfer any global setting for forcing RTL layout, into a System Property
9889        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9890
9891        Configuration configuration = new Configuration();
9892        Settings.System.getConfiguration(resolver, configuration);
9893        if (forceRtl) {
9894            // This will take care of setting the correct layout direction flags
9895            configuration.setLayoutDirection(configuration.locale);
9896        }
9897
9898        synchronized (this) {
9899            mDebugApp = mOrigDebugApp = debugApp;
9900            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9901            mAlwaysFinishActivities = alwaysFinishActivities;
9902            // This happens before any activities are started, so we can
9903            // change mConfiguration in-place.
9904            updateConfigurationLocked(configuration, null, false, true);
9905            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9906        }
9907    }
9908
9909    public boolean testIsSystemReady() {
9910        // no need to synchronize(this) just to read & return the value
9911        return mSystemReady;
9912    }
9913
9914    private static File getCalledPreBootReceiversFile() {
9915        File dataDir = Environment.getDataDirectory();
9916        File systemDir = new File(dataDir, "system");
9917        File fname = new File(systemDir, "called_pre_boots.dat");
9918        return fname;
9919    }
9920
9921    static final int LAST_DONE_VERSION = 10000;
9922
9923    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9924        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9925        File file = getCalledPreBootReceiversFile();
9926        FileInputStream fis = null;
9927        try {
9928            fis = new FileInputStream(file);
9929            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9930            int fvers = dis.readInt();
9931            if (fvers == LAST_DONE_VERSION) {
9932                String vers = dis.readUTF();
9933                String codename = dis.readUTF();
9934                String build = dis.readUTF();
9935                if (android.os.Build.VERSION.RELEASE.equals(vers)
9936                        && android.os.Build.VERSION.CODENAME.equals(codename)
9937                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9938                    int num = dis.readInt();
9939                    while (num > 0) {
9940                        num--;
9941                        String pkg = dis.readUTF();
9942                        String cls = dis.readUTF();
9943                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9944                    }
9945                }
9946            }
9947        } catch (FileNotFoundException e) {
9948        } catch (IOException e) {
9949            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9950        } finally {
9951            if (fis != null) {
9952                try {
9953                    fis.close();
9954                } catch (IOException e) {
9955                }
9956            }
9957        }
9958        return lastDoneReceivers;
9959    }
9960
9961    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9962        File file = getCalledPreBootReceiversFile();
9963        FileOutputStream fos = null;
9964        DataOutputStream dos = null;
9965        try {
9966            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9967            fos = new FileOutputStream(file);
9968            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9969            dos.writeInt(LAST_DONE_VERSION);
9970            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9971            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9972            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9973            dos.writeInt(list.size());
9974            for (int i=0; i<list.size(); i++) {
9975                dos.writeUTF(list.get(i).getPackageName());
9976                dos.writeUTF(list.get(i).getClassName());
9977            }
9978        } catch (IOException e) {
9979            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9980            file.delete();
9981        } finally {
9982            FileUtils.sync(fos);
9983            if (dos != null) {
9984                try {
9985                    dos.close();
9986                } catch (IOException e) {
9987                    // TODO Auto-generated catch block
9988                    e.printStackTrace();
9989                }
9990            }
9991        }
9992    }
9993
9994    public void systemReady(final Runnable goingCallback) {
9995        synchronized(this) {
9996            if (mSystemReady) {
9997                if (goingCallback != null) goingCallback.run();
9998                return;
9999            }
10000
10001            // Make sure we have the current profile info, since it is needed for
10002            // security checks.
10003            updateCurrentProfileIdsLocked();
10004
10005            if (mRecentTasks == null) {
10006                mRecentTasks = mTaskPersister.restoreTasksLocked();
10007                if (!mRecentTasks.isEmpty()) {
10008                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10009                }
10010                mTaskPersister.startPersisting();
10011            }
10012
10013            // Check to see if there are any update receivers to run.
10014            if (!mDidUpdate) {
10015                if (mWaitingUpdate) {
10016                    return;
10017                }
10018                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10019                List<ResolveInfo> ris = null;
10020                try {
10021                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
10022                            intent, null, 0, 0);
10023                } catch (RemoteException e) {
10024                }
10025                if (ris != null) {
10026                    for (int i=ris.size()-1; i>=0; i--) {
10027                        if ((ris.get(i).activityInfo.applicationInfo.flags
10028                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
10029                            ris.remove(i);
10030                        }
10031                    }
10032                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10033
10034                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10035
10036                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10037                    for (int i=0; i<ris.size(); i++) {
10038                        ActivityInfo ai = ris.get(i).activityInfo;
10039                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10040                        if (lastDoneReceivers.contains(comp)) {
10041                            // We already did the pre boot receiver for this app with the current
10042                            // platform version, so don't do it again...
10043                            ris.remove(i);
10044                            i--;
10045                            // ...however, do keep it as one that has been done, so we don't
10046                            // forget about it when rewriting the file of last done receivers.
10047                            doneReceivers.add(comp);
10048                        }
10049                    }
10050
10051                    final int[] users = getUsersLocked();
10052                    for (int i=0; i<ris.size(); i++) {
10053                        ActivityInfo ai = ris.get(i).activityInfo;
10054                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10055                        doneReceivers.add(comp);
10056                        intent.setComponent(comp);
10057                        for (int j=0; j<users.length; j++) {
10058                            IIntentReceiver finisher = null;
10059                            if (i == ris.size()-1 && j == users.length-1) {
10060                                finisher = new IIntentReceiver.Stub() {
10061                                    public void performReceive(Intent intent, int resultCode,
10062                                            String data, Bundle extras, boolean ordered,
10063                                            boolean sticky, int sendingUser) {
10064                                        // The raw IIntentReceiver interface is called
10065                                        // with the AM lock held, so redispatch to
10066                                        // execute our code without the lock.
10067                                        mHandler.post(new Runnable() {
10068                                            public void run() {
10069                                                synchronized (ActivityManagerService.this) {
10070                                                    mDidUpdate = true;
10071                                                }
10072                                                writeLastDonePreBootReceivers(doneReceivers);
10073                                                showBootMessage(mContext.getText(
10074                                                        R.string.android_upgrading_complete),
10075                                                        false);
10076                                                systemReady(goingCallback);
10077                                            }
10078                                        });
10079                                    }
10080                                };
10081                            }
10082                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
10083                                    + " for user " + users[j]);
10084                            broadcastIntentLocked(null, null, intent, null, finisher,
10085                                    0, null, null, null, AppOpsManager.OP_NONE,
10086                                    true, false, MY_PID, Process.SYSTEM_UID,
10087                                    users[j]);
10088                            if (finisher != null) {
10089                                mWaitingUpdate = true;
10090                            }
10091                        }
10092                    }
10093                }
10094                if (mWaitingUpdate) {
10095                    return;
10096                }
10097                mDidUpdate = true;
10098            }
10099
10100            mAppOpsService.systemReady();
10101            mSystemReady = true;
10102        }
10103
10104        ArrayList<ProcessRecord> procsToKill = null;
10105        synchronized(mPidsSelfLocked) {
10106            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10107                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10108                if (!isAllowedWhileBooting(proc.info)){
10109                    if (procsToKill == null) {
10110                        procsToKill = new ArrayList<ProcessRecord>();
10111                    }
10112                    procsToKill.add(proc);
10113                }
10114            }
10115        }
10116
10117        synchronized(this) {
10118            if (procsToKill != null) {
10119                for (int i=procsToKill.size()-1; i>=0; i--) {
10120                    ProcessRecord proc = procsToKill.get(i);
10121                    Slog.i(TAG, "Removing system update proc: " + proc);
10122                    removeProcessLocked(proc, true, false, "system update done");
10123                }
10124            }
10125
10126            // Now that we have cleaned up any update processes, we
10127            // are ready to start launching real processes and know that
10128            // we won't trample on them any more.
10129            mProcessesReady = true;
10130        }
10131
10132        Slog.i(TAG, "System now ready");
10133        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10134            SystemClock.uptimeMillis());
10135
10136        synchronized(this) {
10137            // Make sure we have no pre-ready processes sitting around.
10138
10139            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10140                ResolveInfo ri = mContext.getPackageManager()
10141                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10142                                STOCK_PM_FLAGS);
10143                CharSequence errorMsg = null;
10144                if (ri != null) {
10145                    ActivityInfo ai = ri.activityInfo;
10146                    ApplicationInfo app = ai.applicationInfo;
10147                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10148                        mTopAction = Intent.ACTION_FACTORY_TEST;
10149                        mTopData = null;
10150                        mTopComponent = new ComponentName(app.packageName,
10151                                ai.name);
10152                    } else {
10153                        errorMsg = mContext.getResources().getText(
10154                                com.android.internal.R.string.factorytest_not_system);
10155                    }
10156                } else {
10157                    errorMsg = mContext.getResources().getText(
10158                            com.android.internal.R.string.factorytest_no_action);
10159                }
10160                if (errorMsg != null) {
10161                    mTopAction = null;
10162                    mTopData = null;
10163                    mTopComponent = null;
10164                    Message msg = Message.obtain();
10165                    msg.what = SHOW_FACTORY_ERROR_MSG;
10166                    msg.getData().putCharSequence("msg", errorMsg);
10167                    mHandler.sendMessage(msg);
10168                }
10169            }
10170        }
10171
10172        retrieveSettings();
10173
10174        synchronized (this) {
10175            readGrantedUriPermissionsLocked();
10176        }
10177
10178        if (goingCallback != null) goingCallback.run();
10179
10180        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10181                Integer.toString(mCurrentUserId), mCurrentUserId);
10182        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10183                Integer.toString(mCurrentUserId), mCurrentUserId);
10184        mSystemServiceManager.startUser(mCurrentUserId);
10185
10186        synchronized (this) {
10187            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10188                try {
10189                    List apps = AppGlobals.getPackageManager().
10190                        getPersistentApplications(STOCK_PM_FLAGS);
10191                    if (apps != null) {
10192                        int N = apps.size();
10193                        int i;
10194                        for (i=0; i<N; i++) {
10195                            ApplicationInfo info
10196                                = (ApplicationInfo)apps.get(i);
10197                            if (info != null &&
10198                                    !info.packageName.equals("android")) {
10199                                addAppLocked(info, false, null /* ABI override */);
10200                            }
10201                        }
10202                    }
10203                } catch (RemoteException ex) {
10204                    // pm is in same process, this will never happen.
10205                }
10206            }
10207
10208            // Start up initial activity.
10209            mBooting = true;
10210
10211            try {
10212                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10213                    Message msg = Message.obtain();
10214                    msg.what = SHOW_UID_ERROR_MSG;
10215                    mHandler.sendMessage(msg);
10216                }
10217            } catch (RemoteException e) {
10218            }
10219
10220            long ident = Binder.clearCallingIdentity();
10221            try {
10222                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10223                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10224                        | Intent.FLAG_RECEIVER_FOREGROUND);
10225                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10226                broadcastIntentLocked(null, null, intent,
10227                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10228                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10229                intent = new Intent(Intent.ACTION_USER_STARTING);
10230                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10231                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10232                broadcastIntentLocked(null, null, intent,
10233                        null, new IIntentReceiver.Stub() {
10234                            @Override
10235                            public void performReceive(Intent intent, int resultCode, String data,
10236                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10237                                    throws RemoteException {
10238                            }
10239                        }, 0, null, null,
10240                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10241                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10242            } catch (Throwable t) {
10243                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10244            } finally {
10245                Binder.restoreCallingIdentity(ident);
10246            }
10247            mStackSupervisor.resumeTopActivitiesLocked();
10248            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10249        }
10250    }
10251
10252    private boolean makeAppCrashingLocked(ProcessRecord app,
10253            String shortMsg, String longMsg, String stackTrace) {
10254        app.crashing = true;
10255        app.crashingReport = generateProcessError(app,
10256                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10257        startAppProblemLocked(app);
10258        app.stopFreezingAllLocked();
10259        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10260    }
10261
10262    private void makeAppNotRespondingLocked(ProcessRecord app,
10263            String activity, String shortMsg, String longMsg) {
10264        app.notResponding = true;
10265        app.notRespondingReport = generateProcessError(app,
10266                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10267                activity, shortMsg, longMsg, null);
10268        startAppProblemLocked(app);
10269        app.stopFreezingAllLocked();
10270    }
10271
10272    /**
10273     * Generate a process error record, suitable for attachment to a ProcessRecord.
10274     *
10275     * @param app The ProcessRecord in which the error occurred.
10276     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10277     *                      ActivityManager.AppErrorStateInfo
10278     * @param activity The activity associated with the crash, if known.
10279     * @param shortMsg Short message describing the crash.
10280     * @param longMsg Long message describing the crash.
10281     * @param stackTrace Full crash stack trace, may be null.
10282     *
10283     * @return Returns a fully-formed AppErrorStateInfo record.
10284     */
10285    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10286            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10287        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10288
10289        report.condition = condition;
10290        report.processName = app.processName;
10291        report.pid = app.pid;
10292        report.uid = app.info.uid;
10293        report.tag = activity;
10294        report.shortMsg = shortMsg;
10295        report.longMsg = longMsg;
10296        report.stackTrace = stackTrace;
10297
10298        return report;
10299    }
10300
10301    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10302        synchronized (this) {
10303            app.crashing = false;
10304            app.crashingReport = null;
10305            app.notResponding = false;
10306            app.notRespondingReport = null;
10307            if (app.anrDialog == fromDialog) {
10308                app.anrDialog = null;
10309            }
10310            if (app.waitDialog == fromDialog) {
10311                app.waitDialog = null;
10312            }
10313            if (app.pid > 0 && app.pid != MY_PID) {
10314                handleAppCrashLocked(app, null, null, null);
10315                killUnneededProcessLocked(app, "user request after error");
10316            }
10317        }
10318    }
10319
10320    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10321            String stackTrace) {
10322        long now = SystemClock.uptimeMillis();
10323
10324        Long crashTime;
10325        if (!app.isolated) {
10326            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10327        } else {
10328            crashTime = null;
10329        }
10330        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10331            // This process loses!
10332            Slog.w(TAG, "Process " + app.info.processName
10333                    + " has crashed too many times: killing!");
10334            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10335                    app.userId, app.info.processName, app.uid);
10336            mStackSupervisor.handleAppCrashLocked(app);
10337            if (!app.persistent) {
10338                // We don't want to start this process again until the user
10339                // explicitly does so...  but for persistent process, we really
10340                // need to keep it running.  If a persistent process is actually
10341                // repeatedly crashing, then badness for everyone.
10342                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10343                        app.info.processName);
10344                if (!app.isolated) {
10345                    // XXX We don't have a way to mark isolated processes
10346                    // as bad, since they don't have a peristent identity.
10347                    mBadProcesses.put(app.info.processName, app.uid,
10348                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10349                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10350                }
10351                app.bad = true;
10352                app.removed = true;
10353                // Don't let services in this process be restarted and potentially
10354                // annoy the user repeatedly.  Unless it is persistent, since those
10355                // processes run critical code.
10356                removeProcessLocked(app, false, false, "crash");
10357                mStackSupervisor.resumeTopActivitiesLocked();
10358                return false;
10359            }
10360            mStackSupervisor.resumeTopActivitiesLocked();
10361        } else {
10362            mStackSupervisor.finishTopRunningActivityLocked(app);
10363        }
10364
10365        // Bump up the crash count of any services currently running in the proc.
10366        for (int i=app.services.size()-1; i>=0; i--) {
10367            // Any services running in the application need to be placed
10368            // back in the pending list.
10369            ServiceRecord sr = app.services.valueAt(i);
10370            sr.crashCount++;
10371        }
10372
10373        // If the crashing process is what we consider to be the "home process" and it has been
10374        // replaced by a third-party app, clear the package preferred activities from packages
10375        // with a home activity running in the process to prevent a repeatedly crashing app
10376        // from blocking the user to manually clear the list.
10377        final ArrayList<ActivityRecord> activities = app.activities;
10378        if (app == mHomeProcess && activities.size() > 0
10379                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10380            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10381                final ActivityRecord r = activities.get(activityNdx);
10382                if (r.isHomeActivity()) {
10383                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10384                    try {
10385                        ActivityThread.getPackageManager()
10386                                .clearPackagePreferredActivities(r.packageName);
10387                    } catch (RemoteException c) {
10388                        // pm is in same process, this will never happen.
10389                    }
10390                }
10391            }
10392        }
10393
10394        if (!app.isolated) {
10395            // XXX Can't keep track of crash times for isolated processes,
10396            // because they don't have a perisistent identity.
10397            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10398        }
10399
10400        return true;
10401    }
10402
10403    void startAppProblemLocked(ProcessRecord app) {
10404        if (app.userId == mCurrentUserId) {
10405            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10406                    mContext, app.info.packageName, app.info.flags);
10407        } else {
10408            // If this app is not running under the current user, then we
10409            // can't give it a report button because that would require
10410            // launching the report UI under a different user.
10411            app.errorReportReceiver = null;
10412        }
10413        skipCurrentReceiverLocked(app);
10414    }
10415
10416    void skipCurrentReceiverLocked(ProcessRecord app) {
10417        for (BroadcastQueue queue : mBroadcastQueues) {
10418            queue.skipCurrentReceiverLocked(app);
10419        }
10420    }
10421
10422    /**
10423     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10424     * The application process will exit immediately after this call returns.
10425     * @param app object of the crashing app, null for the system server
10426     * @param crashInfo describing the exception
10427     */
10428    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10429        ProcessRecord r = findAppProcess(app, "Crash");
10430        final String processName = app == null ? "system_server"
10431                : (r == null ? "unknown" : r.processName);
10432
10433        handleApplicationCrashInner("crash", r, processName, crashInfo);
10434    }
10435
10436    /* Native crash reporting uses this inner version because it needs to be somewhat
10437     * decoupled from the AM-managed cleanup lifecycle
10438     */
10439    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10440            ApplicationErrorReport.CrashInfo crashInfo) {
10441        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10442                UserHandle.getUserId(Binder.getCallingUid()), processName,
10443                r == null ? -1 : r.info.flags,
10444                crashInfo.exceptionClassName,
10445                crashInfo.exceptionMessage,
10446                crashInfo.throwFileName,
10447                crashInfo.throwLineNumber);
10448
10449        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10450
10451        crashApplication(r, crashInfo);
10452    }
10453
10454    public void handleApplicationStrictModeViolation(
10455            IBinder app,
10456            int violationMask,
10457            StrictMode.ViolationInfo info) {
10458        ProcessRecord r = findAppProcess(app, "StrictMode");
10459        if (r == null) {
10460            return;
10461        }
10462
10463        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10464            Integer stackFingerprint = info.hashCode();
10465            boolean logIt = true;
10466            synchronized (mAlreadyLoggedViolatedStacks) {
10467                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10468                    logIt = false;
10469                    // TODO: sub-sample into EventLog for these, with
10470                    // the info.durationMillis?  Then we'd get
10471                    // the relative pain numbers, without logging all
10472                    // the stack traces repeatedly.  We'd want to do
10473                    // likewise in the client code, which also does
10474                    // dup suppression, before the Binder call.
10475                } else {
10476                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10477                        mAlreadyLoggedViolatedStacks.clear();
10478                    }
10479                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10480                }
10481            }
10482            if (logIt) {
10483                logStrictModeViolationToDropBox(r, info);
10484            }
10485        }
10486
10487        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10488            AppErrorResult result = new AppErrorResult();
10489            synchronized (this) {
10490                final long origId = Binder.clearCallingIdentity();
10491
10492                Message msg = Message.obtain();
10493                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10494                HashMap<String, Object> data = new HashMap<String, Object>();
10495                data.put("result", result);
10496                data.put("app", r);
10497                data.put("violationMask", violationMask);
10498                data.put("info", info);
10499                msg.obj = data;
10500                mHandler.sendMessage(msg);
10501
10502                Binder.restoreCallingIdentity(origId);
10503            }
10504            int res = result.get();
10505            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10506        }
10507    }
10508
10509    // Depending on the policy in effect, there could be a bunch of
10510    // these in quick succession so we try to batch these together to
10511    // minimize disk writes, number of dropbox entries, and maximize
10512    // compression, by having more fewer, larger records.
10513    private void logStrictModeViolationToDropBox(
10514            ProcessRecord process,
10515            StrictMode.ViolationInfo info) {
10516        if (info == null) {
10517            return;
10518        }
10519        final boolean isSystemApp = process == null ||
10520                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10521                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10522        final String processName = process == null ? "unknown" : process.processName;
10523        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10524        final DropBoxManager dbox = (DropBoxManager)
10525                mContext.getSystemService(Context.DROPBOX_SERVICE);
10526
10527        // Exit early if the dropbox isn't configured to accept this report type.
10528        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10529
10530        boolean bufferWasEmpty;
10531        boolean needsFlush;
10532        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10533        synchronized (sb) {
10534            bufferWasEmpty = sb.length() == 0;
10535            appendDropBoxProcessHeaders(process, processName, sb);
10536            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10537            sb.append("System-App: ").append(isSystemApp).append("\n");
10538            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10539            if (info.violationNumThisLoop != 0) {
10540                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10541            }
10542            if (info.numAnimationsRunning != 0) {
10543                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10544            }
10545            if (info.broadcastIntentAction != null) {
10546                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10547            }
10548            if (info.durationMillis != -1) {
10549                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10550            }
10551            if (info.numInstances != -1) {
10552                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10553            }
10554            if (info.tags != null) {
10555                for (String tag : info.tags) {
10556                    sb.append("Span-Tag: ").append(tag).append("\n");
10557                }
10558            }
10559            sb.append("\n");
10560            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10561                sb.append(info.crashInfo.stackTrace);
10562            }
10563            sb.append("\n");
10564
10565            // Only buffer up to ~64k.  Various logging bits truncate
10566            // things at 128k.
10567            needsFlush = (sb.length() > 64 * 1024);
10568        }
10569
10570        // Flush immediately if the buffer's grown too large, or this
10571        // is a non-system app.  Non-system apps are isolated with a
10572        // different tag & policy and not batched.
10573        //
10574        // Batching is useful during internal testing with
10575        // StrictMode settings turned up high.  Without batching,
10576        // thousands of separate files could be created on boot.
10577        if (!isSystemApp || needsFlush) {
10578            new Thread("Error dump: " + dropboxTag) {
10579                @Override
10580                public void run() {
10581                    String report;
10582                    synchronized (sb) {
10583                        report = sb.toString();
10584                        sb.delete(0, sb.length());
10585                        sb.trimToSize();
10586                    }
10587                    if (report.length() != 0) {
10588                        dbox.addText(dropboxTag, report);
10589                    }
10590                }
10591            }.start();
10592            return;
10593        }
10594
10595        // System app batching:
10596        if (!bufferWasEmpty) {
10597            // An existing dropbox-writing thread is outstanding, so
10598            // we don't need to start it up.  The existing thread will
10599            // catch the buffer appends we just did.
10600            return;
10601        }
10602
10603        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10604        // (After this point, we shouldn't access AMS internal data structures.)
10605        new Thread("Error dump: " + dropboxTag) {
10606            @Override
10607            public void run() {
10608                // 5 second sleep to let stacks arrive and be batched together
10609                try {
10610                    Thread.sleep(5000);  // 5 seconds
10611                } catch (InterruptedException e) {}
10612
10613                String errorReport;
10614                synchronized (mStrictModeBuffer) {
10615                    errorReport = mStrictModeBuffer.toString();
10616                    if (errorReport.length() == 0) {
10617                        return;
10618                    }
10619                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10620                    mStrictModeBuffer.trimToSize();
10621                }
10622                dbox.addText(dropboxTag, errorReport);
10623            }
10624        }.start();
10625    }
10626
10627    /**
10628     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10629     * @param app object of the crashing app, null for the system server
10630     * @param tag reported by the caller
10631     * @param crashInfo describing the context of the error
10632     * @return true if the process should exit immediately (WTF is fatal)
10633     */
10634    public boolean handleApplicationWtf(IBinder app, String tag,
10635            ApplicationErrorReport.CrashInfo crashInfo) {
10636        ProcessRecord r = findAppProcess(app, "WTF");
10637        final String processName = app == null ? "system_server"
10638                : (r == null ? "unknown" : r.processName);
10639
10640        EventLog.writeEvent(EventLogTags.AM_WTF,
10641                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10642                processName,
10643                r == null ? -1 : r.info.flags,
10644                tag, crashInfo.exceptionMessage);
10645
10646        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10647
10648        if (r != null && r.pid != Process.myPid() &&
10649                Settings.Global.getInt(mContext.getContentResolver(),
10650                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10651            crashApplication(r, crashInfo);
10652            return true;
10653        } else {
10654            return false;
10655        }
10656    }
10657
10658    /**
10659     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10660     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10661     */
10662    private ProcessRecord findAppProcess(IBinder app, String reason) {
10663        if (app == null) {
10664            return null;
10665        }
10666
10667        synchronized (this) {
10668            final int NP = mProcessNames.getMap().size();
10669            for (int ip=0; ip<NP; ip++) {
10670                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10671                final int NA = apps.size();
10672                for (int ia=0; ia<NA; ia++) {
10673                    ProcessRecord p = apps.valueAt(ia);
10674                    if (p.thread != null && p.thread.asBinder() == app) {
10675                        return p;
10676                    }
10677                }
10678            }
10679
10680            Slog.w(TAG, "Can't find mystery application for " + reason
10681                    + " from pid=" + Binder.getCallingPid()
10682                    + " uid=" + Binder.getCallingUid() + ": " + app);
10683            return null;
10684        }
10685    }
10686
10687    /**
10688     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10689     * to append various headers to the dropbox log text.
10690     */
10691    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10692            StringBuilder sb) {
10693        // Watchdog thread ends up invoking this function (with
10694        // a null ProcessRecord) to add the stack file to dropbox.
10695        // Do not acquire a lock on this (am) in such cases, as it
10696        // could cause a potential deadlock, if and when watchdog
10697        // is invoked due to unavailability of lock on am and it
10698        // would prevent watchdog from killing system_server.
10699        if (process == null) {
10700            sb.append("Process: ").append(processName).append("\n");
10701            return;
10702        }
10703        // Note: ProcessRecord 'process' is guarded by the service
10704        // instance.  (notably process.pkgList, which could otherwise change
10705        // concurrently during execution of this method)
10706        synchronized (this) {
10707            sb.append("Process: ").append(processName).append("\n");
10708            int flags = process.info.flags;
10709            IPackageManager pm = AppGlobals.getPackageManager();
10710            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10711            for (int ip=0; ip<process.pkgList.size(); ip++) {
10712                String pkg = process.pkgList.keyAt(ip);
10713                sb.append("Package: ").append(pkg);
10714                try {
10715                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10716                    if (pi != null) {
10717                        sb.append(" v").append(pi.versionCode);
10718                        if (pi.versionName != null) {
10719                            sb.append(" (").append(pi.versionName).append(")");
10720                        }
10721                    }
10722                } catch (RemoteException e) {
10723                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10724                }
10725                sb.append("\n");
10726            }
10727        }
10728    }
10729
10730    private static String processClass(ProcessRecord process) {
10731        if (process == null || process.pid == MY_PID) {
10732            return "system_server";
10733        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10734            return "system_app";
10735        } else {
10736            return "data_app";
10737        }
10738    }
10739
10740    /**
10741     * Write a description of an error (crash, WTF, ANR) to the drop box.
10742     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10743     * @param process which caused the error, null means the system server
10744     * @param activity which triggered the error, null if unknown
10745     * @param parent activity related to the error, null if unknown
10746     * @param subject line related to the error, null if absent
10747     * @param report in long form describing the error, null if absent
10748     * @param logFile to include in the report, null if none
10749     * @param crashInfo giving an application stack trace, null if absent
10750     */
10751    public void addErrorToDropBox(String eventType,
10752            ProcessRecord process, String processName, ActivityRecord activity,
10753            ActivityRecord parent, String subject,
10754            final String report, final File logFile,
10755            final ApplicationErrorReport.CrashInfo crashInfo) {
10756        // NOTE -- this must never acquire the ActivityManagerService lock,
10757        // otherwise the watchdog may be prevented from resetting the system.
10758
10759        final String dropboxTag = processClass(process) + "_" + eventType;
10760        final DropBoxManager dbox = (DropBoxManager)
10761                mContext.getSystemService(Context.DROPBOX_SERVICE);
10762
10763        // Exit early if the dropbox isn't configured to accept this report type.
10764        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10765
10766        final StringBuilder sb = new StringBuilder(1024);
10767        appendDropBoxProcessHeaders(process, processName, sb);
10768        if (activity != null) {
10769            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10770        }
10771        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10772            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10773        }
10774        if (parent != null && parent != activity) {
10775            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10776        }
10777        if (subject != null) {
10778            sb.append("Subject: ").append(subject).append("\n");
10779        }
10780        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10781        if (Debug.isDebuggerConnected()) {
10782            sb.append("Debugger: Connected\n");
10783        }
10784        sb.append("\n");
10785
10786        // Do the rest in a worker thread to avoid blocking the caller on I/O
10787        // (After this point, we shouldn't access AMS internal data structures.)
10788        Thread worker = new Thread("Error dump: " + dropboxTag) {
10789            @Override
10790            public void run() {
10791                if (report != null) {
10792                    sb.append(report);
10793                }
10794                if (logFile != null) {
10795                    try {
10796                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10797                                    "\n\n[[TRUNCATED]]"));
10798                    } catch (IOException e) {
10799                        Slog.e(TAG, "Error reading " + logFile, e);
10800                    }
10801                }
10802                if (crashInfo != null && crashInfo.stackTrace != null) {
10803                    sb.append(crashInfo.stackTrace);
10804                }
10805
10806                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10807                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10808                if (lines > 0) {
10809                    sb.append("\n");
10810
10811                    // Merge several logcat streams, and take the last N lines
10812                    InputStreamReader input = null;
10813                    try {
10814                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10815                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10816                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10817
10818                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10819                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10820                        input = new InputStreamReader(logcat.getInputStream());
10821
10822                        int num;
10823                        char[] buf = new char[8192];
10824                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10825                    } catch (IOException e) {
10826                        Slog.e(TAG, "Error running logcat", e);
10827                    } finally {
10828                        if (input != null) try { input.close(); } catch (IOException e) {}
10829                    }
10830                }
10831
10832                dbox.addText(dropboxTag, sb.toString());
10833            }
10834        };
10835
10836        if (process == null) {
10837            // If process is null, we are being called from some internal code
10838            // and may be about to die -- run this synchronously.
10839            worker.run();
10840        } else {
10841            worker.start();
10842        }
10843    }
10844
10845    /**
10846     * Bring up the "unexpected error" dialog box for a crashing app.
10847     * Deal with edge cases (intercepts from instrumented applications,
10848     * ActivityController, error intent receivers, that sort of thing).
10849     * @param r the application crashing
10850     * @param crashInfo describing the failure
10851     */
10852    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10853        long timeMillis = System.currentTimeMillis();
10854        String shortMsg = crashInfo.exceptionClassName;
10855        String longMsg = crashInfo.exceptionMessage;
10856        String stackTrace = crashInfo.stackTrace;
10857        if (shortMsg != null && longMsg != null) {
10858            longMsg = shortMsg + ": " + longMsg;
10859        } else if (shortMsg != null) {
10860            longMsg = shortMsg;
10861        }
10862
10863        AppErrorResult result = new AppErrorResult();
10864        synchronized (this) {
10865            if (mController != null) {
10866                try {
10867                    String name = r != null ? r.processName : null;
10868                    int pid = r != null ? r.pid : Binder.getCallingPid();
10869                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10870                    if (!mController.appCrashed(name, pid,
10871                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10872                        Slog.w(TAG, "Force-killing crashed app " + name
10873                                + " at watcher's request");
10874                        Process.killProcess(pid);
10875                        if (r != null) {
10876                            Process.killProcessGroup(uid, pid);
10877                        }
10878                        return;
10879                    }
10880                } catch (RemoteException e) {
10881                    mController = null;
10882                    Watchdog.getInstance().setActivityController(null);
10883                }
10884            }
10885
10886            final long origId = Binder.clearCallingIdentity();
10887
10888            // If this process is running instrumentation, finish it.
10889            if (r != null && r.instrumentationClass != null) {
10890                Slog.w(TAG, "Error in app " + r.processName
10891                      + " running instrumentation " + r.instrumentationClass + ":");
10892                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10893                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10894                Bundle info = new Bundle();
10895                info.putString("shortMsg", shortMsg);
10896                info.putString("longMsg", longMsg);
10897                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10898                Binder.restoreCallingIdentity(origId);
10899                return;
10900            }
10901
10902            // If we can't identify the process or it's already exceeded its crash quota,
10903            // quit right away without showing a crash dialog.
10904            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10905                Binder.restoreCallingIdentity(origId);
10906                return;
10907            }
10908
10909            Message msg = Message.obtain();
10910            msg.what = SHOW_ERROR_MSG;
10911            HashMap data = new HashMap();
10912            data.put("result", result);
10913            data.put("app", r);
10914            msg.obj = data;
10915            mHandler.sendMessage(msg);
10916
10917            Binder.restoreCallingIdentity(origId);
10918        }
10919
10920        int res = result.get();
10921
10922        Intent appErrorIntent = null;
10923        synchronized (this) {
10924            if (r != null && !r.isolated) {
10925                // XXX Can't keep track of crash time for isolated processes,
10926                // since they don't have a persistent identity.
10927                mProcessCrashTimes.put(r.info.processName, r.uid,
10928                        SystemClock.uptimeMillis());
10929            }
10930            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10931                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10932            }
10933        }
10934
10935        if (appErrorIntent != null) {
10936            try {
10937                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10938            } catch (ActivityNotFoundException e) {
10939                Slog.w(TAG, "bug report receiver dissappeared", e);
10940            }
10941        }
10942    }
10943
10944    Intent createAppErrorIntentLocked(ProcessRecord r,
10945            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10946        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10947        if (report == null) {
10948            return null;
10949        }
10950        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10951        result.setComponent(r.errorReportReceiver);
10952        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10953        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10954        return result;
10955    }
10956
10957    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10958            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10959        if (r.errorReportReceiver == null) {
10960            return null;
10961        }
10962
10963        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10964            return null;
10965        }
10966
10967        ApplicationErrorReport report = new ApplicationErrorReport();
10968        report.packageName = r.info.packageName;
10969        report.installerPackageName = r.errorReportReceiver.getPackageName();
10970        report.processName = r.processName;
10971        report.time = timeMillis;
10972        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10973
10974        if (r.crashing || r.forceCrashReport) {
10975            report.type = ApplicationErrorReport.TYPE_CRASH;
10976            report.crashInfo = crashInfo;
10977        } else if (r.notResponding) {
10978            report.type = ApplicationErrorReport.TYPE_ANR;
10979            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10980
10981            report.anrInfo.activity = r.notRespondingReport.tag;
10982            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10983            report.anrInfo.info = r.notRespondingReport.longMsg;
10984        }
10985
10986        return report;
10987    }
10988
10989    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10990        enforceNotIsolatedCaller("getProcessesInErrorState");
10991        // assume our apps are happy - lazy create the list
10992        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10993
10994        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10995                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10996        int userId = UserHandle.getUserId(Binder.getCallingUid());
10997
10998        synchronized (this) {
10999
11000            // iterate across all processes
11001            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11002                ProcessRecord app = mLruProcesses.get(i);
11003                if (!allUsers && app.userId != userId) {
11004                    continue;
11005                }
11006                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11007                    // This one's in trouble, so we'll generate a report for it
11008                    // crashes are higher priority (in case there's a crash *and* an anr)
11009                    ActivityManager.ProcessErrorStateInfo report = null;
11010                    if (app.crashing) {
11011                        report = app.crashingReport;
11012                    } else if (app.notResponding) {
11013                        report = app.notRespondingReport;
11014                    }
11015
11016                    if (report != null) {
11017                        if (errList == null) {
11018                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11019                        }
11020                        errList.add(report);
11021                    } else {
11022                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11023                                " crashing = " + app.crashing +
11024                                " notResponding = " + app.notResponding);
11025                    }
11026                }
11027            }
11028        }
11029
11030        return errList;
11031    }
11032
11033    static int procStateToImportance(int procState, int memAdj,
11034            ActivityManager.RunningAppProcessInfo currApp) {
11035        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11036        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11037            currApp.lru = memAdj;
11038        } else {
11039            currApp.lru = 0;
11040        }
11041        return imp;
11042    }
11043
11044    private void fillInProcMemInfo(ProcessRecord app,
11045            ActivityManager.RunningAppProcessInfo outInfo) {
11046        outInfo.pid = app.pid;
11047        outInfo.uid = app.info.uid;
11048        if (mHeavyWeightProcess == app) {
11049            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11050        }
11051        if (app.persistent) {
11052            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11053        }
11054        if (app.activities.size() > 0) {
11055            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11056        }
11057        outInfo.lastTrimLevel = app.trimMemoryLevel;
11058        int adj = app.curAdj;
11059        int procState = app.curProcState;
11060        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11061        outInfo.importanceReasonCode = app.adjTypeCode;
11062        outInfo.processState = app.curProcState;
11063    }
11064
11065    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11066        enforceNotIsolatedCaller("getRunningAppProcesses");
11067        // Lazy instantiation of list
11068        List<ActivityManager.RunningAppProcessInfo> runList = null;
11069        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11070                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11071        int userId = UserHandle.getUserId(Binder.getCallingUid());
11072        synchronized (this) {
11073            // Iterate across all processes
11074            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11075                ProcessRecord app = mLruProcesses.get(i);
11076                if (!allUsers && app.userId != userId) {
11077                    continue;
11078                }
11079                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11080                    // Generate process state info for running application
11081                    ActivityManager.RunningAppProcessInfo currApp =
11082                        new ActivityManager.RunningAppProcessInfo(app.processName,
11083                                app.pid, app.getPackageList());
11084                    fillInProcMemInfo(app, currApp);
11085                    if (app.adjSource instanceof ProcessRecord) {
11086                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11087                        currApp.importanceReasonImportance =
11088                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11089                                        app.adjSourceProcState);
11090                    } else if (app.adjSource instanceof ActivityRecord) {
11091                        ActivityRecord r = (ActivityRecord)app.adjSource;
11092                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11093                    }
11094                    if (app.adjTarget instanceof ComponentName) {
11095                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11096                    }
11097                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11098                    //        + " lru=" + currApp.lru);
11099                    if (runList == null) {
11100                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11101                    }
11102                    runList.add(currApp);
11103                }
11104            }
11105        }
11106        return runList;
11107    }
11108
11109    public List<ApplicationInfo> getRunningExternalApplications() {
11110        enforceNotIsolatedCaller("getRunningExternalApplications");
11111        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11112        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11113        if (runningApps != null && runningApps.size() > 0) {
11114            Set<String> extList = new HashSet<String>();
11115            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11116                if (app.pkgList != null) {
11117                    for (String pkg : app.pkgList) {
11118                        extList.add(pkg);
11119                    }
11120                }
11121            }
11122            IPackageManager pm = AppGlobals.getPackageManager();
11123            for (String pkg : extList) {
11124                try {
11125                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11126                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11127                        retList.add(info);
11128                    }
11129                } catch (RemoteException e) {
11130                }
11131            }
11132        }
11133        return retList;
11134    }
11135
11136    @Override
11137    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11138        enforceNotIsolatedCaller("getMyMemoryState");
11139        synchronized (this) {
11140            ProcessRecord proc;
11141            synchronized (mPidsSelfLocked) {
11142                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11143            }
11144            fillInProcMemInfo(proc, outInfo);
11145        }
11146    }
11147
11148    @Override
11149    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11150        if (checkCallingPermission(android.Manifest.permission.DUMP)
11151                != PackageManager.PERMISSION_GRANTED) {
11152            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11153                    + Binder.getCallingPid()
11154                    + ", uid=" + Binder.getCallingUid()
11155                    + " without permission "
11156                    + android.Manifest.permission.DUMP);
11157            return;
11158        }
11159
11160        boolean dumpAll = false;
11161        boolean dumpClient = false;
11162        String dumpPackage = null;
11163
11164        int opti = 0;
11165        while (opti < args.length) {
11166            String opt = args[opti];
11167            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11168                break;
11169            }
11170            opti++;
11171            if ("-a".equals(opt)) {
11172                dumpAll = true;
11173            } else if ("-c".equals(opt)) {
11174                dumpClient = true;
11175            } else if ("-h".equals(opt)) {
11176                pw.println("Activity manager dump options:");
11177                pw.println("  [-a] [-c] [-h] [cmd] ...");
11178                pw.println("  cmd may be one of:");
11179                pw.println("    a[ctivities]: activity stack state");
11180                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11181                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11182                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11183                pw.println("    o[om]: out of memory management");
11184                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11185                pw.println("    provider [COMP_SPEC]: provider client-side state");
11186                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11187                pw.println("    service [COMP_SPEC]: service client-side state");
11188                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11189                pw.println("    all: dump all activities");
11190                pw.println("    top: dump the top activity");
11191                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11192                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11193                pw.println("    a partial substring in a component name, a");
11194                pw.println("    hex object identifier.");
11195                pw.println("  -a: include all available server state.");
11196                pw.println("  -c: include client state.");
11197                return;
11198            } else {
11199                pw.println("Unknown argument: " + opt + "; use -h for help");
11200            }
11201        }
11202
11203        long origId = Binder.clearCallingIdentity();
11204        boolean more = false;
11205        // Is the caller requesting to dump a particular piece of data?
11206        if (opti < args.length) {
11207            String cmd = args[opti];
11208            opti++;
11209            if ("activities".equals(cmd) || "a".equals(cmd)) {
11210                synchronized (this) {
11211                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11212                }
11213            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11214                String[] newArgs;
11215                String name;
11216                if (opti >= args.length) {
11217                    name = null;
11218                    newArgs = EMPTY_STRING_ARRAY;
11219                } else {
11220                    name = args[opti];
11221                    opti++;
11222                    newArgs = new String[args.length - opti];
11223                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11224                            args.length - opti);
11225                }
11226                synchronized (this) {
11227                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11228                }
11229            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11230                String[] newArgs;
11231                String name;
11232                if (opti >= args.length) {
11233                    name = null;
11234                    newArgs = EMPTY_STRING_ARRAY;
11235                } else {
11236                    name = args[opti];
11237                    opti++;
11238                    newArgs = new String[args.length - opti];
11239                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11240                            args.length - opti);
11241                }
11242                synchronized (this) {
11243                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11244                }
11245            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11246                String[] newArgs;
11247                String name;
11248                if (opti >= args.length) {
11249                    name = null;
11250                    newArgs = EMPTY_STRING_ARRAY;
11251                } else {
11252                    name = args[opti];
11253                    opti++;
11254                    newArgs = new String[args.length - opti];
11255                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11256                            args.length - opti);
11257                }
11258                synchronized (this) {
11259                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11260                }
11261            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11262                synchronized (this) {
11263                    dumpOomLocked(fd, pw, args, opti, true);
11264                }
11265            } else if ("provider".equals(cmd)) {
11266                String[] newArgs;
11267                String name;
11268                if (opti >= args.length) {
11269                    name = null;
11270                    newArgs = EMPTY_STRING_ARRAY;
11271                } else {
11272                    name = args[opti];
11273                    opti++;
11274                    newArgs = new String[args.length - opti];
11275                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11276                }
11277                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11278                    pw.println("No providers match: " + name);
11279                    pw.println("Use -h for help.");
11280                }
11281            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11282                synchronized (this) {
11283                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11284                }
11285            } else if ("service".equals(cmd)) {
11286                String[] newArgs;
11287                String name;
11288                if (opti >= args.length) {
11289                    name = null;
11290                    newArgs = EMPTY_STRING_ARRAY;
11291                } else {
11292                    name = args[opti];
11293                    opti++;
11294                    newArgs = new String[args.length - opti];
11295                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11296                            args.length - opti);
11297                }
11298                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11299                    pw.println("No services match: " + name);
11300                    pw.println("Use -h for help.");
11301                }
11302            } else if ("package".equals(cmd)) {
11303                String[] newArgs;
11304                if (opti >= args.length) {
11305                    pw.println("package: no package name specified");
11306                    pw.println("Use -h for help.");
11307                } else {
11308                    dumpPackage = args[opti];
11309                    opti++;
11310                    newArgs = new String[args.length - opti];
11311                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11312                            args.length - opti);
11313                    args = newArgs;
11314                    opti = 0;
11315                    more = true;
11316                }
11317            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11318                synchronized (this) {
11319                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11320                }
11321            } else {
11322                // Dumping a single activity?
11323                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11324                    pw.println("Bad activity command, or no activities match: " + cmd);
11325                    pw.println("Use -h for help.");
11326                }
11327            }
11328            if (!more) {
11329                Binder.restoreCallingIdentity(origId);
11330                return;
11331            }
11332        }
11333
11334        // No piece of data specified, dump everything.
11335        synchronized (this) {
11336            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11337            pw.println();
11338            if (dumpAll) {
11339                pw.println("-------------------------------------------------------------------------------");
11340            }
11341            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11342            pw.println();
11343            if (dumpAll) {
11344                pw.println("-------------------------------------------------------------------------------");
11345            }
11346            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11347            pw.println();
11348            if (dumpAll) {
11349                pw.println("-------------------------------------------------------------------------------");
11350            }
11351            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11352            pw.println();
11353            if (dumpAll) {
11354                pw.println("-------------------------------------------------------------------------------");
11355            }
11356            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11357            pw.println();
11358            if (dumpAll) {
11359                pw.println("-------------------------------------------------------------------------------");
11360            }
11361            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11362        }
11363        Binder.restoreCallingIdentity(origId);
11364    }
11365
11366    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11367            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11368        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11369
11370        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11371                dumpPackage);
11372        boolean needSep = printedAnything;
11373
11374        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11375                dumpPackage, needSep, "  mFocusedActivity: ");
11376        if (printed) {
11377            printedAnything = true;
11378            needSep = false;
11379        }
11380
11381        if (dumpPackage == null) {
11382            if (needSep) {
11383                pw.println();
11384            }
11385            needSep = true;
11386            printedAnything = true;
11387            mStackSupervisor.dump(pw, "  ");
11388        }
11389
11390        if (mRecentTasks.size() > 0) {
11391            boolean printedHeader = false;
11392
11393            final int N = mRecentTasks.size();
11394            for (int i=0; i<N; i++) {
11395                TaskRecord tr = mRecentTasks.get(i);
11396                if (dumpPackage != null) {
11397                    if (tr.realActivity == null ||
11398                            !dumpPackage.equals(tr.realActivity)) {
11399                        continue;
11400                    }
11401                }
11402                if (!printedHeader) {
11403                    if (needSep) {
11404                        pw.println();
11405                    }
11406                    pw.println("  Recent tasks:");
11407                    printedHeader = true;
11408                    printedAnything = true;
11409                }
11410                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11411                        pw.println(tr);
11412                if (dumpAll) {
11413                    mRecentTasks.get(i).dump(pw, "    ");
11414                }
11415            }
11416        }
11417
11418        if (!printedAnything) {
11419            pw.println("  (nothing)");
11420        }
11421    }
11422
11423    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11424            int opti, boolean dumpAll, String dumpPackage) {
11425        boolean needSep = false;
11426        boolean printedAnything = false;
11427        int numPers = 0;
11428
11429        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11430
11431        if (dumpAll) {
11432            final int NP = mProcessNames.getMap().size();
11433            for (int ip=0; ip<NP; ip++) {
11434                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11435                final int NA = procs.size();
11436                for (int ia=0; ia<NA; ia++) {
11437                    ProcessRecord r = procs.valueAt(ia);
11438                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11439                        continue;
11440                    }
11441                    if (!needSep) {
11442                        pw.println("  All known processes:");
11443                        needSep = true;
11444                        printedAnything = true;
11445                    }
11446                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11447                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11448                        pw.print(" "); pw.println(r);
11449                    r.dump(pw, "    ");
11450                    if (r.persistent) {
11451                        numPers++;
11452                    }
11453                }
11454            }
11455        }
11456
11457        if (mIsolatedProcesses.size() > 0) {
11458            boolean printed = false;
11459            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11460                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11461                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11462                    continue;
11463                }
11464                if (!printed) {
11465                    if (needSep) {
11466                        pw.println();
11467                    }
11468                    pw.println("  Isolated process list (sorted by uid):");
11469                    printedAnything = true;
11470                    printed = true;
11471                    needSep = true;
11472                }
11473                pw.println(String.format("%sIsolated #%2d: %s",
11474                        "    ", i, r.toString()));
11475            }
11476        }
11477
11478        if (mLruProcesses.size() > 0) {
11479            if (needSep) {
11480                pw.println();
11481            }
11482            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11483                    pw.print(" total, non-act at ");
11484                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11485                    pw.print(", non-svc at ");
11486                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11487                    pw.println("):");
11488            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11489            needSep = true;
11490            printedAnything = true;
11491        }
11492
11493        if (dumpAll || dumpPackage != null) {
11494            synchronized (mPidsSelfLocked) {
11495                boolean printed = false;
11496                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11497                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11498                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11499                        continue;
11500                    }
11501                    if (!printed) {
11502                        if (needSep) pw.println();
11503                        needSep = true;
11504                        pw.println("  PID mappings:");
11505                        printed = true;
11506                        printedAnything = true;
11507                    }
11508                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11509                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11510                }
11511            }
11512        }
11513
11514        if (mForegroundProcesses.size() > 0) {
11515            synchronized (mPidsSelfLocked) {
11516                boolean printed = false;
11517                for (int i=0; i<mForegroundProcesses.size(); i++) {
11518                    ProcessRecord r = mPidsSelfLocked.get(
11519                            mForegroundProcesses.valueAt(i).pid);
11520                    if (dumpPackage != null && (r == null
11521                            || !r.pkgList.containsKey(dumpPackage))) {
11522                        continue;
11523                    }
11524                    if (!printed) {
11525                        if (needSep) pw.println();
11526                        needSep = true;
11527                        pw.println("  Foreground Processes:");
11528                        printed = true;
11529                        printedAnything = true;
11530                    }
11531                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11532                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11533                }
11534            }
11535        }
11536
11537        if (mPersistentStartingProcesses.size() > 0) {
11538            if (needSep) pw.println();
11539            needSep = true;
11540            printedAnything = true;
11541            pw.println("  Persisent processes that are starting:");
11542            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11543                    "Starting Norm", "Restarting PERS", dumpPackage);
11544        }
11545
11546        if (mRemovedProcesses.size() > 0) {
11547            if (needSep) pw.println();
11548            needSep = true;
11549            printedAnything = true;
11550            pw.println("  Processes that are being removed:");
11551            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11552                    "Removed Norm", "Removed PERS", dumpPackage);
11553        }
11554
11555        if (mProcessesOnHold.size() > 0) {
11556            if (needSep) pw.println();
11557            needSep = true;
11558            printedAnything = true;
11559            pw.println("  Processes that are on old until the system is ready:");
11560            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11561                    "OnHold Norm", "OnHold PERS", dumpPackage);
11562        }
11563
11564        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11565
11566        if (mProcessCrashTimes.getMap().size() > 0) {
11567            boolean printed = false;
11568            long now = SystemClock.uptimeMillis();
11569            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11570            final int NP = pmap.size();
11571            for (int ip=0; ip<NP; ip++) {
11572                String pname = pmap.keyAt(ip);
11573                SparseArray<Long> uids = pmap.valueAt(ip);
11574                final int N = uids.size();
11575                for (int i=0; i<N; i++) {
11576                    int puid = uids.keyAt(i);
11577                    ProcessRecord r = mProcessNames.get(pname, puid);
11578                    if (dumpPackage != null && (r == null
11579                            || !r.pkgList.containsKey(dumpPackage))) {
11580                        continue;
11581                    }
11582                    if (!printed) {
11583                        if (needSep) pw.println();
11584                        needSep = true;
11585                        pw.println("  Time since processes crashed:");
11586                        printed = true;
11587                        printedAnything = true;
11588                    }
11589                    pw.print("    Process "); pw.print(pname);
11590                            pw.print(" uid "); pw.print(puid);
11591                            pw.print(": last crashed ");
11592                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11593                            pw.println(" ago");
11594                }
11595            }
11596        }
11597
11598        if (mBadProcesses.getMap().size() > 0) {
11599            boolean printed = false;
11600            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11601            final int NP = pmap.size();
11602            for (int ip=0; ip<NP; ip++) {
11603                String pname = pmap.keyAt(ip);
11604                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11605                final int N = uids.size();
11606                for (int i=0; i<N; i++) {
11607                    int puid = uids.keyAt(i);
11608                    ProcessRecord r = mProcessNames.get(pname, puid);
11609                    if (dumpPackage != null && (r == null
11610                            || !r.pkgList.containsKey(dumpPackage))) {
11611                        continue;
11612                    }
11613                    if (!printed) {
11614                        if (needSep) pw.println();
11615                        needSep = true;
11616                        pw.println("  Bad processes:");
11617                        printedAnything = true;
11618                    }
11619                    BadProcessInfo info = uids.valueAt(i);
11620                    pw.print("    Bad process "); pw.print(pname);
11621                            pw.print(" uid "); pw.print(puid);
11622                            pw.print(": crashed at time "); pw.println(info.time);
11623                    if (info.shortMsg != null) {
11624                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11625                    }
11626                    if (info.longMsg != null) {
11627                        pw.print("      Long msg: "); pw.println(info.longMsg);
11628                    }
11629                    if (info.stack != null) {
11630                        pw.println("      Stack:");
11631                        int lastPos = 0;
11632                        for (int pos=0; pos<info.stack.length(); pos++) {
11633                            if (info.stack.charAt(pos) == '\n') {
11634                                pw.print("        ");
11635                                pw.write(info.stack, lastPos, pos-lastPos);
11636                                pw.println();
11637                                lastPos = pos+1;
11638                            }
11639                        }
11640                        if (lastPos < info.stack.length()) {
11641                            pw.print("        ");
11642                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11643                            pw.println();
11644                        }
11645                    }
11646                }
11647            }
11648        }
11649
11650        if (dumpPackage == null) {
11651            pw.println();
11652            needSep = false;
11653            pw.println("  mStartedUsers:");
11654            for (int i=0; i<mStartedUsers.size(); i++) {
11655                UserStartedState uss = mStartedUsers.valueAt(i);
11656                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11657                        pw.print(": "); uss.dump("", pw);
11658            }
11659            pw.print("  mStartedUserArray: [");
11660            for (int i=0; i<mStartedUserArray.length; i++) {
11661                if (i > 0) pw.print(", ");
11662                pw.print(mStartedUserArray[i]);
11663            }
11664            pw.println("]");
11665            pw.print("  mUserLru: [");
11666            for (int i=0; i<mUserLru.size(); i++) {
11667                if (i > 0) pw.print(", ");
11668                pw.print(mUserLru.get(i));
11669            }
11670            pw.println("]");
11671            if (dumpAll) {
11672                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11673            }
11674            synchronized (mUserProfileGroupIdsSelfLocked) {
11675                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11676                    pw.println("  mUserProfileGroupIds:");
11677                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11678                        pw.print("    User #");
11679                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11680                        pw.print(" -> profile #");
11681                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11682                    }
11683                }
11684            }
11685        }
11686        if (mHomeProcess != null && (dumpPackage == null
11687                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11688            if (needSep) {
11689                pw.println();
11690                needSep = false;
11691            }
11692            pw.println("  mHomeProcess: " + mHomeProcess);
11693        }
11694        if (mPreviousProcess != null && (dumpPackage == null
11695                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11696            if (needSep) {
11697                pw.println();
11698                needSep = false;
11699            }
11700            pw.println("  mPreviousProcess: " + mPreviousProcess);
11701        }
11702        if (dumpAll) {
11703            StringBuilder sb = new StringBuilder(128);
11704            sb.append("  mPreviousProcessVisibleTime: ");
11705            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11706            pw.println(sb);
11707        }
11708        if (mHeavyWeightProcess != null && (dumpPackage == null
11709                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11710            if (needSep) {
11711                pw.println();
11712                needSep = false;
11713            }
11714            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11715        }
11716        if (dumpPackage == null) {
11717            pw.println("  mConfiguration: " + mConfiguration);
11718        }
11719        if (dumpAll) {
11720            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11721            if (mCompatModePackages.getPackages().size() > 0) {
11722                boolean printed = false;
11723                for (Map.Entry<String, Integer> entry
11724                        : mCompatModePackages.getPackages().entrySet()) {
11725                    String pkg = entry.getKey();
11726                    int mode = entry.getValue();
11727                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11728                        continue;
11729                    }
11730                    if (!printed) {
11731                        pw.println("  mScreenCompatPackages:");
11732                        printed = true;
11733                    }
11734                    pw.print("    "); pw.print(pkg); pw.print(": ");
11735                            pw.print(mode); pw.println();
11736                }
11737            }
11738        }
11739        if (dumpPackage == null) {
11740            if (mSleeping || mWentToSleep || mLockScreenShown) {
11741                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11742                        + " mLockScreenShown " + mLockScreenShown);
11743            }
11744            if (mShuttingDown || mRunningVoice) {
11745                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11746            }
11747        }
11748        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11749                || mOrigWaitForDebugger) {
11750            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11751                    || dumpPackage.equals(mOrigDebugApp)) {
11752                if (needSep) {
11753                    pw.println();
11754                    needSep = false;
11755                }
11756                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11757                        + " mDebugTransient=" + mDebugTransient
11758                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11759            }
11760        }
11761        if (mOpenGlTraceApp != null) {
11762            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11763                if (needSep) {
11764                    pw.println();
11765                    needSep = false;
11766                }
11767                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11768            }
11769        }
11770        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11771                || mProfileFd != null) {
11772            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11773                if (needSep) {
11774                    pw.println();
11775                    needSep = false;
11776                }
11777                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11778                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11779                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11780                        + mAutoStopProfiler);
11781            }
11782        }
11783        if (dumpPackage == null) {
11784            if (mAlwaysFinishActivities || mController != null) {
11785                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11786                        + " mController=" + mController);
11787            }
11788            if (dumpAll) {
11789                pw.println("  Total persistent processes: " + numPers);
11790                pw.println("  mProcessesReady=" + mProcessesReady
11791                        + " mSystemReady=" + mSystemReady);
11792                pw.println("  mBooting=" + mBooting
11793                        + " mBooted=" + mBooted
11794                        + " mFactoryTest=" + mFactoryTest);
11795                pw.print("  mLastPowerCheckRealtime=");
11796                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11797                        pw.println("");
11798                pw.print("  mLastPowerCheckUptime=");
11799                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11800                        pw.println("");
11801                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11802                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11803                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11804                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11805                        + " (" + mLruProcesses.size() + " total)"
11806                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11807                        + " mNumServiceProcs=" + mNumServiceProcs
11808                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11809                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11810                        + " mLastMemoryLevel" + mLastMemoryLevel
11811                        + " mLastNumProcesses" + mLastNumProcesses);
11812                long now = SystemClock.uptimeMillis();
11813                pw.print("  mLastIdleTime=");
11814                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11815                        pw.print(" mLowRamSinceLastIdle=");
11816                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11817                        pw.println();
11818            }
11819        }
11820
11821        if (!printedAnything) {
11822            pw.println("  (nothing)");
11823        }
11824    }
11825
11826    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11827            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11828        if (mProcessesToGc.size() > 0) {
11829            boolean printed = false;
11830            long now = SystemClock.uptimeMillis();
11831            for (int i=0; i<mProcessesToGc.size(); i++) {
11832                ProcessRecord proc = mProcessesToGc.get(i);
11833                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11834                    continue;
11835                }
11836                if (!printed) {
11837                    if (needSep) pw.println();
11838                    needSep = true;
11839                    pw.println("  Processes that are waiting to GC:");
11840                    printed = true;
11841                }
11842                pw.print("    Process "); pw.println(proc);
11843                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11844                        pw.print(", last gced=");
11845                        pw.print(now-proc.lastRequestedGc);
11846                        pw.print(" ms ago, last lowMem=");
11847                        pw.print(now-proc.lastLowMemory);
11848                        pw.println(" ms ago");
11849
11850            }
11851        }
11852        return needSep;
11853    }
11854
11855    void printOomLevel(PrintWriter pw, String name, int adj) {
11856        pw.print("    ");
11857        if (adj >= 0) {
11858            pw.print(' ');
11859            if (adj < 10) pw.print(' ');
11860        } else {
11861            if (adj > -10) pw.print(' ');
11862        }
11863        pw.print(adj);
11864        pw.print(": ");
11865        pw.print(name);
11866        pw.print(" (");
11867        pw.print(mProcessList.getMemLevel(adj)/1024);
11868        pw.println(" kB)");
11869    }
11870
11871    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11872            int opti, boolean dumpAll) {
11873        boolean needSep = false;
11874
11875        if (mLruProcesses.size() > 0) {
11876            if (needSep) pw.println();
11877            needSep = true;
11878            pw.println("  OOM levels:");
11879            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11880            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11881            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11882            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11883            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11884            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11885            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11886            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11887            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11888            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11889            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11890            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11891            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11892
11893            if (needSep) pw.println();
11894            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11895                    pw.print(" total, non-act at ");
11896                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11897                    pw.print(", non-svc at ");
11898                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11899                    pw.println("):");
11900            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11901            needSep = true;
11902        }
11903
11904        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11905
11906        pw.println();
11907        pw.println("  mHomeProcess: " + mHomeProcess);
11908        pw.println("  mPreviousProcess: " + mPreviousProcess);
11909        if (mHeavyWeightProcess != null) {
11910            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11911        }
11912
11913        return true;
11914    }
11915
11916    /**
11917     * There are three ways to call this:
11918     *  - no provider specified: dump all the providers
11919     *  - a flattened component name that matched an existing provider was specified as the
11920     *    first arg: dump that one provider
11921     *  - the first arg isn't the flattened component name of an existing provider:
11922     *    dump all providers whose component contains the first arg as a substring
11923     */
11924    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11925            int opti, boolean dumpAll) {
11926        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11927    }
11928
11929    static class ItemMatcher {
11930        ArrayList<ComponentName> components;
11931        ArrayList<String> strings;
11932        ArrayList<Integer> objects;
11933        boolean all;
11934
11935        ItemMatcher() {
11936            all = true;
11937        }
11938
11939        void build(String name) {
11940            ComponentName componentName = ComponentName.unflattenFromString(name);
11941            if (componentName != null) {
11942                if (components == null) {
11943                    components = new ArrayList<ComponentName>();
11944                }
11945                components.add(componentName);
11946                all = false;
11947            } else {
11948                int objectId = 0;
11949                // Not a '/' separated full component name; maybe an object ID?
11950                try {
11951                    objectId = Integer.parseInt(name, 16);
11952                    if (objects == null) {
11953                        objects = new ArrayList<Integer>();
11954                    }
11955                    objects.add(objectId);
11956                    all = false;
11957                } catch (RuntimeException e) {
11958                    // Not an integer; just do string match.
11959                    if (strings == null) {
11960                        strings = new ArrayList<String>();
11961                    }
11962                    strings.add(name);
11963                    all = false;
11964                }
11965            }
11966        }
11967
11968        int build(String[] args, int opti) {
11969            for (; opti<args.length; opti++) {
11970                String name = args[opti];
11971                if ("--".equals(name)) {
11972                    return opti+1;
11973                }
11974                build(name);
11975            }
11976            return opti;
11977        }
11978
11979        boolean match(Object object, ComponentName comp) {
11980            if (all) {
11981                return true;
11982            }
11983            if (components != null) {
11984                for (int i=0; i<components.size(); i++) {
11985                    if (components.get(i).equals(comp)) {
11986                        return true;
11987                    }
11988                }
11989            }
11990            if (objects != null) {
11991                for (int i=0; i<objects.size(); i++) {
11992                    if (System.identityHashCode(object) == objects.get(i)) {
11993                        return true;
11994                    }
11995                }
11996            }
11997            if (strings != null) {
11998                String flat = comp.flattenToString();
11999                for (int i=0; i<strings.size(); i++) {
12000                    if (flat.contains(strings.get(i))) {
12001                        return true;
12002                    }
12003                }
12004            }
12005            return false;
12006        }
12007    }
12008
12009    /**
12010     * There are three things that cmd can be:
12011     *  - a flattened component name that matches an existing activity
12012     *  - the cmd arg isn't the flattened component name of an existing activity:
12013     *    dump all activity whose component contains the cmd as a substring
12014     *  - A hex number of the ActivityRecord object instance.
12015     */
12016    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12017            int opti, boolean dumpAll) {
12018        ArrayList<ActivityRecord> activities;
12019
12020        synchronized (this) {
12021            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12022        }
12023
12024        if (activities.size() <= 0) {
12025            return false;
12026        }
12027
12028        String[] newArgs = new String[args.length - opti];
12029        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12030
12031        TaskRecord lastTask = null;
12032        boolean needSep = false;
12033        for (int i=activities.size()-1; i>=0; i--) {
12034            ActivityRecord r = activities.get(i);
12035            if (needSep) {
12036                pw.println();
12037            }
12038            needSep = true;
12039            synchronized (this) {
12040                if (lastTask != r.task) {
12041                    lastTask = r.task;
12042                    pw.print("TASK "); pw.print(lastTask.affinity);
12043                            pw.print(" id="); pw.println(lastTask.taskId);
12044                    if (dumpAll) {
12045                        lastTask.dump(pw, "  ");
12046                    }
12047                }
12048            }
12049            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12050        }
12051        return true;
12052    }
12053
12054    /**
12055     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12056     * there is a thread associated with the activity.
12057     */
12058    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12059            final ActivityRecord r, String[] args, boolean dumpAll) {
12060        String innerPrefix = prefix + "  ";
12061        synchronized (this) {
12062            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12063                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12064                    pw.print(" pid=");
12065                    if (r.app != null) pw.println(r.app.pid);
12066                    else pw.println("(not running)");
12067            if (dumpAll) {
12068                r.dump(pw, innerPrefix);
12069            }
12070        }
12071        if (r.app != null && r.app.thread != null) {
12072            // flush anything that is already in the PrintWriter since the thread is going
12073            // to write to the file descriptor directly
12074            pw.flush();
12075            try {
12076                TransferPipe tp = new TransferPipe();
12077                try {
12078                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12079                            r.appToken, innerPrefix, args);
12080                    tp.go(fd);
12081                } finally {
12082                    tp.kill();
12083                }
12084            } catch (IOException e) {
12085                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12086            } catch (RemoteException e) {
12087                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12088            }
12089        }
12090    }
12091
12092    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12093            int opti, boolean dumpAll, String dumpPackage) {
12094        boolean needSep = false;
12095        boolean onlyHistory = false;
12096        boolean printedAnything = false;
12097
12098        if ("history".equals(dumpPackage)) {
12099            if (opti < args.length && "-s".equals(args[opti])) {
12100                dumpAll = false;
12101            }
12102            onlyHistory = true;
12103            dumpPackage = null;
12104        }
12105
12106        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12107        if (!onlyHistory && dumpAll) {
12108            if (mRegisteredReceivers.size() > 0) {
12109                boolean printed = false;
12110                Iterator it = mRegisteredReceivers.values().iterator();
12111                while (it.hasNext()) {
12112                    ReceiverList r = (ReceiverList)it.next();
12113                    if (dumpPackage != null && (r.app == null ||
12114                            !dumpPackage.equals(r.app.info.packageName))) {
12115                        continue;
12116                    }
12117                    if (!printed) {
12118                        pw.println("  Registered Receivers:");
12119                        needSep = true;
12120                        printed = true;
12121                        printedAnything = true;
12122                    }
12123                    pw.print("  * "); pw.println(r);
12124                    r.dump(pw, "    ");
12125                }
12126            }
12127
12128            if (mReceiverResolver.dump(pw, needSep ?
12129                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12130                    "    ", dumpPackage, false)) {
12131                needSep = true;
12132                printedAnything = true;
12133            }
12134        }
12135
12136        for (BroadcastQueue q : mBroadcastQueues) {
12137            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12138            printedAnything |= needSep;
12139        }
12140
12141        needSep = true;
12142
12143        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12144            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12145                if (needSep) {
12146                    pw.println();
12147                }
12148                needSep = true;
12149                printedAnything = true;
12150                pw.print("  Sticky broadcasts for user ");
12151                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12152                StringBuilder sb = new StringBuilder(128);
12153                for (Map.Entry<String, ArrayList<Intent>> ent
12154                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12155                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12156                    if (dumpAll) {
12157                        pw.println(":");
12158                        ArrayList<Intent> intents = ent.getValue();
12159                        final int N = intents.size();
12160                        for (int i=0; i<N; i++) {
12161                            sb.setLength(0);
12162                            sb.append("    Intent: ");
12163                            intents.get(i).toShortString(sb, false, true, false, false);
12164                            pw.println(sb.toString());
12165                            Bundle bundle = intents.get(i).getExtras();
12166                            if (bundle != null) {
12167                                pw.print("      ");
12168                                pw.println(bundle.toString());
12169                            }
12170                        }
12171                    } else {
12172                        pw.println("");
12173                    }
12174                }
12175            }
12176        }
12177
12178        if (!onlyHistory && dumpAll) {
12179            pw.println();
12180            for (BroadcastQueue queue : mBroadcastQueues) {
12181                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12182                        + queue.mBroadcastsScheduled);
12183            }
12184            pw.println("  mHandler:");
12185            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12186            needSep = true;
12187            printedAnything = true;
12188        }
12189
12190        if (!printedAnything) {
12191            pw.println("  (nothing)");
12192        }
12193    }
12194
12195    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12196            int opti, boolean dumpAll, String dumpPackage) {
12197        boolean needSep;
12198        boolean printedAnything = false;
12199
12200        ItemMatcher matcher = new ItemMatcher();
12201        matcher.build(args, opti);
12202
12203        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12204
12205        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12206        printedAnything |= needSep;
12207
12208        if (mLaunchingProviders.size() > 0) {
12209            boolean printed = false;
12210            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12211                ContentProviderRecord r = mLaunchingProviders.get(i);
12212                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12213                    continue;
12214                }
12215                if (!printed) {
12216                    if (needSep) pw.println();
12217                    needSep = true;
12218                    pw.println("  Launching content providers:");
12219                    printed = true;
12220                    printedAnything = true;
12221                }
12222                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12223                        pw.println(r);
12224            }
12225        }
12226
12227        if (mGrantedUriPermissions.size() > 0) {
12228            boolean printed = false;
12229            int dumpUid = -2;
12230            if (dumpPackage != null) {
12231                try {
12232                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12233                } catch (NameNotFoundException e) {
12234                    dumpUid = -1;
12235                }
12236            }
12237            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12238                int uid = mGrantedUriPermissions.keyAt(i);
12239                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12240                    continue;
12241                }
12242                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12243                if (!printed) {
12244                    if (needSep) pw.println();
12245                    needSep = true;
12246                    pw.println("  Granted Uri Permissions:");
12247                    printed = true;
12248                    printedAnything = true;
12249                }
12250                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12251                for (UriPermission perm : perms.values()) {
12252                    pw.print("    "); pw.println(perm);
12253                    if (dumpAll) {
12254                        perm.dump(pw, "      ");
12255                    }
12256                }
12257            }
12258        }
12259
12260        if (!printedAnything) {
12261            pw.println("  (nothing)");
12262        }
12263    }
12264
12265    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12266            int opti, boolean dumpAll, String dumpPackage) {
12267        boolean printed = false;
12268
12269        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12270
12271        if (mIntentSenderRecords.size() > 0) {
12272            Iterator<WeakReference<PendingIntentRecord>> it
12273                    = mIntentSenderRecords.values().iterator();
12274            while (it.hasNext()) {
12275                WeakReference<PendingIntentRecord> ref = it.next();
12276                PendingIntentRecord rec = ref != null ? ref.get(): null;
12277                if (dumpPackage != null && (rec == null
12278                        || !dumpPackage.equals(rec.key.packageName))) {
12279                    continue;
12280                }
12281                printed = true;
12282                if (rec != null) {
12283                    pw.print("  * "); pw.println(rec);
12284                    if (dumpAll) {
12285                        rec.dump(pw, "    ");
12286                    }
12287                } else {
12288                    pw.print("  * "); pw.println(ref);
12289                }
12290            }
12291        }
12292
12293        if (!printed) {
12294            pw.println("  (nothing)");
12295        }
12296    }
12297
12298    private static final int dumpProcessList(PrintWriter pw,
12299            ActivityManagerService service, List list,
12300            String prefix, String normalLabel, String persistentLabel,
12301            String dumpPackage) {
12302        int numPers = 0;
12303        final int N = list.size()-1;
12304        for (int i=N; i>=0; i--) {
12305            ProcessRecord r = (ProcessRecord)list.get(i);
12306            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12307                continue;
12308            }
12309            pw.println(String.format("%s%s #%2d: %s",
12310                    prefix, (r.persistent ? persistentLabel : normalLabel),
12311                    i, r.toString()));
12312            if (r.persistent) {
12313                numPers++;
12314            }
12315        }
12316        return numPers;
12317    }
12318
12319    private static final boolean dumpProcessOomList(PrintWriter pw,
12320            ActivityManagerService service, List<ProcessRecord> origList,
12321            String prefix, String normalLabel, String persistentLabel,
12322            boolean inclDetails, String dumpPackage) {
12323
12324        ArrayList<Pair<ProcessRecord, Integer>> list
12325                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12326        for (int i=0; i<origList.size(); i++) {
12327            ProcessRecord r = origList.get(i);
12328            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12329                continue;
12330            }
12331            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12332        }
12333
12334        if (list.size() <= 0) {
12335            return false;
12336        }
12337
12338        Comparator<Pair<ProcessRecord, Integer>> comparator
12339                = new Comparator<Pair<ProcessRecord, Integer>>() {
12340            @Override
12341            public int compare(Pair<ProcessRecord, Integer> object1,
12342                    Pair<ProcessRecord, Integer> object2) {
12343                if (object1.first.setAdj != object2.first.setAdj) {
12344                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12345                }
12346                if (object1.second.intValue() != object2.second.intValue()) {
12347                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12348                }
12349                return 0;
12350            }
12351        };
12352
12353        Collections.sort(list, comparator);
12354
12355        final long curRealtime = SystemClock.elapsedRealtime();
12356        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12357        final long curUptime = SystemClock.uptimeMillis();
12358        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12359
12360        for (int i=list.size()-1; i>=0; i--) {
12361            ProcessRecord r = list.get(i).first;
12362            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12363            char schedGroup;
12364            switch (r.setSchedGroup) {
12365                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12366                    schedGroup = 'B';
12367                    break;
12368                case Process.THREAD_GROUP_DEFAULT:
12369                    schedGroup = 'F';
12370                    break;
12371                default:
12372                    schedGroup = '?';
12373                    break;
12374            }
12375            char foreground;
12376            if (r.foregroundActivities) {
12377                foreground = 'A';
12378            } else if (r.foregroundServices) {
12379                foreground = 'S';
12380            } else {
12381                foreground = ' ';
12382            }
12383            String procState = ProcessList.makeProcStateString(r.curProcState);
12384            pw.print(prefix);
12385            pw.print(r.persistent ? persistentLabel : normalLabel);
12386            pw.print(" #");
12387            int num = (origList.size()-1)-list.get(i).second;
12388            if (num < 10) pw.print(' ');
12389            pw.print(num);
12390            pw.print(": ");
12391            pw.print(oomAdj);
12392            pw.print(' ');
12393            pw.print(schedGroup);
12394            pw.print('/');
12395            pw.print(foreground);
12396            pw.print('/');
12397            pw.print(procState);
12398            pw.print(" trm:");
12399            if (r.trimMemoryLevel < 10) pw.print(' ');
12400            pw.print(r.trimMemoryLevel);
12401            pw.print(' ');
12402            pw.print(r.toShortString());
12403            pw.print(" (");
12404            pw.print(r.adjType);
12405            pw.println(')');
12406            if (r.adjSource != null || r.adjTarget != null) {
12407                pw.print(prefix);
12408                pw.print("    ");
12409                if (r.adjTarget instanceof ComponentName) {
12410                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12411                } else if (r.adjTarget != null) {
12412                    pw.print(r.adjTarget.toString());
12413                } else {
12414                    pw.print("{null}");
12415                }
12416                pw.print("<=");
12417                if (r.adjSource instanceof ProcessRecord) {
12418                    pw.print("Proc{");
12419                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12420                    pw.println("}");
12421                } else if (r.adjSource != null) {
12422                    pw.println(r.adjSource.toString());
12423                } else {
12424                    pw.println("{null}");
12425                }
12426            }
12427            if (inclDetails) {
12428                pw.print(prefix);
12429                pw.print("    ");
12430                pw.print("oom: max="); pw.print(r.maxAdj);
12431                pw.print(" curRaw="); pw.print(r.curRawAdj);
12432                pw.print(" setRaw="); pw.print(r.setRawAdj);
12433                pw.print(" cur="); pw.print(r.curAdj);
12434                pw.print(" set="); pw.println(r.setAdj);
12435                pw.print(prefix);
12436                pw.print("    ");
12437                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12438                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12439                pw.print(" lastPss="); pw.print(r.lastPss);
12440                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12441                pw.print(prefix);
12442                pw.print("    ");
12443                pw.print("cached="); pw.print(r.cached);
12444                pw.print(" empty="); pw.print(r.empty);
12445                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12446
12447                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12448                    if (r.lastWakeTime != 0) {
12449                        long wtime;
12450                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12451                        synchronized (stats) {
12452                            wtime = stats.getProcessWakeTime(r.info.uid,
12453                                    r.pid, curRealtime);
12454                        }
12455                        long timeUsed = wtime - r.lastWakeTime;
12456                        pw.print(prefix);
12457                        pw.print("    ");
12458                        pw.print("keep awake over ");
12459                        TimeUtils.formatDuration(realtimeSince, pw);
12460                        pw.print(" used ");
12461                        TimeUtils.formatDuration(timeUsed, pw);
12462                        pw.print(" (");
12463                        pw.print((timeUsed*100)/realtimeSince);
12464                        pw.println("%)");
12465                    }
12466                    if (r.lastCpuTime != 0) {
12467                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12468                        pw.print(prefix);
12469                        pw.print("    ");
12470                        pw.print("run cpu over ");
12471                        TimeUtils.formatDuration(uptimeSince, pw);
12472                        pw.print(" used ");
12473                        TimeUtils.formatDuration(timeUsed, pw);
12474                        pw.print(" (");
12475                        pw.print((timeUsed*100)/uptimeSince);
12476                        pw.println("%)");
12477                    }
12478                }
12479            }
12480        }
12481        return true;
12482    }
12483
12484    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12485        ArrayList<ProcessRecord> procs;
12486        synchronized (this) {
12487            if (args != null && args.length > start
12488                    && args[start].charAt(0) != '-') {
12489                procs = new ArrayList<ProcessRecord>();
12490                int pid = -1;
12491                try {
12492                    pid = Integer.parseInt(args[start]);
12493                } catch (NumberFormatException e) {
12494                }
12495                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12496                    ProcessRecord proc = mLruProcesses.get(i);
12497                    if (proc.pid == pid) {
12498                        procs.add(proc);
12499                    } else if (proc.processName.equals(args[start])) {
12500                        procs.add(proc);
12501                    }
12502                }
12503                if (procs.size() <= 0) {
12504                    return null;
12505                }
12506            } else {
12507                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12508            }
12509        }
12510        return procs;
12511    }
12512
12513    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12514            PrintWriter pw, String[] args) {
12515        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12516        if (procs == null) {
12517            pw.println("No process found for: " + args[0]);
12518            return;
12519        }
12520
12521        long uptime = SystemClock.uptimeMillis();
12522        long realtime = SystemClock.elapsedRealtime();
12523        pw.println("Applications Graphics Acceleration Info:");
12524        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12525
12526        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12527            ProcessRecord r = procs.get(i);
12528            if (r.thread != null) {
12529                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12530                pw.flush();
12531                try {
12532                    TransferPipe tp = new TransferPipe();
12533                    try {
12534                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12535                        tp.go(fd);
12536                    } finally {
12537                        tp.kill();
12538                    }
12539                } catch (IOException e) {
12540                    pw.println("Failure while dumping the app: " + r);
12541                    pw.flush();
12542                } catch (RemoteException e) {
12543                    pw.println("Got a RemoteException while dumping the app " + r);
12544                    pw.flush();
12545                }
12546            }
12547        }
12548    }
12549
12550    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12551        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12552        if (procs == null) {
12553            pw.println("No process found for: " + args[0]);
12554            return;
12555        }
12556
12557        pw.println("Applications Database Info:");
12558
12559        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12560            ProcessRecord r = procs.get(i);
12561            if (r.thread != null) {
12562                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12563                pw.flush();
12564                try {
12565                    TransferPipe tp = new TransferPipe();
12566                    try {
12567                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12568                        tp.go(fd);
12569                    } finally {
12570                        tp.kill();
12571                    }
12572                } catch (IOException e) {
12573                    pw.println("Failure while dumping the app: " + r);
12574                    pw.flush();
12575                } catch (RemoteException e) {
12576                    pw.println("Got a RemoteException while dumping the app " + r);
12577                    pw.flush();
12578                }
12579            }
12580        }
12581    }
12582
12583    final static class MemItem {
12584        final boolean isProc;
12585        final String label;
12586        final String shortLabel;
12587        final long pss;
12588        final int id;
12589        final boolean hasActivities;
12590        ArrayList<MemItem> subitems;
12591
12592        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12593                boolean _hasActivities) {
12594            isProc = true;
12595            label = _label;
12596            shortLabel = _shortLabel;
12597            pss = _pss;
12598            id = _id;
12599            hasActivities = _hasActivities;
12600        }
12601
12602        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12603            isProc = false;
12604            label = _label;
12605            shortLabel = _shortLabel;
12606            pss = _pss;
12607            id = _id;
12608            hasActivities = false;
12609        }
12610    }
12611
12612    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12613            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12614        if (sort && !isCompact) {
12615            Collections.sort(items, new Comparator<MemItem>() {
12616                @Override
12617                public int compare(MemItem lhs, MemItem rhs) {
12618                    if (lhs.pss < rhs.pss) {
12619                        return 1;
12620                    } else if (lhs.pss > rhs.pss) {
12621                        return -1;
12622                    }
12623                    return 0;
12624                }
12625            });
12626        }
12627
12628        for (int i=0; i<items.size(); i++) {
12629            MemItem mi = items.get(i);
12630            if (!isCompact) {
12631                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12632            } else if (mi.isProc) {
12633                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12634                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12635                pw.println(mi.hasActivities ? ",a" : ",e");
12636            } else {
12637                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12638                pw.println(mi.pss);
12639            }
12640            if (mi.subitems != null) {
12641                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12642                        true, isCompact);
12643            }
12644        }
12645    }
12646
12647    // These are in KB.
12648    static final long[] DUMP_MEM_BUCKETS = new long[] {
12649        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12650        120*1024, 160*1024, 200*1024,
12651        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12652        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12653    };
12654
12655    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12656            boolean stackLike) {
12657        int start = label.lastIndexOf('.');
12658        if (start >= 0) start++;
12659        else start = 0;
12660        int end = label.length();
12661        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12662            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12663                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12664                out.append(bucket);
12665                out.append(stackLike ? "MB." : "MB ");
12666                out.append(label, start, end);
12667                return;
12668            }
12669        }
12670        out.append(memKB/1024);
12671        out.append(stackLike ? "MB." : "MB ");
12672        out.append(label, start, end);
12673    }
12674
12675    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12676            ProcessList.NATIVE_ADJ,
12677            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12678            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12679            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12680            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12681            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12682    };
12683    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12684            "Native",
12685            "System", "Persistent", "Foreground",
12686            "Visible", "Perceptible",
12687            "Heavy Weight", "Backup",
12688            "A Services", "Home",
12689            "Previous", "B Services", "Cached"
12690    };
12691    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12692            "native",
12693            "sys", "pers", "fore",
12694            "vis", "percept",
12695            "heavy", "backup",
12696            "servicea", "home",
12697            "prev", "serviceb", "cached"
12698    };
12699
12700    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12701            long realtime, boolean isCheckinRequest, boolean isCompact) {
12702        if (isCheckinRequest || isCompact) {
12703            // short checkin version
12704            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12705        } else {
12706            pw.println("Applications Memory Usage (kB):");
12707            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12708        }
12709    }
12710
12711    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12712            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12713        boolean dumpDetails = false;
12714        boolean dumpFullDetails = false;
12715        boolean dumpDalvik = false;
12716        boolean oomOnly = false;
12717        boolean isCompact = false;
12718        boolean localOnly = false;
12719
12720        int opti = 0;
12721        while (opti < args.length) {
12722            String opt = args[opti];
12723            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12724                break;
12725            }
12726            opti++;
12727            if ("-a".equals(opt)) {
12728                dumpDetails = true;
12729                dumpFullDetails = true;
12730                dumpDalvik = true;
12731            } else if ("-d".equals(opt)) {
12732                dumpDalvik = true;
12733            } else if ("-c".equals(opt)) {
12734                isCompact = true;
12735            } else if ("--oom".equals(opt)) {
12736                oomOnly = true;
12737            } else if ("--local".equals(opt)) {
12738                localOnly = true;
12739            } else if ("-h".equals(opt)) {
12740                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12741                pw.println("  -a: include all available information for each process.");
12742                pw.println("  -d: include dalvik details when dumping process details.");
12743                pw.println("  -c: dump in a compact machine-parseable representation.");
12744                pw.println("  --oom: only show processes organized by oom adj.");
12745                pw.println("  --local: only collect details locally, don't call process.");
12746                pw.println("If [process] is specified it can be the name or ");
12747                pw.println("pid of a specific process to dump.");
12748                return;
12749            } else {
12750                pw.println("Unknown argument: " + opt + "; use -h for help");
12751            }
12752        }
12753
12754        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12755        long uptime = SystemClock.uptimeMillis();
12756        long realtime = SystemClock.elapsedRealtime();
12757        final long[] tmpLong = new long[1];
12758
12759        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12760        if (procs == null) {
12761            // No Java processes.  Maybe they want to print a native process.
12762            if (args != null && args.length > opti
12763                    && args[opti].charAt(0) != '-') {
12764                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12765                        = new ArrayList<ProcessCpuTracker.Stats>();
12766                updateCpuStatsNow();
12767                int findPid = -1;
12768                try {
12769                    findPid = Integer.parseInt(args[opti]);
12770                } catch (NumberFormatException e) {
12771                }
12772                synchronized (mProcessCpuThread) {
12773                    final int N = mProcessCpuTracker.countStats();
12774                    for (int i=0; i<N; i++) {
12775                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12776                        if (st.pid == findPid || (st.baseName != null
12777                                && st.baseName.equals(args[opti]))) {
12778                            nativeProcs.add(st);
12779                        }
12780                    }
12781                }
12782                if (nativeProcs.size() > 0) {
12783                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12784                            isCompact);
12785                    Debug.MemoryInfo mi = null;
12786                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12787                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12788                        final int pid = r.pid;
12789                        if (!isCheckinRequest && dumpDetails) {
12790                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12791                        }
12792                        if (mi == null) {
12793                            mi = new Debug.MemoryInfo();
12794                        }
12795                        if (dumpDetails || (!brief && !oomOnly)) {
12796                            Debug.getMemoryInfo(pid, mi);
12797                        } else {
12798                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12799                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12800                        }
12801                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12802                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12803                        if (isCheckinRequest) {
12804                            pw.println();
12805                        }
12806                    }
12807                    return;
12808                }
12809            }
12810            pw.println("No process found for: " + args[opti]);
12811            return;
12812        }
12813
12814        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12815            dumpDetails = true;
12816        }
12817
12818        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12819
12820        String[] innerArgs = new String[args.length-opti];
12821        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12822
12823        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12824        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12825        long nativePss=0, dalvikPss=0, otherPss=0;
12826        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12827
12828        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12829        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12830                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12831
12832        long totalPss = 0;
12833        long cachedPss = 0;
12834
12835        Debug.MemoryInfo mi = null;
12836        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12837            final ProcessRecord r = procs.get(i);
12838            final IApplicationThread thread;
12839            final int pid;
12840            final int oomAdj;
12841            final boolean hasActivities;
12842            synchronized (this) {
12843                thread = r.thread;
12844                pid = r.pid;
12845                oomAdj = r.getSetAdjWithServices();
12846                hasActivities = r.activities.size() > 0;
12847            }
12848            if (thread != null) {
12849                if (!isCheckinRequest && dumpDetails) {
12850                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12851                }
12852                if (mi == null) {
12853                    mi = new Debug.MemoryInfo();
12854                }
12855                if (dumpDetails || (!brief && !oomOnly)) {
12856                    Debug.getMemoryInfo(pid, mi);
12857                } else {
12858                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12859                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12860                }
12861                if (dumpDetails) {
12862                    if (localOnly) {
12863                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12864                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12865                        if (isCheckinRequest) {
12866                            pw.println();
12867                        }
12868                    } else {
12869                        try {
12870                            pw.flush();
12871                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12872                                    dumpDalvik, innerArgs);
12873                        } catch (RemoteException e) {
12874                            if (!isCheckinRequest) {
12875                                pw.println("Got RemoteException!");
12876                                pw.flush();
12877                            }
12878                        }
12879                    }
12880                }
12881
12882                final long myTotalPss = mi.getTotalPss();
12883                final long myTotalUss = mi.getTotalUss();
12884
12885                synchronized (this) {
12886                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12887                        // Record this for posterity if the process has been stable.
12888                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12889                    }
12890                }
12891
12892                if (!isCheckinRequest && mi != null) {
12893                    totalPss += myTotalPss;
12894                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12895                            (hasActivities ? " / activities)" : ")"),
12896                            r.processName, myTotalPss, pid, hasActivities);
12897                    procMems.add(pssItem);
12898                    procMemsMap.put(pid, pssItem);
12899
12900                    nativePss += mi.nativePss;
12901                    dalvikPss += mi.dalvikPss;
12902                    otherPss += mi.otherPss;
12903                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12904                        long mem = mi.getOtherPss(j);
12905                        miscPss[j] += mem;
12906                        otherPss -= mem;
12907                    }
12908
12909                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12910                        cachedPss += myTotalPss;
12911                    }
12912
12913                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12914                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12915                                || oomIndex == (oomPss.length-1)) {
12916                            oomPss[oomIndex] += myTotalPss;
12917                            if (oomProcs[oomIndex] == null) {
12918                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12919                            }
12920                            oomProcs[oomIndex].add(pssItem);
12921                            break;
12922                        }
12923                    }
12924                }
12925            }
12926        }
12927
12928        long nativeProcTotalPss = 0;
12929
12930        if (!isCheckinRequest && procs.size() > 1) {
12931            // If we are showing aggregations, also look for native processes to
12932            // include so that our aggregations are more accurate.
12933            updateCpuStatsNow();
12934            synchronized (mProcessCpuThread) {
12935                final int N = mProcessCpuTracker.countStats();
12936                for (int i=0; i<N; i++) {
12937                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12938                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12939                        if (mi == null) {
12940                            mi = new Debug.MemoryInfo();
12941                        }
12942                        if (!brief && !oomOnly) {
12943                            Debug.getMemoryInfo(st.pid, mi);
12944                        } else {
12945                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12946                            mi.nativePrivateDirty = (int)tmpLong[0];
12947                        }
12948
12949                        final long myTotalPss = mi.getTotalPss();
12950                        totalPss += myTotalPss;
12951                        nativeProcTotalPss += myTotalPss;
12952
12953                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12954                                st.name, myTotalPss, st.pid, false);
12955                        procMems.add(pssItem);
12956
12957                        nativePss += mi.nativePss;
12958                        dalvikPss += mi.dalvikPss;
12959                        otherPss += mi.otherPss;
12960                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12961                            long mem = mi.getOtherPss(j);
12962                            miscPss[j] += mem;
12963                            otherPss -= mem;
12964                        }
12965                        oomPss[0] += myTotalPss;
12966                        if (oomProcs[0] == null) {
12967                            oomProcs[0] = new ArrayList<MemItem>();
12968                        }
12969                        oomProcs[0].add(pssItem);
12970                    }
12971                }
12972            }
12973
12974            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12975
12976            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12977            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12978            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12979            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12980                String label = Debug.MemoryInfo.getOtherLabel(j);
12981                catMems.add(new MemItem(label, label, miscPss[j], j));
12982            }
12983
12984            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12985            for (int j=0; j<oomPss.length; j++) {
12986                if (oomPss[j] != 0) {
12987                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12988                            : DUMP_MEM_OOM_LABEL[j];
12989                    MemItem item = new MemItem(label, label, oomPss[j],
12990                            DUMP_MEM_OOM_ADJ[j]);
12991                    item.subitems = oomProcs[j];
12992                    oomMems.add(item);
12993                }
12994            }
12995
12996            if (!brief && !oomOnly && !isCompact) {
12997                pw.println();
12998                pw.println("Total PSS by process:");
12999                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13000                pw.println();
13001            }
13002            if (!isCompact) {
13003                pw.println("Total PSS by OOM adjustment:");
13004            }
13005            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13006            if (!brief && !oomOnly) {
13007                PrintWriter out = categoryPw != null ? categoryPw : pw;
13008                if (!isCompact) {
13009                    out.println();
13010                    out.println("Total PSS by category:");
13011                }
13012                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13013            }
13014            if (!isCompact) {
13015                pw.println();
13016            }
13017            MemInfoReader memInfo = new MemInfoReader();
13018            memInfo.readMemInfo();
13019            if (nativeProcTotalPss > 0) {
13020                synchronized (this) {
13021                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13022                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13023                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13024                            nativeProcTotalPss);
13025                }
13026            }
13027            if (!brief) {
13028                if (!isCompact) {
13029                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13030                    pw.print(" kB (status ");
13031                    switch (mLastMemoryLevel) {
13032                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13033                            pw.println("normal)");
13034                            break;
13035                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13036                            pw.println("moderate)");
13037                            break;
13038                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13039                            pw.println("low)");
13040                            break;
13041                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13042                            pw.println("critical)");
13043                            break;
13044                        default:
13045                            pw.print(mLastMemoryLevel);
13046                            pw.println(")");
13047                            break;
13048                    }
13049                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13050                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13051                            pw.print(cachedPss); pw.print(" cached pss + ");
13052                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13053                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13054                } else {
13055                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13056                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13057                            + memInfo.getFreeSizeKb()); pw.print(",");
13058                    pw.println(totalPss - cachedPss);
13059                }
13060            }
13061            if (!isCompact) {
13062                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13063                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13064                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13065                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13066                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13067                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13068                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13069                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13070                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13071                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13072                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13073            }
13074            if (!brief) {
13075                if (memInfo.getZramTotalSizeKb() != 0) {
13076                    if (!isCompact) {
13077                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13078                                pw.print(" kB physical used for ");
13079                                pw.print(memInfo.getSwapTotalSizeKb()
13080                                        - memInfo.getSwapFreeSizeKb());
13081                                pw.print(" kB in swap (");
13082                                pw.print(memInfo.getSwapTotalSizeKb());
13083                                pw.println(" kB total swap)");
13084                    } else {
13085                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13086                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13087                                pw.println(memInfo.getSwapFreeSizeKb());
13088                    }
13089                }
13090                final int[] SINGLE_LONG_FORMAT = new int[] {
13091                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13092                };
13093                long[] longOut = new long[1];
13094                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13095                        SINGLE_LONG_FORMAT, null, longOut, null);
13096                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13097                longOut[0] = 0;
13098                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13099                        SINGLE_LONG_FORMAT, null, longOut, null);
13100                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13101                longOut[0] = 0;
13102                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13103                        SINGLE_LONG_FORMAT, null, longOut, null);
13104                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13105                longOut[0] = 0;
13106                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13107                        SINGLE_LONG_FORMAT, null, longOut, null);
13108                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13109                if (!isCompact) {
13110                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13111                        pw.print("      KSM: "); pw.print(sharing);
13112                                pw.print(" kB saved from shared ");
13113                                pw.print(shared); pw.println(" kB");
13114                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13115                                pw.print(voltile); pw.println(" kB volatile");
13116                    }
13117                    pw.print("   Tuning: ");
13118                    pw.print(ActivityManager.staticGetMemoryClass());
13119                    pw.print(" (large ");
13120                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13121                    pw.print("), oom ");
13122                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13123                    pw.print(" kB");
13124                    pw.print(", restore limit ");
13125                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13126                    pw.print(" kB");
13127                    if (ActivityManager.isLowRamDeviceStatic()) {
13128                        pw.print(" (low-ram)");
13129                    }
13130                    if (ActivityManager.isHighEndGfx()) {
13131                        pw.print(" (high-end-gfx)");
13132                    }
13133                    pw.println();
13134                } else {
13135                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13136                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13137                    pw.println(voltile);
13138                    pw.print("tuning,");
13139                    pw.print(ActivityManager.staticGetMemoryClass());
13140                    pw.print(',');
13141                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13142                    pw.print(',');
13143                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13144                    if (ActivityManager.isLowRamDeviceStatic()) {
13145                        pw.print(",low-ram");
13146                    }
13147                    if (ActivityManager.isHighEndGfx()) {
13148                        pw.print(",high-end-gfx");
13149                    }
13150                    pw.println();
13151                }
13152            }
13153        }
13154    }
13155
13156    /**
13157     * Searches array of arguments for the specified string
13158     * @param args array of argument strings
13159     * @param value value to search for
13160     * @return true if the value is contained in the array
13161     */
13162    private static boolean scanArgs(String[] args, String value) {
13163        if (args != null) {
13164            for (String arg : args) {
13165                if (value.equals(arg)) {
13166                    return true;
13167                }
13168            }
13169        }
13170        return false;
13171    }
13172
13173    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13174            ContentProviderRecord cpr, boolean always) {
13175        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13176
13177        if (!inLaunching || always) {
13178            synchronized (cpr) {
13179                cpr.launchingApp = null;
13180                cpr.notifyAll();
13181            }
13182            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13183            String names[] = cpr.info.authority.split(";");
13184            for (int j = 0; j < names.length; j++) {
13185                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13186            }
13187        }
13188
13189        for (int i=0; i<cpr.connections.size(); i++) {
13190            ContentProviderConnection conn = cpr.connections.get(i);
13191            if (conn.waiting) {
13192                // If this connection is waiting for the provider, then we don't
13193                // need to mess with its process unless we are always removing
13194                // or for some reason the provider is not currently launching.
13195                if (inLaunching && !always) {
13196                    continue;
13197                }
13198            }
13199            ProcessRecord capp = conn.client;
13200            conn.dead = true;
13201            if (conn.stableCount > 0) {
13202                if (!capp.persistent && capp.thread != null
13203                        && capp.pid != 0
13204                        && capp.pid != MY_PID) {
13205                    killUnneededProcessLocked(capp, "depends on provider "
13206                            + cpr.name.flattenToShortString()
13207                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13208                }
13209            } else if (capp.thread != null && conn.provider.provider != null) {
13210                try {
13211                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13212                } catch (RemoteException e) {
13213                }
13214                // In the protocol here, we don't expect the client to correctly
13215                // clean up this connection, we'll just remove it.
13216                cpr.connections.remove(i);
13217                conn.client.conProviders.remove(conn);
13218            }
13219        }
13220
13221        if (inLaunching && always) {
13222            mLaunchingProviders.remove(cpr);
13223        }
13224        return inLaunching;
13225    }
13226
13227    /**
13228     * Main code for cleaning up a process when it has gone away.  This is
13229     * called both as a result of the process dying, or directly when stopping
13230     * a process when running in single process mode.
13231     */
13232    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13233            boolean restarting, boolean allowRestart, int index) {
13234        if (index >= 0) {
13235            removeLruProcessLocked(app);
13236            ProcessList.remove(app.pid);
13237        }
13238
13239        mProcessesToGc.remove(app);
13240        mPendingPssProcesses.remove(app);
13241
13242        // Dismiss any open dialogs.
13243        if (app.crashDialog != null && !app.forceCrashReport) {
13244            app.crashDialog.dismiss();
13245            app.crashDialog = null;
13246        }
13247        if (app.anrDialog != null) {
13248            app.anrDialog.dismiss();
13249            app.anrDialog = null;
13250        }
13251        if (app.waitDialog != null) {
13252            app.waitDialog.dismiss();
13253            app.waitDialog = null;
13254        }
13255
13256        app.crashing = false;
13257        app.notResponding = false;
13258
13259        app.resetPackageList(mProcessStats);
13260        app.unlinkDeathRecipient();
13261        app.makeInactive(mProcessStats);
13262        app.waitingToKill = null;
13263        app.forcingToForeground = null;
13264        updateProcessForegroundLocked(app, false, false);
13265        app.foregroundActivities = false;
13266        app.hasShownUi = false;
13267        app.treatLikeActivity = false;
13268        app.hasAboveClient = false;
13269        app.hasClientActivities = false;
13270
13271        mServices.killServicesLocked(app, allowRestart);
13272
13273        boolean restart = false;
13274
13275        // Remove published content providers.
13276        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13277            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13278            final boolean always = app.bad || !allowRestart;
13279            if (removeDyingProviderLocked(app, cpr, always) || always) {
13280                // We left the provider in the launching list, need to
13281                // restart it.
13282                restart = true;
13283            }
13284
13285            cpr.provider = null;
13286            cpr.proc = null;
13287        }
13288        app.pubProviders.clear();
13289
13290        // Take care of any launching providers waiting for this process.
13291        if (checkAppInLaunchingProvidersLocked(app, false)) {
13292            restart = true;
13293        }
13294
13295        // Unregister from connected content providers.
13296        if (!app.conProviders.isEmpty()) {
13297            for (int i=0; i<app.conProviders.size(); i++) {
13298                ContentProviderConnection conn = app.conProviders.get(i);
13299                conn.provider.connections.remove(conn);
13300            }
13301            app.conProviders.clear();
13302        }
13303
13304        // At this point there may be remaining entries in mLaunchingProviders
13305        // where we were the only one waiting, so they are no longer of use.
13306        // Look for these and clean up if found.
13307        // XXX Commented out for now.  Trying to figure out a way to reproduce
13308        // the actual situation to identify what is actually going on.
13309        if (false) {
13310            for (int i=0; i<mLaunchingProviders.size(); i++) {
13311                ContentProviderRecord cpr = (ContentProviderRecord)
13312                        mLaunchingProviders.get(i);
13313                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13314                    synchronized (cpr) {
13315                        cpr.launchingApp = null;
13316                        cpr.notifyAll();
13317                    }
13318                }
13319            }
13320        }
13321
13322        skipCurrentReceiverLocked(app);
13323
13324        // Unregister any receivers.
13325        for (int i=app.receivers.size()-1; i>=0; i--) {
13326            removeReceiverLocked(app.receivers.valueAt(i));
13327        }
13328        app.receivers.clear();
13329
13330        // If the app is undergoing backup, tell the backup manager about it
13331        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13332            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13333                    + mBackupTarget.appInfo + " died during backup");
13334            try {
13335                IBackupManager bm = IBackupManager.Stub.asInterface(
13336                        ServiceManager.getService(Context.BACKUP_SERVICE));
13337                bm.agentDisconnected(app.info.packageName);
13338            } catch (RemoteException e) {
13339                // can't happen; backup manager is local
13340            }
13341        }
13342
13343        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13344            ProcessChangeItem item = mPendingProcessChanges.get(i);
13345            if (item.pid == app.pid) {
13346                mPendingProcessChanges.remove(i);
13347                mAvailProcessChanges.add(item);
13348            }
13349        }
13350        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13351
13352        // If the caller is restarting this app, then leave it in its
13353        // current lists and let the caller take care of it.
13354        if (restarting) {
13355            return;
13356        }
13357
13358        if (!app.persistent || app.isolated) {
13359            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13360                    "Removing non-persistent process during cleanup: " + app);
13361            mProcessNames.remove(app.processName, app.uid);
13362            mIsolatedProcesses.remove(app.uid);
13363            if (mHeavyWeightProcess == app) {
13364                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13365                        mHeavyWeightProcess.userId, 0));
13366                mHeavyWeightProcess = null;
13367            }
13368        } else if (!app.removed) {
13369            // This app is persistent, so we need to keep its record around.
13370            // If it is not already on the pending app list, add it there
13371            // and start a new process for it.
13372            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13373                mPersistentStartingProcesses.add(app);
13374                restart = true;
13375            }
13376        }
13377        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13378                "Clean-up removing on hold: " + app);
13379        mProcessesOnHold.remove(app);
13380
13381        if (app == mHomeProcess) {
13382            mHomeProcess = null;
13383        }
13384        if (app == mPreviousProcess) {
13385            mPreviousProcess = null;
13386        }
13387
13388        if (restart && !app.isolated) {
13389            // We have components that still need to be running in the
13390            // process, so re-launch it.
13391            mProcessNames.put(app.processName, app.uid, app);
13392            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13393        } else if (app.pid > 0 && app.pid != MY_PID) {
13394            // Goodbye!
13395            boolean removed;
13396            synchronized (mPidsSelfLocked) {
13397                mPidsSelfLocked.remove(app.pid);
13398                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13399            }
13400            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13401            if (app.isolated) {
13402                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13403            }
13404            app.setPid(0);
13405        }
13406    }
13407
13408    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13409        // Look through the content providers we are waiting to have launched,
13410        // and if any run in this process then either schedule a restart of
13411        // the process or kill the client waiting for it if this process has
13412        // gone bad.
13413        int NL = mLaunchingProviders.size();
13414        boolean restart = false;
13415        for (int i=0; i<NL; i++) {
13416            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13417            if (cpr.launchingApp == app) {
13418                if (!alwaysBad && !app.bad) {
13419                    restart = true;
13420                } else {
13421                    removeDyingProviderLocked(app, cpr, true);
13422                    // cpr should have been removed from mLaunchingProviders
13423                    NL = mLaunchingProviders.size();
13424                    i--;
13425                }
13426            }
13427        }
13428        return restart;
13429    }
13430
13431    // =========================================================
13432    // SERVICES
13433    // =========================================================
13434
13435    @Override
13436    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13437            int flags) {
13438        enforceNotIsolatedCaller("getServices");
13439        synchronized (this) {
13440            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13441        }
13442    }
13443
13444    @Override
13445    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13446        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13447        synchronized (this) {
13448            return mServices.getRunningServiceControlPanelLocked(name);
13449        }
13450    }
13451
13452    @Override
13453    public ComponentName startService(IApplicationThread caller, Intent service,
13454            String resolvedType, int userId) {
13455        enforceNotIsolatedCaller("startService");
13456        // Refuse possible leaked file descriptors
13457        if (service != null && service.hasFileDescriptors() == true) {
13458            throw new IllegalArgumentException("File descriptors passed in Intent");
13459        }
13460
13461        if (DEBUG_SERVICE)
13462            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13463        synchronized(this) {
13464            final int callingPid = Binder.getCallingPid();
13465            final int callingUid = Binder.getCallingUid();
13466            final long origId = Binder.clearCallingIdentity();
13467            ComponentName res = mServices.startServiceLocked(caller, service,
13468                    resolvedType, callingPid, callingUid, userId);
13469            Binder.restoreCallingIdentity(origId);
13470            return res;
13471        }
13472    }
13473
13474    ComponentName startServiceInPackage(int uid,
13475            Intent service, String resolvedType, int userId) {
13476        synchronized(this) {
13477            if (DEBUG_SERVICE)
13478                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13479            final long origId = Binder.clearCallingIdentity();
13480            ComponentName res = mServices.startServiceLocked(null, service,
13481                    resolvedType, -1, uid, userId);
13482            Binder.restoreCallingIdentity(origId);
13483            return res;
13484        }
13485    }
13486
13487    @Override
13488    public int stopService(IApplicationThread caller, Intent service,
13489            String resolvedType, int userId) {
13490        enforceNotIsolatedCaller("stopService");
13491        // Refuse possible leaked file descriptors
13492        if (service != null && service.hasFileDescriptors() == true) {
13493            throw new IllegalArgumentException("File descriptors passed in Intent");
13494        }
13495
13496        synchronized(this) {
13497            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13498        }
13499    }
13500
13501    @Override
13502    public IBinder peekService(Intent service, String resolvedType) {
13503        enforceNotIsolatedCaller("peekService");
13504        // Refuse possible leaked file descriptors
13505        if (service != null && service.hasFileDescriptors() == true) {
13506            throw new IllegalArgumentException("File descriptors passed in Intent");
13507        }
13508        synchronized(this) {
13509            return mServices.peekServiceLocked(service, resolvedType);
13510        }
13511    }
13512
13513    @Override
13514    public boolean stopServiceToken(ComponentName className, IBinder token,
13515            int startId) {
13516        synchronized(this) {
13517            return mServices.stopServiceTokenLocked(className, token, startId);
13518        }
13519    }
13520
13521    @Override
13522    public void setServiceForeground(ComponentName className, IBinder token,
13523            int id, Notification notification, boolean removeNotification) {
13524        synchronized(this) {
13525            mServices.setServiceForegroundLocked(className, token, id, notification,
13526                    removeNotification);
13527        }
13528    }
13529
13530    @Override
13531    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13532            boolean requireFull, String name, String callerPackage) {
13533        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13534                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13535    }
13536
13537    int unsafeConvertIncomingUser(int userId) {
13538        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13539                ? mCurrentUserId : userId;
13540    }
13541
13542    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13543            int allowMode, String name, String callerPackage) {
13544        final int callingUserId = UserHandle.getUserId(callingUid);
13545        if (callingUserId == userId) {
13546            return userId;
13547        }
13548
13549        // Note that we may be accessing mCurrentUserId outside of a lock...
13550        // shouldn't be a big deal, if this is being called outside
13551        // of a locked context there is intrinsically a race with
13552        // the value the caller will receive and someone else changing it.
13553        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13554        // we will switch to the calling user if access to the current user fails.
13555        int targetUserId = unsafeConvertIncomingUser(userId);
13556
13557        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13558            final boolean allow;
13559            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13560                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13561                // If the caller has this permission, they always pass go.  And collect $200.
13562                allow = true;
13563            } else if (allowMode == ALLOW_FULL_ONLY) {
13564                // We require full access, sucks to be you.
13565                allow = false;
13566            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13567                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13568                // If the caller does not have either permission, they are always doomed.
13569                allow = false;
13570            } else if (allowMode == ALLOW_NON_FULL) {
13571                // We are blanket allowing non-full access, you lucky caller!
13572                allow = true;
13573            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13574                // We may or may not allow this depending on whether the two users are
13575                // in the same profile.
13576                synchronized (mUserProfileGroupIdsSelfLocked) {
13577                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13578                            UserInfo.NO_PROFILE_GROUP_ID);
13579                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13580                            UserInfo.NO_PROFILE_GROUP_ID);
13581                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13582                            && callingProfile == targetProfile;
13583                }
13584            } else {
13585                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13586            }
13587            if (!allow) {
13588                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13589                    // In this case, they would like to just execute as their
13590                    // owner user instead of failing.
13591                    targetUserId = callingUserId;
13592                } else {
13593                    StringBuilder builder = new StringBuilder(128);
13594                    builder.append("Permission Denial: ");
13595                    builder.append(name);
13596                    if (callerPackage != null) {
13597                        builder.append(" from ");
13598                        builder.append(callerPackage);
13599                    }
13600                    builder.append(" asks to run as user ");
13601                    builder.append(userId);
13602                    builder.append(" but is calling from user ");
13603                    builder.append(UserHandle.getUserId(callingUid));
13604                    builder.append("; this requires ");
13605                    builder.append(INTERACT_ACROSS_USERS_FULL);
13606                    if (allowMode != ALLOW_FULL_ONLY) {
13607                        builder.append(" or ");
13608                        builder.append(INTERACT_ACROSS_USERS);
13609                    }
13610                    String msg = builder.toString();
13611                    Slog.w(TAG, msg);
13612                    throw new SecurityException(msg);
13613                }
13614            }
13615        }
13616        if (!allowAll && targetUserId < 0) {
13617            throw new IllegalArgumentException(
13618                    "Call does not support special user #" + targetUserId);
13619        }
13620        return targetUserId;
13621    }
13622
13623    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13624            String className, int flags) {
13625        boolean result = false;
13626        // For apps that don't have pre-defined UIDs, check for permission
13627        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13628            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13629                if (ActivityManager.checkUidPermission(
13630                        INTERACT_ACROSS_USERS,
13631                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13632                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13633                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13634                            + " requests FLAG_SINGLE_USER, but app does not hold "
13635                            + INTERACT_ACROSS_USERS;
13636                    Slog.w(TAG, msg);
13637                    throw new SecurityException(msg);
13638                }
13639                // Permission passed
13640                result = true;
13641            }
13642        } else if ("system".equals(componentProcessName)) {
13643            result = true;
13644        } else {
13645            // App with pre-defined UID, check if it's a persistent app
13646            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13647        }
13648        if (DEBUG_MU) {
13649            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13650                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13651        }
13652        return result;
13653    }
13654
13655    /**
13656     * Checks to see if the caller is in the same app as the singleton
13657     * component, or the component is in a special app. It allows special apps
13658     * to export singleton components but prevents exporting singleton
13659     * components for regular apps.
13660     */
13661    boolean isValidSingletonCall(int callingUid, int componentUid) {
13662        int componentAppId = UserHandle.getAppId(componentUid);
13663        return UserHandle.isSameApp(callingUid, componentUid)
13664                || componentAppId == Process.SYSTEM_UID
13665                || componentAppId == Process.PHONE_UID
13666                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13667                        == PackageManager.PERMISSION_GRANTED;
13668    }
13669
13670    public int bindService(IApplicationThread caller, IBinder token,
13671            Intent service, String resolvedType,
13672            IServiceConnection connection, int flags, int userId) {
13673        enforceNotIsolatedCaller("bindService");
13674        // Refuse possible leaked file descriptors
13675        if (service != null && service.hasFileDescriptors() == true) {
13676            throw new IllegalArgumentException("File descriptors passed in Intent");
13677        }
13678
13679        synchronized(this) {
13680            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13681                    connection, flags, userId);
13682        }
13683    }
13684
13685    public boolean unbindService(IServiceConnection connection) {
13686        synchronized (this) {
13687            return mServices.unbindServiceLocked(connection);
13688        }
13689    }
13690
13691    public void publishService(IBinder token, Intent intent, IBinder service) {
13692        // Refuse possible leaked file descriptors
13693        if (intent != null && intent.hasFileDescriptors() == true) {
13694            throw new IllegalArgumentException("File descriptors passed in Intent");
13695        }
13696
13697        synchronized(this) {
13698            if (!(token instanceof ServiceRecord)) {
13699                throw new IllegalArgumentException("Invalid service token");
13700            }
13701            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13702        }
13703    }
13704
13705    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13706        // Refuse possible leaked file descriptors
13707        if (intent != null && intent.hasFileDescriptors() == true) {
13708            throw new IllegalArgumentException("File descriptors passed in Intent");
13709        }
13710
13711        synchronized(this) {
13712            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13713        }
13714    }
13715
13716    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13717        synchronized(this) {
13718            if (!(token instanceof ServiceRecord)) {
13719                throw new IllegalArgumentException("Invalid service token");
13720            }
13721            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13722        }
13723    }
13724
13725    // =========================================================
13726    // BACKUP AND RESTORE
13727    // =========================================================
13728
13729    // Cause the target app to be launched if necessary and its backup agent
13730    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13731    // activity manager to announce its creation.
13732    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13733        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13734        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13735
13736        synchronized(this) {
13737            // !!! TODO: currently no check here that we're already bound
13738            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13739            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13740            synchronized (stats) {
13741                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13742            }
13743
13744            // Backup agent is now in use, its package can't be stopped.
13745            try {
13746                AppGlobals.getPackageManager().setPackageStoppedState(
13747                        app.packageName, false, UserHandle.getUserId(app.uid));
13748            } catch (RemoteException e) {
13749            } catch (IllegalArgumentException e) {
13750                Slog.w(TAG, "Failed trying to unstop package "
13751                        + app.packageName + ": " + e);
13752            }
13753
13754            BackupRecord r = new BackupRecord(ss, app, backupMode);
13755            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13756                    ? new ComponentName(app.packageName, app.backupAgentName)
13757                    : new ComponentName("android", "FullBackupAgent");
13758            // startProcessLocked() returns existing proc's record if it's already running
13759            ProcessRecord proc = startProcessLocked(app.processName, app,
13760                    false, 0, "backup", hostingName, false, false, false);
13761            if (proc == null) {
13762                Slog.e(TAG, "Unable to start backup agent process " + r);
13763                return false;
13764            }
13765
13766            r.app = proc;
13767            mBackupTarget = r;
13768            mBackupAppName = app.packageName;
13769
13770            // Try not to kill the process during backup
13771            updateOomAdjLocked(proc);
13772
13773            // If the process is already attached, schedule the creation of the backup agent now.
13774            // If it is not yet live, this will be done when it attaches to the framework.
13775            if (proc.thread != null) {
13776                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13777                try {
13778                    proc.thread.scheduleCreateBackupAgent(app,
13779                            compatibilityInfoForPackageLocked(app), backupMode);
13780                } catch (RemoteException e) {
13781                    // Will time out on the backup manager side
13782                }
13783            } else {
13784                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13785            }
13786            // Invariants: at this point, the target app process exists and the application
13787            // is either already running or in the process of coming up.  mBackupTarget and
13788            // mBackupAppName describe the app, so that when it binds back to the AM we
13789            // know that it's scheduled for a backup-agent operation.
13790        }
13791
13792        return true;
13793    }
13794
13795    @Override
13796    public void clearPendingBackup() {
13797        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13798        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13799
13800        synchronized (this) {
13801            mBackupTarget = null;
13802            mBackupAppName = null;
13803        }
13804    }
13805
13806    // A backup agent has just come up
13807    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13808        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13809                + " = " + agent);
13810
13811        synchronized(this) {
13812            if (!agentPackageName.equals(mBackupAppName)) {
13813                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13814                return;
13815            }
13816        }
13817
13818        long oldIdent = Binder.clearCallingIdentity();
13819        try {
13820            IBackupManager bm = IBackupManager.Stub.asInterface(
13821                    ServiceManager.getService(Context.BACKUP_SERVICE));
13822            bm.agentConnected(agentPackageName, agent);
13823        } catch (RemoteException e) {
13824            // can't happen; the backup manager service is local
13825        } catch (Exception e) {
13826            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13827            e.printStackTrace();
13828        } finally {
13829            Binder.restoreCallingIdentity(oldIdent);
13830        }
13831    }
13832
13833    // done with this agent
13834    public void unbindBackupAgent(ApplicationInfo appInfo) {
13835        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13836        if (appInfo == null) {
13837            Slog.w(TAG, "unbind backup agent for null app");
13838            return;
13839        }
13840
13841        synchronized(this) {
13842            try {
13843                if (mBackupAppName == null) {
13844                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13845                    return;
13846                }
13847
13848                if (!mBackupAppName.equals(appInfo.packageName)) {
13849                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13850                    return;
13851                }
13852
13853                // Not backing this app up any more; reset its OOM adjustment
13854                final ProcessRecord proc = mBackupTarget.app;
13855                updateOomAdjLocked(proc);
13856
13857                // If the app crashed during backup, 'thread' will be null here
13858                if (proc.thread != null) {
13859                    try {
13860                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13861                                compatibilityInfoForPackageLocked(appInfo));
13862                    } catch (Exception e) {
13863                        Slog.e(TAG, "Exception when unbinding backup agent:");
13864                        e.printStackTrace();
13865                    }
13866                }
13867            } finally {
13868                mBackupTarget = null;
13869                mBackupAppName = null;
13870            }
13871        }
13872    }
13873    // =========================================================
13874    // BROADCASTS
13875    // =========================================================
13876
13877    private final List getStickiesLocked(String action, IntentFilter filter,
13878            List cur, int userId) {
13879        final ContentResolver resolver = mContext.getContentResolver();
13880        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13881        if (stickies == null) {
13882            return cur;
13883        }
13884        final ArrayList<Intent> list = stickies.get(action);
13885        if (list == null) {
13886            return cur;
13887        }
13888        int N = list.size();
13889        for (int i=0; i<N; i++) {
13890            Intent intent = list.get(i);
13891            if (filter.match(resolver, intent, true, TAG) >= 0) {
13892                if (cur == null) {
13893                    cur = new ArrayList<Intent>();
13894                }
13895                cur.add(intent);
13896            }
13897        }
13898        return cur;
13899    }
13900
13901    boolean isPendingBroadcastProcessLocked(int pid) {
13902        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13903                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13904    }
13905
13906    void skipPendingBroadcastLocked(int pid) {
13907            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13908            for (BroadcastQueue queue : mBroadcastQueues) {
13909                queue.skipPendingBroadcastLocked(pid);
13910            }
13911    }
13912
13913    // The app just attached; send any pending broadcasts that it should receive
13914    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13915        boolean didSomething = false;
13916        for (BroadcastQueue queue : mBroadcastQueues) {
13917            didSomething |= queue.sendPendingBroadcastsLocked(app);
13918        }
13919        return didSomething;
13920    }
13921
13922    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13923            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13924        enforceNotIsolatedCaller("registerReceiver");
13925        int callingUid;
13926        int callingPid;
13927        synchronized(this) {
13928            ProcessRecord callerApp = null;
13929            if (caller != null) {
13930                callerApp = getRecordForAppLocked(caller);
13931                if (callerApp == null) {
13932                    throw new SecurityException(
13933                            "Unable to find app for caller " + caller
13934                            + " (pid=" + Binder.getCallingPid()
13935                            + ") when registering receiver " + receiver);
13936                }
13937                if (callerApp.info.uid != Process.SYSTEM_UID &&
13938                        !callerApp.pkgList.containsKey(callerPackage) &&
13939                        !"android".equals(callerPackage)) {
13940                    throw new SecurityException("Given caller package " + callerPackage
13941                            + " is not running in process " + callerApp);
13942                }
13943                callingUid = callerApp.info.uid;
13944                callingPid = callerApp.pid;
13945            } else {
13946                callerPackage = null;
13947                callingUid = Binder.getCallingUid();
13948                callingPid = Binder.getCallingPid();
13949            }
13950
13951            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13952                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13953
13954            List allSticky = null;
13955
13956            // Look for any matching sticky broadcasts...
13957            Iterator actions = filter.actionsIterator();
13958            if (actions != null) {
13959                while (actions.hasNext()) {
13960                    String action = (String)actions.next();
13961                    allSticky = getStickiesLocked(action, filter, allSticky,
13962                            UserHandle.USER_ALL);
13963                    allSticky = getStickiesLocked(action, filter, allSticky,
13964                            UserHandle.getUserId(callingUid));
13965                }
13966            } else {
13967                allSticky = getStickiesLocked(null, filter, allSticky,
13968                        UserHandle.USER_ALL);
13969                allSticky = getStickiesLocked(null, filter, allSticky,
13970                        UserHandle.getUserId(callingUid));
13971            }
13972
13973            // The first sticky in the list is returned directly back to
13974            // the client.
13975            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13976
13977            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13978                    + ": " + sticky);
13979
13980            if (receiver == null) {
13981                return sticky;
13982            }
13983
13984            ReceiverList rl
13985                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13986            if (rl == null) {
13987                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13988                        userId, receiver);
13989                if (rl.app != null) {
13990                    rl.app.receivers.add(rl);
13991                } else {
13992                    try {
13993                        receiver.asBinder().linkToDeath(rl, 0);
13994                    } catch (RemoteException e) {
13995                        return sticky;
13996                    }
13997                    rl.linkedToDeath = true;
13998                }
13999                mRegisteredReceivers.put(receiver.asBinder(), rl);
14000            } else if (rl.uid != callingUid) {
14001                throw new IllegalArgumentException(
14002                        "Receiver requested to register for uid " + callingUid
14003                        + " was previously registered for uid " + rl.uid);
14004            } else if (rl.pid != callingPid) {
14005                throw new IllegalArgumentException(
14006                        "Receiver requested to register for pid " + callingPid
14007                        + " was previously registered for pid " + rl.pid);
14008            } else if (rl.userId != userId) {
14009                throw new IllegalArgumentException(
14010                        "Receiver requested to register for user " + userId
14011                        + " was previously registered for user " + rl.userId);
14012            }
14013            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14014                    permission, callingUid, userId);
14015            rl.add(bf);
14016            if (!bf.debugCheck()) {
14017                Slog.w(TAG, "==> For Dynamic broadast");
14018            }
14019            mReceiverResolver.addFilter(bf);
14020
14021            // Enqueue broadcasts for all existing stickies that match
14022            // this filter.
14023            if (allSticky != null) {
14024                ArrayList receivers = new ArrayList();
14025                receivers.add(bf);
14026
14027                int N = allSticky.size();
14028                for (int i=0; i<N; i++) {
14029                    Intent intent = (Intent)allSticky.get(i);
14030                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14031                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14032                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14033                            null, null, false, true, true, -1);
14034                    queue.enqueueParallelBroadcastLocked(r);
14035                    queue.scheduleBroadcastsLocked();
14036                }
14037            }
14038
14039            return sticky;
14040        }
14041    }
14042
14043    public void unregisterReceiver(IIntentReceiver receiver) {
14044        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14045
14046        final long origId = Binder.clearCallingIdentity();
14047        try {
14048            boolean doTrim = false;
14049
14050            synchronized(this) {
14051                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14052                if (rl != null) {
14053                    if (rl.curBroadcast != null) {
14054                        BroadcastRecord r = rl.curBroadcast;
14055                        final boolean doNext = finishReceiverLocked(
14056                                receiver.asBinder(), r.resultCode, r.resultData,
14057                                r.resultExtras, r.resultAbort);
14058                        if (doNext) {
14059                            doTrim = true;
14060                            r.queue.processNextBroadcast(false);
14061                        }
14062                    }
14063
14064                    if (rl.app != null) {
14065                        rl.app.receivers.remove(rl);
14066                    }
14067                    removeReceiverLocked(rl);
14068                    if (rl.linkedToDeath) {
14069                        rl.linkedToDeath = false;
14070                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14071                    }
14072                }
14073            }
14074
14075            // If we actually concluded any broadcasts, we might now be able
14076            // to trim the recipients' apps from our working set
14077            if (doTrim) {
14078                trimApplications();
14079                return;
14080            }
14081
14082        } finally {
14083            Binder.restoreCallingIdentity(origId);
14084        }
14085    }
14086
14087    void removeReceiverLocked(ReceiverList rl) {
14088        mRegisteredReceivers.remove(rl.receiver.asBinder());
14089        int N = rl.size();
14090        for (int i=0; i<N; i++) {
14091            mReceiverResolver.removeFilter(rl.get(i));
14092        }
14093    }
14094
14095    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14096        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14097            ProcessRecord r = mLruProcesses.get(i);
14098            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14099                try {
14100                    r.thread.dispatchPackageBroadcast(cmd, packages);
14101                } catch (RemoteException ex) {
14102                }
14103            }
14104        }
14105    }
14106
14107    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14108            int[] users) {
14109        List<ResolveInfo> receivers = null;
14110        try {
14111            HashSet<ComponentName> singleUserReceivers = null;
14112            boolean scannedFirstReceivers = false;
14113            for (int user : users) {
14114                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14115                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14116                if (user != 0 && newReceivers != null) {
14117                    // If this is not the primary user, we need to check for
14118                    // any receivers that should be filtered out.
14119                    for (int i=0; i<newReceivers.size(); i++) {
14120                        ResolveInfo ri = newReceivers.get(i);
14121                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14122                            newReceivers.remove(i);
14123                            i--;
14124                        }
14125                    }
14126                }
14127                if (newReceivers != null && newReceivers.size() == 0) {
14128                    newReceivers = null;
14129                }
14130                if (receivers == null) {
14131                    receivers = newReceivers;
14132                } else if (newReceivers != null) {
14133                    // We need to concatenate the additional receivers
14134                    // found with what we have do far.  This would be easy,
14135                    // but we also need to de-dup any receivers that are
14136                    // singleUser.
14137                    if (!scannedFirstReceivers) {
14138                        // Collect any single user receivers we had already retrieved.
14139                        scannedFirstReceivers = true;
14140                        for (int i=0; i<receivers.size(); i++) {
14141                            ResolveInfo ri = receivers.get(i);
14142                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14143                                ComponentName cn = new ComponentName(
14144                                        ri.activityInfo.packageName, ri.activityInfo.name);
14145                                if (singleUserReceivers == null) {
14146                                    singleUserReceivers = new HashSet<ComponentName>();
14147                                }
14148                                singleUserReceivers.add(cn);
14149                            }
14150                        }
14151                    }
14152                    // Add the new results to the existing results, tracking
14153                    // and de-dupping single user receivers.
14154                    for (int i=0; i<newReceivers.size(); i++) {
14155                        ResolveInfo ri = newReceivers.get(i);
14156                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14157                            ComponentName cn = new ComponentName(
14158                                    ri.activityInfo.packageName, ri.activityInfo.name);
14159                            if (singleUserReceivers == null) {
14160                                singleUserReceivers = new HashSet<ComponentName>();
14161                            }
14162                            if (!singleUserReceivers.contains(cn)) {
14163                                singleUserReceivers.add(cn);
14164                                receivers.add(ri);
14165                            }
14166                        } else {
14167                            receivers.add(ri);
14168                        }
14169                    }
14170                }
14171            }
14172        } catch (RemoteException ex) {
14173            // pm is in same process, this will never happen.
14174        }
14175        return receivers;
14176    }
14177
14178    private final int broadcastIntentLocked(ProcessRecord callerApp,
14179            String callerPackage, Intent intent, String resolvedType,
14180            IIntentReceiver resultTo, int resultCode, String resultData,
14181            Bundle map, String requiredPermission, int appOp,
14182            boolean ordered, boolean sticky, int callingPid, int callingUid,
14183            int userId) {
14184        intent = new Intent(intent);
14185
14186        // By default broadcasts do not go to stopped apps.
14187        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14188
14189        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14190            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14191            + " ordered=" + ordered + " userid=" + userId);
14192        if ((resultTo != null) && !ordered) {
14193            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14194        }
14195
14196        userId = handleIncomingUser(callingPid, callingUid, userId,
14197                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14198
14199        // Make sure that the user who is receiving this broadcast is started.
14200        // If not, we will just skip it.
14201
14202
14203        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14204            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14205                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14206                Slog.w(TAG, "Skipping broadcast of " + intent
14207                        + ": user " + userId + " is stopped");
14208                return ActivityManager.BROADCAST_SUCCESS;
14209            }
14210        }
14211
14212        /*
14213         * Prevent non-system code (defined here to be non-persistent
14214         * processes) from sending protected broadcasts.
14215         */
14216        int callingAppId = UserHandle.getAppId(callingUid);
14217        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14218            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14219            || callingAppId == Process.NFC_UID || callingUid == 0) {
14220            // Always okay.
14221        } else if (callerApp == null || !callerApp.persistent) {
14222            try {
14223                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14224                        intent.getAction())) {
14225                    String msg = "Permission Denial: not allowed to send broadcast "
14226                            + intent.getAction() + " from pid="
14227                            + callingPid + ", uid=" + callingUid;
14228                    Slog.w(TAG, msg);
14229                    throw new SecurityException(msg);
14230                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14231                    // Special case for compatibility: we don't want apps to send this,
14232                    // but historically it has not been protected and apps may be using it
14233                    // to poke their own app widget.  So, instead of making it protected,
14234                    // just limit it to the caller.
14235                    if (callerApp == null) {
14236                        String msg = "Permission Denial: not allowed to send broadcast "
14237                                + intent.getAction() + " from unknown caller.";
14238                        Slog.w(TAG, msg);
14239                        throw new SecurityException(msg);
14240                    } else if (intent.getComponent() != null) {
14241                        // They are good enough to send to an explicit component...  verify
14242                        // it is being sent to the calling app.
14243                        if (!intent.getComponent().getPackageName().equals(
14244                                callerApp.info.packageName)) {
14245                            String msg = "Permission Denial: not allowed to send broadcast "
14246                                    + intent.getAction() + " to "
14247                                    + intent.getComponent().getPackageName() + " from "
14248                                    + callerApp.info.packageName;
14249                            Slog.w(TAG, msg);
14250                            throw new SecurityException(msg);
14251                        }
14252                    } else {
14253                        // Limit broadcast to their own package.
14254                        intent.setPackage(callerApp.info.packageName);
14255                    }
14256                }
14257            } catch (RemoteException e) {
14258                Slog.w(TAG, "Remote exception", e);
14259                return ActivityManager.BROADCAST_SUCCESS;
14260            }
14261        }
14262
14263        // Handle special intents: if this broadcast is from the package
14264        // manager about a package being removed, we need to remove all of
14265        // its activities from the history stack.
14266        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14267                intent.getAction());
14268        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14269                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14270                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14271                || uidRemoved) {
14272            if (checkComponentPermission(
14273                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14274                    callingPid, callingUid, -1, true)
14275                    == PackageManager.PERMISSION_GRANTED) {
14276                if (uidRemoved) {
14277                    final Bundle intentExtras = intent.getExtras();
14278                    final int uid = intentExtras != null
14279                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14280                    if (uid >= 0) {
14281                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14282                        synchronized (bs) {
14283                            bs.removeUidStatsLocked(uid);
14284                        }
14285                        mAppOpsService.uidRemoved(uid);
14286                    }
14287                } else {
14288                    // If resources are unavailable just force stop all
14289                    // those packages and flush the attribute cache as well.
14290                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14291                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14292                        if (list != null && (list.length > 0)) {
14293                            for (String pkg : list) {
14294                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14295                                        "storage unmount");
14296                            }
14297                            sendPackageBroadcastLocked(
14298                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14299                        }
14300                    } else {
14301                        Uri data = intent.getData();
14302                        String ssp;
14303                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14304                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14305                                    intent.getAction());
14306                            boolean fullUninstall = removed &&
14307                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14308                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14309                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14310                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14311                                        false, fullUninstall, userId,
14312                                        removed ? "pkg removed" : "pkg changed");
14313                            }
14314                            if (removed) {
14315                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14316                                        new String[] {ssp}, userId);
14317                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14318                                    mAppOpsService.packageRemoved(
14319                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14320
14321                                    // Remove all permissions granted from/to this package
14322                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14323                                }
14324                            }
14325                        }
14326                    }
14327                }
14328            } else {
14329                String msg = "Permission Denial: " + intent.getAction()
14330                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14331                        + ", uid=" + callingUid + ")"
14332                        + " requires "
14333                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14334                Slog.w(TAG, msg);
14335                throw new SecurityException(msg);
14336            }
14337
14338        // Special case for adding a package: by default turn on compatibility
14339        // mode.
14340        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14341            Uri data = intent.getData();
14342            String ssp;
14343            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14344                mCompatModePackages.handlePackageAddedLocked(ssp,
14345                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14346            }
14347        }
14348
14349        /*
14350         * If this is the time zone changed action, queue up a message that will reset the timezone
14351         * of all currently running processes. This message will get queued up before the broadcast
14352         * happens.
14353         */
14354        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14355            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14356        }
14357
14358        /*
14359         * If the user set the time, let all running processes know.
14360         */
14361        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14362            final int is24Hour = intent.getBooleanExtra(
14363                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14364            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14365        }
14366
14367        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14368            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14369        }
14370
14371        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14372            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14373            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14374        }
14375
14376        // Add to the sticky list if requested.
14377        if (sticky) {
14378            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14379                    callingPid, callingUid)
14380                    != PackageManager.PERMISSION_GRANTED) {
14381                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14382                        + callingPid + ", uid=" + callingUid
14383                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14384                Slog.w(TAG, msg);
14385                throw new SecurityException(msg);
14386            }
14387            if (requiredPermission != null) {
14388                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14389                        + " and enforce permission " + requiredPermission);
14390                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14391            }
14392            if (intent.getComponent() != null) {
14393                throw new SecurityException(
14394                        "Sticky broadcasts can't target a specific component");
14395            }
14396            // We use userId directly here, since the "all" target is maintained
14397            // as a separate set of sticky broadcasts.
14398            if (userId != UserHandle.USER_ALL) {
14399                // But first, if this is not a broadcast to all users, then
14400                // make sure it doesn't conflict with an existing broadcast to
14401                // all users.
14402                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14403                        UserHandle.USER_ALL);
14404                if (stickies != null) {
14405                    ArrayList<Intent> list = stickies.get(intent.getAction());
14406                    if (list != null) {
14407                        int N = list.size();
14408                        int i;
14409                        for (i=0; i<N; i++) {
14410                            if (intent.filterEquals(list.get(i))) {
14411                                throw new IllegalArgumentException(
14412                                        "Sticky broadcast " + intent + " for user "
14413                                        + userId + " conflicts with existing global broadcast");
14414                            }
14415                        }
14416                    }
14417                }
14418            }
14419            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14420            if (stickies == null) {
14421                stickies = new ArrayMap<String, ArrayList<Intent>>();
14422                mStickyBroadcasts.put(userId, stickies);
14423            }
14424            ArrayList<Intent> list = stickies.get(intent.getAction());
14425            if (list == null) {
14426                list = new ArrayList<Intent>();
14427                stickies.put(intent.getAction(), list);
14428            }
14429            int N = list.size();
14430            int i;
14431            for (i=0; i<N; i++) {
14432                if (intent.filterEquals(list.get(i))) {
14433                    // This sticky already exists, replace it.
14434                    list.set(i, new Intent(intent));
14435                    break;
14436                }
14437            }
14438            if (i >= N) {
14439                list.add(new Intent(intent));
14440            }
14441        }
14442
14443        int[] users;
14444        if (userId == UserHandle.USER_ALL) {
14445            // Caller wants broadcast to go to all started users.
14446            users = mStartedUserArray;
14447        } else {
14448            // Caller wants broadcast to go to one specific user.
14449            users = new int[] {userId};
14450        }
14451
14452        // Figure out who all will receive this broadcast.
14453        List receivers = null;
14454        List<BroadcastFilter> registeredReceivers = null;
14455        // Need to resolve the intent to interested receivers...
14456        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14457                 == 0) {
14458            receivers = collectReceiverComponents(intent, resolvedType, users);
14459        }
14460        if (intent.getComponent() == null) {
14461            registeredReceivers = mReceiverResolver.queryIntent(intent,
14462                    resolvedType, false, userId);
14463        }
14464
14465        final boolean replacePending =
14466                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14467
14468        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14469                + " replacePending=" + replacePending);
14470
14471        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14472        if (!ordered && NR > 0) {
14473            // If we are not serializing this broadcast, then send the
14474            // registered receivers separately so they don't wait for the
14475            // components to be launched.
14476            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14477            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14478                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14479                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14480                    ordered, sticky, false, userId);
14481            if (DEBUG_BROADCAST) Slog.v(
14482                    TAG, "Enqueueing parallel broadcast " + r);
14483            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14484            if (!replaced) {
14485                queue.enqueueParallelBroadcastLocked(r);
14486                queue.scheduleBroadcastsLocked();
14487            }
14488            registeredReceivers = null;
14489            NR = 0;
14490        }
14491
14492        // Merge into one list.
14493        int ir = 0;
14494        if (receivers != null) {
14495            // A special case for PACKAGE_ADDED: do not allow the package
14496            // being added to see this broadcast.  This prevents them from
14497            // using this as a back door to get run as soon as they are
14498            // installed.  Maybe in the future we want to have a special install
14499            // broadcast or such for apps, but we'd like to deliberately make
14500            // this decision.
14501            String skipPackages[] = null;
14502            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14503                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14504                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14505                Uri data = intent.getData();
14506                if (data != null) {
14507                    String pkgName = data.getSchemeSpecificPart();
14508                    if (pkgName != null) {
14509                        skipPackages = new String[] { pkgName };
14510                    }
14511                }
14512            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14513                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14514            }
14515            if (skipPackages != null && (skipPackages.length > 0)) {
14516                for (String skipPackage : skipPackages) {
14517                    if (skipPackage != null) {
14518                        int NT = receivers.size();
14519                        for (int it=0; it<NT; it++) {
14520                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14521                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14522                                receivers.remove(it);
14523                                it--;
14524                                NT--;
14525                            }
14526                        }
14527                    }
14528                }
14529            }
14530
14531            int NT = receivers != null ? receivers.size() : 0;
14532            int it = 0;
14533            ResolveInfo curt = null;
14534            BroadcastFilter curr = null;
14535            while (it < NT && ir < NR) {
14536                if (curt == null) {
14537                    curt = (ResolveInfo)receivers.get(it);
14538                }
14539                if (curr == null) {
14540                    curr = registeredReceivers.get(ir);
14541                }
14542                if (curr.getPriority() >= curt.priority) {
14543                    // Insert this broadcast record into the final list.
14544                    receivers.add(it, curr);
14545                    ir++;
14546                    curr = null;
14547                    it++;
14548                    NT++;
14549                } else {
14550                    // Skip to the next ResolveInfo in the final list.
14551                    it++;
14552                    curt = null;
14553                }
14554            }
14555        }
14556        while (ir < NR) {
14557            if (receivers == null) {
14558                receivers = new ArrayList();
14559            }
14560            receivers.add(registeredReceivers.get(ir));
14561            ir++;
14562        }
14563
14564        if ((receivers != null && receivers.size() > 0)
14565                || resultTo != null) {
14566            BroadcastQueue queue = broadcastQueueForIntent(intent);
14567            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14568                    callerPackage, callingPid, callingUid, resolvedType,
14569                    requiredPermission, appOp, receivers, resultTo, resultCode,
14570                    resultData, map, ordered, sticky, false, userId);
14571            if (DEBUG_BROADCAST) Slog.v(
14572                    TAG, "Enqueueing ordered broadcast " + r
14573                    + ": prev had " + queue.mOrderedBroadcasts.size());
14574            if (DEBUG_BROADCAST) {
14575                int seq = r.intent.getIntExtra("seq", -1);
14576                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14577            }
14578            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14579            if (!replaced) {
14580                queue.enqueueOrderedBroadcastLocked(r);
14581                queue.scheduleBroadcastsLocked();
14582            }
14583        }
14584
14585        return ActivityManager.BROADCAST_SUCCESS;
14586    }
14587
14588    final Intent verifyBroadcastLocked(Intent intent) {
14589        // Refuse possible leaked file descriptors
14590        if (intent != null && intent.hasFileDescriptors() == true) {
14591            throw new IllegalArgumentException("File descriptors passed in Intent");
14592        }
14593
14594        int flags = intent.getFlags();
14595
14596        if (!mProcessesReady) {
14597            // if the caller really truly claims to know what they're doing, go
14598            // ahead and allow the broadcast without launching any receivers
14599            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14600                intent = new Intent(intent);
14601                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14602            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14603                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14604                        + " before boot completion");
14605                throw new IllegalStateException("Cannot broadcast before boot completed");
14606            }
14607        }
14608
14609        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14610            throw new IllegalArgumentException(
14611                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14612        }
14613
14614        return intent;
14615    }
14616
14617    public final int broadcastIntent(IApplicationThread caller,
14618            Intent intent, String resolvedType, IIntentReceiver resultTo,
14619            int resultCode, String resultData, Bundle map,
14620            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14621        enforceNotIsolatedCaller("broadcastIntent");
14622        synchronized(this) {
14623            intent = verifyBroadcastLocked(intent);
14624
14625            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14626            final int callingPid = Binder.getCallingPid();
14627            final int callingUid = Binder.getCallingUid();
14628            final long origId = Binder.clearCallingIdentity();
14629            int res = broadcastIntentLocked(callerApp,
14630                    callerApp != null ? callerApp.info.packageName : null,
14631                    intent, resolvedType, resultTo,
14632                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14633                    callingPid, callingUid, userId);
14634            Binder.restoreCallingIdentity(origId);
14635            return res;
14636        }
14637    }
14638
14639    int broadcastIntentInPackage(String packageName, int uid,
14640            Intent intent, String resolvedType, IIntentReceiver resultTo,
14641            int resultCode, String resultData, Bundle map,
14642            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14643        synchronized(this) {
14644            intent = verifyBroadcastLocked(intent);
14645
14646            final long origId = Binder.clearCallingIdentity();
14647            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14648                    resultTo, resultCode, resultData, map, requiredPermission,
14649                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14650            Binder.restoreCallingIdentity(origId);
14651            return res;
14652        }
14653    }
14654
14655    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14656        // Refuse possible leaked file descriptors
14657        if (intent != null && intent.hasFileDescriptors() == true) {
14658            throw new IllegalArgumentException("File descriptors passed in Intent");
14659        }
14660
14661        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14662                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14663
14664        synchronized(this) {
14665            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14666                    != PackageManager.PERMISSION_GRANTED) {
14667                String msg = "Permission Denial: unbroadcastIntent() from pid="
14668                        + Binder.getCallingPid()
14669                        + ", uid=" + Binder.getCallingUid()
14670                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14671                Slog.w(TAG, msg);
14672                throw new SecurityException(msg);
14673            }
14674            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14675            if (stickies != null) {
14676                ArrayList<Intent> list = stickies.get(intent.getAction());
14677                if (list != null) {
14678                    int N = list.size();
14679                    int i;
14680                    for (i=0; i<N; i++) {
14681                        if (intent.filterEquals(list.get(i))) {
14682                            list.remove(i);
14683                            break;
14684                        }
14685                    }
14686                    if (list.size() <= 0) {
14687                        stickies.remove(intent.getAction());
14688                    }
14689                }
14690                if (stickies.size() <= 0) {
14691                    mStickyBroadcasts.remove(userId);
14692                }
14693            }
14694        }
14695    }
14696
14697    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14698            String resultData, Bundle resultExtras, boolean resultAbort) {
14699        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14700        if (r == null) {
14701            Slog.w(TAG, "finishReceiver called but not found on queue");
14702            return false;
14703        }
14704
14705        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14706    }
14707
14708    void backgroundServicesFinishedLocked(int userId) {
14709        for (BroadcastQueue queue : mBroadcastQueues) {
14710            queue.backgroundServicesFinishedLocked(userId);
14711        }
14712    }
14713
14714    public void finishReceiver(IBinder who, int resultCode, String resultData,
14715            Bundle resultExtras, boolean resultAbort) {
14716        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14717
14718        // Refuse possible leaked file descriptors
14719        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14720            throw new IllegalArgumentException("File descriptors passed in Bundle");
14721        }
14722
14723        final long origId = Binder.clearCallingIdentity();
14724        try {
14725            boolean doNext = false;
14726            BroadcastRecord r;
14727
14728            synchronized(this) {
14729                r = broadcastRecordForReceiverLocked(who);
14730                if (r != null) {
14731                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14732                        resultData, resultExtras, resultAbort, true);
14733                }
14734            }
14735
14736            if (doNext) {
14737                r.queue.processNextBroadcast(false);
14738            }
14739            trimApplications();
14740        } finally {
14741            Binder.restoreCallingIdentity(origId);
14742        }
14743    }
14744
14745    // =========================================================
14746    // INSTRUMENTATION
14747    // =========================================================
14748
14749    public boolean startInstrumentation(ComponentName className,
14750            String profileFile, int flags, Bundle arguments,
14751            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14752            int userId, String abiOverride) {
14753        enforceNotIsolatedCaller("startInstrumentation");
14754        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14755                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14756        // Refuse possible leaked file descriptors
14757        if (arguments != null && arguments.hasFileDescriptors()) {
14758            throw new IllegalArgumentException("File descriptors passed in Bundle");
14759        }
14760
14761        synchronized(this) {
14762            InstrumentationInfo ii = null;
14763            ApplicationInfo ai = null;
14764            try {
14765                ii = mContext.getPackageManager().getInstrumentationInfo(
14766                    className, STOCK_PM_FLAGS);
14767                ai = AppGlobals.getPackageManager().getApplicationInfo(
14768                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14769            } catch (PackageManager.NameNotFoundException e) {
14770            } catch (RemoteException e) {
14771            }
14772            if (ii == null) {
14773                reportStartInstrumentationFailure(watcher, className,
14774                        "Unable to find instrumentation info for: " + className);
14775                return false;
14776            }
14777            if (ai == null) {
14778                reportStartInstrumentationFailure(watcher, className,
14779                        "Unable to find instrumentation target package: " + ii.targetPackage);
14780                return false;
14781            }
14782
14783            int match = mContext.getPackageManager().checkSignatures(
14784                    ii.targetPackage, ii.packageName);
14785            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14786                String msg = "Permission Denial: starting instrumentation "
14787                        + className + " from pid="
14788                        + Binder.getCallingPid()
14789                        + ", uid=" + Binder.getCallingPid()
14790                        + " not allowed because package " + ii.packageName
14791                        + " does not have a signature matching the target "
14792                        + ii.targetPackage;
14793                reportStartInstrumentationFailure(watcher, className, msg);
14794                throw new SecurityException(msg);
14795            }
14796
14797            final long origId = Binder.clearCallingIdentity();
14798            // Instrumentation can kill and relaunch even persistent processes
14799            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14800                    "start instr");
14801            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14802            app.instrumentationClass = className;
14803            app.instrumentationInfo = ai;
14804            app.instrumentationProfileFile = profileFile;
14805            app.instrumentationArguments = arguments;
14806            app.instrumentationWatcher = watcher;
14807            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14808            app.instrumentationResultClass = className;
14809            Binder.restoreCallingIdentity(origId);
14810        }
14811
14812        return true;
14813    }
14814
14815    /**
14816     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14817     * error to the logs, but if somebody is watching, send the report there too.  This enables
14818     * the "am" command to report errors with more information.
14819     *
14820     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14821     * @param cn The component name of the instrumentation.
14822     * @param report The error report.
14823     */
14824    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14825            ComponentName cn, String report) {
14826        Slog.w(TAG, report);
14827        try {
14828            if (watcher != null) {
14829                Bundle results = new Bundle();
14830                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14831                results.putString("Error", report);
14832                watcher.instrumentationStatus(cn, -1, results);
14833            }
14834        } catch (RemoteException e) {
14835            Slog.w(TAG, e);
14836        }
14837    }
14838
14839    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14840        if (app.instrumentationWatcher != null) {
14841            try {
14842                // NOTE:  IInstrumentationWatcher *must* be oneway here
14843                app.instrumentationWatcher.instrumentationFinished(
14844                    app.instrumentationClass,
14845                    resultCode,
14846                    results);
14847            } catch (RemoteException e) {
14848            }
14849        }
14850        if (app.instrumentationUiAutomationConnection != null) {
14851            try {
14852                app.instrumentationUiAutomationConnection.shutdown();
14853            } catch (RemoteException re) {
14854                /* ignore */
14855            }
14856            // Only a UiAutomation can set this flag and now that
14857            // it is finished we make sure it is reset to its default.
14858            mUserIsMonkey = false;
14859        }
14860        app.instrumentationWatcher = null;
14861        app.instrumentationUiAutomationConnection = null;
14862        app.instrumentationClass = null;
14863        app.instrumentationInfo = null;
14864        app.instrumentationProfileFile = null;
14865        app.instrumentationArguments = null;
14866
14867        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14868                "finished inst");
14869    }
14870
14871    public void finishInstrumentation(IApplicationThread target,
14872            int resultCode, Bundle results) {
14873        int userId = UserHandle.getCallingUserId();
14874        // Refuse possible leaked file descriptors
14875        if (results != null && results.hasFileDescriptors()) {
14876            throw new IllegalArgumentException("File descriptors passed in Intent");
14877        }
14878
14879        synchronized(this) {
14880            ProcessRecord app = getRecordForAppLocked(target);
14881            if (app == null) {
14882                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14883                return;
14884            }
14885            final long origId = Binder.clearCallingIdentity();
14886            finishInstrumentationLocked(app, resultCode, results);
14887            Binder.restoreCallingIdentity(origId);
14888        }
14889    }
14890
14891    // =========================================================
14892    // CONFIGURATION
14893    // =========================================================
14894
14895    public ConfigurationInfo getDeviceConfigurationInfo() {
14896        ConfigurationInfo config = new ConfigurationInfo();
14897        synchronized (this) {
14898            config.reqTouchScreen = mConfiguration.touchscreen;
14899            config.reqKeyboardType = mConfiguration.keyboard;
14900            config.reqNavigation = mConfiguration.navigation;
14901            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14902                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14903                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14904            }
14905            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14906                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14907                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14908            }
14909            config.reqGlEsVersion = GL_ES_VERSION;
14910        }
14911        return config;
14912    }
14913
14914    ActivityStack getFocusedStack() {
14915        return mStackSupervisor.getFocusedStack();
14916    }
14917
14918    public Configuration getConfiguration() {
14919        Configuration ci;
14920        synchronized(this) {
14921            ci = new Configuration(mConfiguration);
14922        }
14923        return ci;
14924    }
14925
14926    public void updatePersistentConfiguration(Configuration values) {
14927        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14928                "updateConfiguration()");
14929        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14930                "updateConfiguration()");
14931        if (values == null) {
14932            throw new NullPointerException("Configuration must not be null");
14933        }
14934
14935        synchronized(this) {
14936            final long origId = Binder.clearCallingIdentity();
14937            updateConfigurationLocked(values, null, true, false);
14938            Binder.restoreCallingIdentity(origId);
14939        }
14940    }
14941
14942    public void updateConfiguration(Configuration values) {
14943        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14944                "updateConfiguration()");
14945
14946        synchronized(this) {
14947            if (values == null && mWindowManager != null) {
14948                // sentinel: fetch the current configuration from the window manager
14949                values = mWindowManager.computeNewConfiguration();
14950            }
14951
14952            if (mWindowManager != null) {
14953                mProcessList.applyDisplaySize(mWindowManager);
14954            }
14955
14956            final long origId = Binder.clearCallingIdentity();
14957            if (values != null) {
14958                Settings.System.clearConfiguration(values);
14959            }
14960            updateConfigurationLocked(values, null, false, false);
14961            Binder.restoreCallingIdentity(origId);
14962        }
14963    }
14964
14965    /**
14966     * Do either or both things: (1) change the current configuration, and (2)
14967     * make sure the given activity is running with the (now) current
14968     * configuration.  Returns true if the activity has been left running, or
14969     * false if <var>starting</var> is being destroyed to match the new
14970     * configuration.
14971     * @param persistent TODO
14972     */
14973    boolean updateConfigurationLocked(Configuration values,
14974            ActivityRecord starting, boolean persistent, boolean initLocale) {
14975        int changes = 0;
14976
14977        if (values != null) {
14978            Configuration newConfig = new Configuration(mConfiguration);
14979            changes = newConfig.updateFrom(values);
14980            if (changes != 0) {
14981                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14982                    Slog.i(TAG, "Updating configuration to: " + values);
14983                }
14984
14985                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14986
14987                if (values.locale != null && !initLocale) {
14988                    saveLocaleLocked(values.locale,
14989                                     !values.locale.equals(mConfiguration.locale),
14990                                     values.userSetLocale);
14991                }
14992
14993                mConfigurationSeq++;
14994                if (mConfigurationSeq <= 0) {
14995                    mConfigurationSeq = 1;
14996                }
14997                newConfig.seq = mConfigurationSeq;
14998                mConfiguration = newConfig;
14999                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15000                //mUsageStatsService.noteStartConfig(newConfig);
15001
15002                final Configuration configCopy = new Configuration(mConfiguration);
15003
15004                // TODO: If our config changes, should we auto dismiss any currently
15005                // showing dialogs?
15006                mShowDialogs = shouldShowDialogs(newConfig);
15007
15008                AttributeCache ac = AttributeCache.instance();
15009                if (ac != null) {
15010                    ac.updateConfiguration(configCopy);
15011                }
15012
15013                // Make sure all resources in our process are updated
15014                // right now, so that anyone who is going to retrieve
15015                // resource values after we return will be sure to get
15016                // the new ones.  This is especially important during
15017                // boot, where the first config change needs to guarantee
15018                // all resources have that config before following boot
15019                // code is executed.
15020                mSystemThread.applyConfigurationToResources(configCopy);
15021
15022                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15023                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15024                    msg.obj = new Configuration(configCopy);
15025                    mHandler.sendMessage(msg);
15026                }
15027
15028                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15029                    ProcessRecord app = mLruProcesses.get(i);
15030                    try {
15031                        if (app.thread != null) {
15032                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15033                                    + app.processName + " new config " + mConfiguration);
15034                            app.thread.scheduleConfigurationChanged(configCopy);
15035                        }
15036                    } catch (Exception e) {
15037                    }
15038                }
15039                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15040                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15041                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15042                        | Intent.FLAG_RECEIVER_FOREGROUND);
15043                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15044                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15045                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15046                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15047                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15048                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15049                    broadcastIntentLocked(null, null, intent,
15050                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15051                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15052                }
15053            }
15054        }
15055
15056        boolean kept = true;
15057        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15058        // mainStack is null during startup.
15059        if (mainStack != null) {
15060            if (changes != 0 && starting == null) {
15061                // If the configuration changed, and the caller is not already
15062                // in the process of starting an activity, then find the top
15063                // activity to check if its configuration needs to change.
15064                starting = mainStack.topRunningActivityLocked(null);
15065            }
15066
15067            if (starting != null) {
15068                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15069                // And we need to make sure at this point that all other activities
15070                // are made visible with the correct configuration.
15071                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15072            }
15073        }
15074
15075        if (values != null && mWindowManager != null) {
15076            mWindowManager.setNewConfiguration(mConfiguration);
15077        }
15078
15079        return kept;
15080    }
15081
15082    /**
15083     * Decide based on the configuration whether we should shouw the ANR,
15084     * crash, etc dialogs.  The idea is that if there is no affordnace to
15085     * press the on-screen buttons, we shouldn't show the dialog.
15086     *
15087     * A thought: SystemUI might also want to get told about this, the Power
15088     * dialog / global actions also might want different behaviors.
15089     */
15090    private static final boolean shouldShowDialogs(Configuration config) {
15091        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15092                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15093    }
15094
15095    /**
15096     * Save the locale.  You must be inside a synchronized (this) block.
15097     */
15098    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15099        if(isDiff) {
15100            SystemProperties.set("user.language", l.getLanguage());
15101            SystemProperties.set("user.region", l.getCountry());
15102        }
15103
15104        if(isPersist) {
15105            SystemProperties.set("persist.sys.language", l.getLanguage());
15106            SystemProperties.set("persist.sys.country", l.getCountry());
15107            SystemProperties.set("persist.sys.localevar", l.getVariant());
15108        }
15109    }
15110
15111    @Override
15112    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15113        ActivityRecord srec = ActivityRecord.forToken(token);
15114        return srec != null && srec.task.affinity != null &&
15115                srec.task.affinity.equals(destAffinity);
15116    }
15117
15118    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15119            Intent resultData) {
15120
15121        synchronized (this) {
15122            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15123            if (stack != null) {
15124                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15125            }
15126            return false;
15127        }
15128    }
15129
15130    public int getLaunchedFromUid(IBinder activityToken) {
15131        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15132        if (srec == null) {
15133            return -1;
15134        }
15135        return srec.launchedFromUid;
15136    }
15137
15138    public String getLaunchedFromPackage(IBinder activityToken) {
15139        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15140        if (srec == null) {
15141            return null;
15142        }
15143        return srec.launchedFromPackage;
15144    }
15145
15146    // =========================================================
15147    // LIFETIME MANAGEMENT
15148    // =========================================================
15149
15150    // Returns which broadcast queue the app is the current [or imminent] receiver
15151    // on, or 'null' if the app is not an active broadcast recipient.
15152    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15153        BroadcastRecord r = app.curReceiver;
15154        if (r != null) {
15155            return r.queue;
15156        }
15157
15158        // It's not the current receiver, but it might be starting up to become one
15159        synchronized (this) {
15160            for (BroadcastQueue queue : mBroadcastQueues) {
15161                r = queue.mPendingBroadcast;
15162                if (r != null && r.curApp == app) {
15163                    // found it; report which queue it's in
15164                    return queue;
15165                }
15166            }
15167        }
15168
15169        return null;
15170    }
15171
15172    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15173            boolean doingAll, long now) {
15174        if (mAdjSeq == app.adjSeq) {
15175            // This adjustment has already been computed.
15176            return app.curRawAdj;
15177        }
15178
15179        if (app.thread == null) {
15180            app.adjSeq = mAdjSeq;
15181            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15182            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15183            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15184        }
15185
15186        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15187        app.adjSource = null;
15188        app.adjTarget = null;
15189        app.empty = false;
15190        app.cached = false;
15191
15192        final int activitiesSize = app.activities.size();
15193
15194        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15195            // The max adjustment doesn't allow this app to be anything
15196            // below foreground, so it is not worth doing work for it.
15197            app.adjType = "fixed";
15198            app.adjSeq = mAdjSeq;
15199            app.curRawAdj = app.maxAdj;
15200            app.foregroundActivities = false;
15201            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15202            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15203            // System processes can do UI, and when they do we want to have
15204            // them trim their memory after the user leaves the UI.  To
15205            // facilitate this, here we need to determine whether or not it
15206            // is currently showing UI.
15207            app.systemNoUi = true;
15208            if (app == TOP_APP) {
15209                app.systemNoUi = false;
15210            } else if (activitiesSize > 0) {
15211                for (int j = 0; j < activitiesSize; j++) {
15212                    final ActivityRecord r = app.activities.get(j);
15213                    if (r.visible) {
15214                        app.systemNoUi = false;
15215                    }
15216                }
15217            }
15218            if (!app.systemNoUi) {
15219                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15220            }
15221            return (app.curAdj=app.maxAdj);
15222        }
15223
15224        app.systemNoUi = false;
15225
15226        // Determine the importance of the process, starting with most
15227        // important to least, and assign an appropriate OOM adjustment.
15228        int adj;
15229        int schedGroup;
15230        int procState;
15231        boolean foregroundActivities = false;
15232        BroadcastQueue queue;
15233        if (app == TOP_APP) {
15234            // The last app on the list is the foreground app.
15235            adj = ProcessList.FOREGROUND_APP_ADJ;
15236            schedGroup = Process.THREAD_GROUP_DEFAULT;
15237            app.adjType = "top-activity";
15238            foregroundActivities = true;
15239            procState = ActivityManager.PROCESS_STATE_TOP;
15240        } else if (app.instrumentationClass != null) {
15241            // Don't want to kill running instrumentation.
15242            adj = ProcessList.FOREGROUND_APP_ADJ;
15243            schedGroup = Process.THREAD_GROUP_DEFAULT;
15244            app.adjType = "instrumentation";
15245            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15246        } else if ((queue = isReceivingBroadcast(app)) != null) {
15247            // An app that is currently receiving a broadcast also
15248            // counts as being in the foreground for OOM killer purposes.
15249            // It's placed in a sched group based on the nature of the
15250            // broadcast as reflected by which queue it's active in.
15251            adj = ProcessList.FOREGROUND_APP_ADJ;
15252            schedGroup = (queue == mFgBroadcastQueue)
15253                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15254            app.adjType = "broadcast";
15255            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15256        } else if (app.executingServices.size() > 0) {
15257            // An app that is currently executing a service callback also
15258            // counts as being in the foreground.
15259            adj = ProcessList.FOREGROUND_APP_ADJ;
15260            schedGroup = app.execServicesFg ?
15261                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15262            app.adjType = "exec-service";
15263            procState = ActivityManager.PROCESS_STATE_SERVICE;
15264            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15265        } else {
15266            // As far as we know the process is empty.  We may change our mind later.
15267            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15268            // At this point we don't actually know the adjustment.  Use the cached adj
15269            // value that the caller wants us to.
15270            adj = cachedAdj;
15271            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15272            app.cached = true;
15273            app.empty = true;
15274            app.adjType = "cch-empty";
15275        }
15276
15277        // Examine all activities if not already foreground.
15278        if (!foregroundActivities && activitiesSize > 0) {
15279            for (int j = 0; j < activitiesSize; j++) {
15280                final ActivityRecord r = app.activities.get(j);
15281                if (r.app != app) {
15282                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15283                            + app + "?!?");
15284                    continue;
15285                }
15286                if (r.visible) {
15287                    // App has a visible activity; only upgrade adjustment.
15288                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15289                        adj = ProcessList.VISIBLE_APP_ADJ;
15290                        app.adjType = "visible";
15291                    }
15292                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15293                        procState = ActivityManager.PROCESS_STATE_TOP;
15294                    }
15295                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15296                    app.cached = false;
15297                    app.empty = false;
15298                    foregroundActivities = true;
15299                    break;
15300                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15301                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15302                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15303                        app.adjType = "pausing";
15304                    }
15305                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15306                        procState = ActivityManager.PROCESS_STATE_TOP;
15307                    }
15308                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15309                    app.cached = false;
15310                    app.empty = false;
15311                    foregroundActivities = true;
15312                } else if (r.state == ActivityState.STOPPING) {
15313                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15314                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15315                        app.adjType = "stopping";
15316                    }
15317                    // For the process state, we will at this point consider the
15318                    // process to be cached.  It will be cached either as an activity
15319                    // or empty depending on whether the activity is finishing.  We do
15320                    // this so that we can treat the process as cached for purposes of
15321                    // memory trimming (determing current memory level, trim command to
15322                    // send to process) since there can be an arbitrary number of stopping
15323                    // processes and they should soon all go into the cached state.
15324                    if (!r.finishing) {
15325                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15326                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15327                        }
15328                    }
15329                    app.cached = false;
15330                    app.empty = false;
15331                    foregroundActivities = true;
15332                } else {
15333                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15334                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15335                        app.adjType = "cch-act";
15336                    }
15337                }
15338            }
15339        }
15340
15341        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15342            if (app.foregroundServices) {
15343                // The user is aware of this app, so make it visible.
15344                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15345                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15346                app.cached = false;
15347                app.adjType = "fg-service";
15348                schedGroup = Process.THREAD_GROUP_DEFAULT;
15349            } else if (app.forcingToForeground != null) {
15350                // The user is aware of this app, so make it visible.
15351                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15352                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15353                app.cached = false;
15354                app.adjType = "force-fg";
15355                app.adjSource = app.forcingToForeground;
15356                schedGroup = Process.THREAD_GROUP_DEFAULT;
15357            }
15358        }
15359
15360        if (app == mHeavyWeightProcess) {
15361            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15362                // We don't want to kill the current heavy-weight process.
15363                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15364                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15365                app.cached = false;
15366                app.adjType = "heavy";
15367            }
15368            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15369                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15370            }
15371        }
15372
15373        if (app == mHomeProcess) {
15374            if (adj > ProcessList.HOME_APP_ADJ) {
15375                // This process is hosting what we currently consider to be the
15376                // home app, so we don't want to let it go into the background.
15377                adj = ProcessList.HOME_APP_ADJ;
15378                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15379                app.cached = false;
15380                app.adjType = "home";
15381            }
15382            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15383                procState = ActivityManager.PROCESS_STATE_HOME;
15384            }
15385        }
15386
15387        if (app == mPreviousProcess && app.activities.size() > 0) {
15388            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15389                // This was the previous process that showed UI to the user.
15390                // We want to try to keep it around more aggressively, to give
15391                // a good experience around switching between two apps.
15392                adj = ProcessList.PREVIOUS_APP_ADJ;
15393                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15394                app.cached = false;
15395                app.adjType = "previous";
15396            }
15397            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15398                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15399            }
15400        }
15401
15402        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15403                + " reason=" + app.adjType);
15404
15405        // By default, we use the computed adjustment.  It may be changed if
15406        // there are applications dependent on our services or providers, but
15407        // this gives us a baseline and makes sure we don't get into an
15408        // infinite recursion.
15409        app.adjSeq = mAdjSeq;
15410        app.curRawAdj = adj;
15411        app.hasStartedServices = false;
15412
15413        if (mBackupTarget != null && app == mBackupTarget.app) {
15414            // If possible we want to avoid killing apps while they're being backed up
15415            if (adj > ProcessList.BACKUP_APP_ADJ) {
15416                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15417                adj = ProcessList.BACKUP_APP_ADJ;
15418                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15419                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15420                }
15421                app.adjType = "backup";
15422                app.cached = false;
15423            }
15424            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15425                procState = ActivityManager.PROCESS_STATE_BACKUP;
15426            }
15427        }
15428
15429        boolean mayBeTop = false;
15430
15431        for (int is = app.services.size()-1;
15432                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15433                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15434                        || procState > ActivityManager.PROCESS_STATE_TOP);
15435                is--) {
15436            ServiceRecord s = app.services.valueAt(is);
15437            if (s.startRequested) {
15438                app.hasStartedServices = true;
15439                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15440                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15441                }
15442                if (app.hasShownUi && app != mHomeProcess) {
15443                    // If this process has shown some UI, let it immediately
15444                    // go to the LRU list because it may be pretty heavy with
15445                    // UI stuff.  We'll tag it with a label just to help
15446                    // debug and understand what is going on.
15447                    if (adj > ProcessList.SERVICE_ADJ) {
15448                        app.adjType = "cch-started-ui-services";
15449                    }
15450                } else {
15451                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15452                        // This service has seen some activity within
15453                        // recent memory, so we will keep its process ahead
15454                        // of the background processes.
15455                        if (adj > ProcessList.SERVICE_ADJ) {
15456                            adj = ProcessList.SERVICE_ADJ;
15457                            app.adjType = "started-services";
15458                            app.cached = false;
15459                        }
15460                    }
15461                    // If we have let the service slide into the background
15462                    // state, still have some text describing what it is doing
15463                    // even though the service no longer has an impact.
15464                    if (adj > ProcessList.SERVICE_ADJ) {
15465                        app.adjType = "cch-started-services";
15466                    }
15467                }
15468            }
15469            for (int conni = s.connections.size()-1;
15470                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15471                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15472                            || procState > ActivityManager.PROCESS_STATE_TOP);
15473                    conni--) {
15474                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15475                for (int i = 0;
15476                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15477                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15478                                || procState > ActivityManager.PROCESS_STATE_TOP);
15479                        i++) {
15480                    // XXX should compute this based on the max of
15481                    // all connected clients.
15482                    ConnectionRecord cr = clist.get(i);
15483                    if (cr.binding.client == app) {
15484                        // Binding to ourself is not interesting.
15485                        continue;
15486                    }
15487                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15488                        ProcessRecord client = cr.binding.client;
15489                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15490                                TOP_APP, doingAll, now);
15491                        int clientProcState = client.curProcState;
15492                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15493                            // If the other app is cached for any reason, for purposes here
15494                            // we are going to consider it empty.  The specific cached state
15495                            // doesn't propagate except under certain conditions.
15496                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15497                        }
15498                        String adjType = null;
15499                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15500                            // Not doing bind OOM management, so treat
15501                            // this guy more like a started service.
15502                            if (app.hasShownUi && app != mHomeProcess) {
15503                                // If this process has shown some UI, let it immediately
15504                                // go to the LRU list because it may be pretty heavy with
15505                                // UI stuff.  We'll tag it with a label just to help
15506                                // debug and understand what is going on.
15507                                if (adj > clientAdj) {
15508                                    adjType = "cch-bound-ui-services";
15509                                }
15510                                app.cached = false;
15511                                clientAdj = adj;
15512                                clientProcState = procState;
15513                            } else {
15514                                if (now >= (s.lastActivity
15515                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15516                                    // This service has not seen activity within
15517                                    // recent memory, so allow it to drop to the
15518                                    // LRU list if there is no other reason to keep
15519                                    // it around.  We'll also tag it with a label just
15520                                    // to help debug and undertand what is going on.
15521                                    if (adj > clientAdj) {
15522                                        adjType = "cch-bound-services";
15523                                    }
15524                                    clientAdj = adj;
15525                                }
15526                            }
15527                        }
15528                        if (adj > clientAdj) {
15529                            // If this process has recently shown UI, and
15530                            // the process that is binding to it is less
15531                            // important than being visible, then we don't
15532                            // care about the binding as much as we care
15533                            // about letting this process get into the LRU
15534                            // list to be killed and restarted if needed for
15535                            // memory.
15536                            if (app.hasShownUi && app != mHomeProcess
15537                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15538                                adjType = "cch-bound-ui-services";
15539                            } else {
15540                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15541                                        |Context.BIND_IMPORTANT)) != 0) {
15542                                    adj = clientAdj;
15543                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15544                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15545                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15546                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15547                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15548                                    adj = clientAdj;
15549                                } else {
15550                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15551                                        adj = ProcessList.VISIBLE_APP_ADJ;
15552                                    }
15553                                }
15554                                if (!client.cached) {
15555                                    app.cached = false;
15556                                }
15557                                adjType = "service";
15558                            }
15559                        }
15560                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15561                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15562                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15563                            }
15564                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15565                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15566                                    // Special handling of clients who are in the top state.
15567                                    // We *may* want to consider this process to be in the
15568                                    // top state as well, but only if there is not another
15569                                    // reason for it to be running.  Being on the top is a
15570                                    // special state, meaning you are specifically running
15571                                    // for the current top app.  If the process is already
15572                                    // running in the background for some other reason, it
15573                                    // is more important to continue considering it to be
15574                                    // in the background state.
15575                                    mayBeTop = true;
15576                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15577                                } else {
15578                                    // Special handling for above-top states (persistent
15579                                    // processes).  These should not bring the current process
15580                                    // into the top state, since they are not on top.  Instead
15581                                    // give them the best state after that.
15582                                    clientProcState =
15583                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15584                                }
15585                            }
15586                        } else {
15587                            if (clientProcState <
15588                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15589                                clientProcState =
15590                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15591                            }
15592                        }
15593                        if (procState > clientProcState) {
15594                            procState = clientProcState;
15595                        }
15596                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15597                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15598                            app.pendingUiClean = true;
15599                        }
15600                        if (adjType != null) {
15601                            app.adjType = adjType;
15602                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15603                                    .REASON_SERVICE_IN_USE;
15604                            app.adjSource = cr.binding.client;
15605                            app.adjSourceProcState = clientProcState;
15606                            app.adjTarget = s.name;
15607                        }
15608                    }
15609                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15610                        app.treatLikeActivity = true;
15611                    }
15612                    final ActivityRecord a = cr.activity;
15613                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15614                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15615                                (a.visible || a.state == ActivityState.RESUMED
15616                                 || a.state == ActivityState.PAUSING)) {
15617                            adj = ProcessList.FOREGROUND_APP_ADJ;
15618                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15619                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15620                            }
15621                            app.cached = false;
15622                            app.adjType = "service";
15623                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15624                                    .REASON_SERVICE_IN_USE;
15625                            app.adjSource = a;
15626                            app.adjSourceProcState = procState;
15627                            app.adjTarget = s.name;
15628                        }
15629                    }
15630                }
15631            }
15632        }
15633
15634        for (int provi = app.pubProviders.size()-1;
15635                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15636                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15637                        || procState > ActivityManager.PROCESS_STATE_TOP);
15638                provi--) {
15639            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15640            for (int i = cpr.connections.size()-1;
15641                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15642                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15643                            || procState > ActivityManager.PROCESS_STATE_TOP);
15644                    i--) {
15645                ContentProviderConnection conn = cpr.connections.get(i);
15646                ProcessRecord client = conn.client;
15647                if (client == app) {
15648                    // Being our own client is not interesting.
15649                    continue;
15650                }
15651                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15652                int clientProcState = client.curProcState;
15653                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15654                    // If the other app is cached for any reason, for purposes here
15655                    // we are going to consider it empty.
15656                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15657                }
15658                if (adj > clientAdj) {
15659                    if (app.hasShownUi && app != mHomeProcess
15660                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15661                        app.adjType = "cch-ui-provider";
15662                    } else {
15663                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15664                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15665                        app.adjType = "provider";
15666                    }
15667                    app.cached &= client.cached;
15668                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15669                            .REASON_PROVIDER_IN_USE;
15670                    app.adjSource = client;
15671                    app.adjSourceProcState = clientProcState;
15672                    app.adjTarget = cpr.name;
15673                }
15674                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15675                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15676                        // Special handling of clients who are in the top state.
15677                        // We *may* want to consider this process to be in the
15678                        // top state as well, but only if there is not another
15679                        // reason for it to be running.  Being on the top is a
15680                        // special state, meaning you are specifically running
15681                        // for the current top app.  If the process is already
15682                        // running in the background for some other reason, it
15683                        // is more important to continue considering it to be
15684                        // in the background state.
15685                        mayBeTop = true;
15686                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15687                    } else {
15688                        // Special handling for above-top states (persistent
15689                        // processes).  These should not bring the current process
15690                        // into the top state, since they are not on top.  Instead
15691                        // give them the best state after that.
15692                        clientProcState =
15693                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15694                    }
15695                }
15696                if (procState > clientProcState) {
15697                    procState = clientProcState;
15698                }
15699                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15700                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15701                }
15702            }
15703            // If the provider has external (non-framework) process
15704            // dependencies, ensure that its adjustment is at least
15705            // FOREGROUND_APP_ADJ.
15706            if (cpr.hasExternalProcessHandles()) {
15707                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15708                    adj = ProcessList.FOREGROUND_APP_ADJ;
15709                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15710                    app.cached = false;
15711                    app.adjType = "provider";
15712                    app.adjTarget = cpr.name;
15713                }
15714                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15715                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15716                }
15717            }
15718        }
15719
15720        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15721            // A client of one of our services or providers is in the top state.  We
15722            // *may* want to be in the top state, but not if we are already running in
15723            // the background for some other reason.  For the decision here, we are going
15724            // to pick out a few specific states that we want to remain in when a client
15725            // is top (states that tend to be longer-term) and otherwise allow it to go
15726            // to the top state.
15727            switch (procState) {
15728                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15729                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15730                case ActivityManager.PROCESS_STATE_SERVICE:
15731                    // These all are longer-term states, so pull them up to the top
15732                    // of the background states, but not all the way to the top state.
15733                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15734                    break;
15735                default:
15736                    // Otherwise, top is a better choice, so take it.
15737                    procState = ActivityManager.PROCESS_STATE_TOP;
15738                    break;
15739            }
15740        }
15741
15742        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15743            if (app.hasClientActivities) {
15744                // This is a cached process, but with client activities.  Mark it so.
15745                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15746                app.adjType = "cch-client-act";
15747            } else if (app.treatLikeActivity) {
15748                // This is a cached process, but somebody wants us to treat it like it has
15749                // an activity, okay!
15750                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15751                app.adjType = "cch-as-act";
15752            }
15753        }
15754
15755        if (adj == ProcessList.SERVICE_ADJ) {
15756            if (doingAll) {
15757                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15758                mNewNumServiceProcs++;
15759                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15760                if (!app.serviceb) {
15761                    // This service isn't far enough down on the LRU list to
15762                    // normally be a B service, but if we are low on RAM and it
15763                    // is large we want to force it down since we would prefer to
15764                    // keep launcher over it.
15765                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15766                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15767                        app.serviceHighRam = true;
15768                        app.serviceb = true;
15769                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15770                    } else {
15771                        mNewNumAServiceProcs++;
15772                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15773                    }
15774                } else {
15775                    app.serviceHighRam = false;
15776                }
15777            }
15778            if (app.serviceb) {
15779                adj = ProcessList.SERVICE_B_ADJ;
15780            }
15781        }
15782
15783        app.curRawAdj = adj;
15784
15785        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15786        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15787        if (adj > app.maxAdj) {
15788            adj = app.maxAdj;
15789            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15790                schedGroup = Process.THREAD_GROUP_DEFAULT;
15791            }
15792        }
15793
15794        // Do final modification to adj.  Everything we do between here and applying
15795        // the final setAdj must be done in this function, because we will also use
15796        // it when computing the final cached adj later.  Note that we don't need to
15797        // worry about this for max adj above, since max adj will always be used to
15798        // keep it out of the cached vaues.
15799        app.curAdj = app.modifyRawOomAdj(adj);
15800        app.curSchedGroup = schedGroup;
15801        app.curProcState = procState;
15802        app.foregroundActivities = foregroundActivities;
15803
15804        return app.curRawAdj;
15805    }
15806
15807    /**
15808     * Schedule PSS collection of a process.
15809     */
15810    void requestPssLocked(ProcessRecord proc, int procState) {
15811        if (mPendingPssProcesses.contains(proc)) {
15812            return;
15813        }
15814        if (mPendingPssProcesses.size() == 0) {
15815            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15816        }
15817        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15818        proc.pssProcState = procState;
15819        mPendingPssProcesses.add(proc);
15820    }
15821
15822    /**
15823     * Schedule PSS collection of all processes.
15824     */
15825    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15826        if (!always) {
15827            if (now < (mLastFullPssTime +
15828                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15829                return;
15830            }
15831        }
15832        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15833        mLastFullPssTime = now;
15834        mFullPssPending = true;
15835        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15836        mPendingPssProcesses.clear();
15837        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15838            ProcessRecord app = mLruProcesses.get(i);
15839            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15840                app.pssProcState = app.setProcState;
15841                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15842                        isSleeping(), now);
15843                mPendingPssProcesses.add(app);
15844            }
15845        }
15846        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15847    }
15848
15849    /**
15850     * Ask a given process to GC right now.
15851     */
15852    final void performAppGcLocked(ProcessRecord app) {
15853        try {
15854            app.lastRequestedGc = SystemClock.uptimeMillis();
15855            if (app.thread != null) {
15856                if (app.reportLowMemory) {
15857                    app.reportLowMemory = false;
15858                    app.thread.scheduleLowMemory();
15859                } else {
15860                    app.thread.processInBackground();
15861                }
15862            }
15863        } catch (Exception e) {
15864            // whatever.
15865        }
15866    }
15867
15868    /**
15869     * Returns true if things are idle enough to perform GCs.
15870     */
15871    private final boolean canGcNowLocked() {
15872        boolean processingBroadcasts = false;
15873        for (BroadcastQueue q : mBroadcastQueues) {
15874            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15875                processingBroadcasts = true;
15876            }
15877        }
15878        return !processingBroadcasts
15879                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15880    }
15881
15882    /**
15883     * Perform GCs on all processes that are waiting for it, but only
15884     * if things are idle.
15885     */
15886    final void performAppGcsLocked() {
15887        final int N = mProcessesToGc.size();
15888        if (N <= 0) {
15889            return;
15890        }
15891        if (canGcNowLocked()) {
15892            while (mProcessesToGc.size() > 0) {
15893                ProcessRecord proc = mProcessesToGc.remove(0);
15894                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15895                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15896                            <= SystemClock.uptimeMillis()) {
15897                        // To avoid spamming the system, we will GC processes one
15898                        // at a time, waiting a few seconds between each.
15899                        performAppGcLocked(proc);
15900                        scheduleAppGcsLocked();
15901                        return;
15902                    } else {
15903                        // It hasn't been long enough since we last GCed this
15904                        // process...  put it in the list to wait for its time.
15905                        addProcessToGcListLocked(proc);
15906                        break;
15907                    }
15908                }
15909            }
15910
15911            scheduleAppGcsLocked();
15912        }
15913    }
15914
15915    /**
15916     * If all looks good, perform GCs on all processes waiting for them.
15917     */
15918    final void performAppGcsIfAppropriateLocked() {
15919        if (canGcNowLocked()) {
15920            performAppGcsLocked();
15921            return;
15922        }
15923        // Still not idle, wait some more.
15924        scheduleAppGcsLocked();
15925    }
15926
15927    /**
15928     * Schedule the execution of all pending app GCs.
15929     */
15930    final void scheduleAppGcsLocked() {
15931        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15932
15933        if (mProcessesToGc.size() > 0) {
15934            // Schedule a GC for the time to the next process.
15935            ProcessRecord proc = mProcessesToGc.get(0);
15936            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15937
15938            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15939            long now = SystemClock.uptimeMillis();
15940            if (when < (now+GC_TIMEOUT)) {
15941                when = now + GC_TIMEOUT;
15942            }
15943            mHandler.sendMessageAtTime(msg, when);
15944        }
15945    }
15946
15947    /**
15948     * Add a process to the array of processes waiting to be GCed.  Keeps the
15949     * list in sorted order by the last GC time.  The process can't already be
15950     * on the list.
15951     */
15952    final void addProcessToGcListLocked(ProcessRecord proc) {
15953        boolean added = false;
15954        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15955            if (mProcessesToGc.get(i).lastRequestedGc <
15956                    proc.lastRequestedGc) {
15957                added = true;
15958                mProcessesToGc.add(i+1, proc);
15959                break;
15960            }
15961        }
15962        if (!added) {
15963            mProcessesToGc.add(0, proc);
15964        }
15965    }
15966
15967    /**
15968     * Set up to ask a process to GC itself.  This will either do it
15969     * immediately, or put it on the list of processes to gc the next
15970     * time things are idle.
15971     */
15972    final void scheduleAppGcLocked(ProcessRecord app) {
15973        long now = SystemClock.uptimeMillis();
15974        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15975            return;
15976        }
15977        if (!mProcessesToGc.contains(app)) {
15978            addProcessToGcListLocked(app);
15979            scheduleAppGcsLocked();
15980        }
15981    }
15982
15983    final void checkExcessivePowerUsageLocked(boolean doKills) {
15984        updateCpuStatsNow();
15985
15986        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15987        boolean doWakeKills = doKills;
15988        boolean doCpuKills = doKills;
15989        if (mLastPowerCheckRealtime == 0) {
15990            doWakeKills = false;
15991        }
15992        if (mLastPowerCheckUptime == 0) {
15993            doCpuKills = false;
15994        }
15995        if (stats.isScreenOn()) {
15996            doWakeKills = false;
15997        }
15998        final long curRealtime = SystemClock.elapsedRealtime();
15999        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16000        final long curUptime = SystemClock.uptimeMillis();
16001        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16002        mLastPowerCheckRealtime = curRealtime;
16003        mLastPowerCheckUptime = curUptime;
16004        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16005            doWakeKills = false;
16006        }
16007        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16008            doCpuKills = false;
16009        }
16010        int i = mLruProcesses.size();
16011        while (i > 0) {
16012            i--;
16013            ProcessRecord app = mLruProcesses.get(i);
16014            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16015                long wtime;
16016                synchronized (stats) {
16017                    wtime = stats.getProcessWakeTime(app.info.uid,
16018                            app.pid, curRealtime);
16019                }
16020                long wtimeUsed = wtime - app.lastWakeTime;
16021                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16022                if (DEBUG_POWER) {
16023                    StringBuilder sb = new StringBuilder(128);
16024                    sb.append("Wake for ");
16025                    app.toShortString(sb);
16026                    sb.append(": over ");
16027                    TimeUtils.formatDuration(realtimeSince, sb);
16028                    sb.append(" used ");
16029                    TimeUtils.formatDuration(wtimeUsed, sb);
16030                    sb.append(" (");
16031                    sb.append((wtimeUsed*100)/realtimeSince);
16032                    sb.append("%)");
16033                    Slog.i(TAG, sb.toString());
16034                    sb.setLength(0);
16035                    sb.append("CPU for ");
16036                    app.toShortString(sb);
16037                    sb.append(": over ");
16038                    TimeUtils.formatDuration(uptimeSince, sb);
16039                    sb.append(" used ");
16040                    TimeUtils.formatDuration(cputimeUsed, sb);
16041                    sb.append(" (");
16042                    sb.append((cputimeUsed*100)/uptimeSince);
16043                    sb.append("%)");
16044                    Slog.i(TAG, sb.toString());
16045                }
16046                // If a process has held a wake lock for more
16047                // than 50% of the time during this period,
16048                // that sounds bad.  Kill!
16049                if (doWakeKills && realtimeSince > 0
16050                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16051                    synchronized (stats) {
16052                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16053                                realtimeSince, wtimeUsed);
16054                    }
16055                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16056                            + " during " + realtimeSince);
16057                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16058                } else if (doCpuKills && uptimeSince > 0
16059                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16060                    synchronized (stats) {
16061                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16062                                uptimeSince, cputimeUsed);
16063                    }
16064                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16065                            + " during " + uptimeSince);
16066                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16067                } else {
16068                    app.lastWakeTime = wtime;
16069                    app.lastCpuTime = app.curCpuTime;
16070                }
16071            }
16072        }
16073    }
16074
16075    private final boolean applyOomAdjLocked(ProcessRecord app,
16076            ProcessRecord TOP_APP, boolean doingAll, long now) {
16077        boolean success = true;
16078
16079        if (app.curRawAdj != app.setRawAdj) {
16080            app.setRawAdj = app.curRawAdj;
16081        }
16082
16083        int changes = 0;
16084
16085        if (app.curAdj != app.setAdj) {
16086            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16087            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16088                TAG, "Set " + app.pid + " " + app.processName +
16089                " adj " + app.curAdj + ": " + app.adjType);
16090            app.setAdj = app.curAdj;
16091        }
16092
16093        if (app.setSchedGroup != app.curSchedGroup) {
16094            app.setSchedGroup = app.curSchedGroup;
16095            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16096                    "Setting process group of " + app.processName
16097                    + " to " + app.curSchedGroup);
16098            if (app.waitingToKill != null &&
16099                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16100                killUnneededProcessLocked(app, app.waitingToKill);
16101                success = false;
16102            } else {
16103                if (true) {
16104                    long oldId = Binder.clearCallingIdentity();
16105                    try {
16106                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16107                    } catch (Exception e) {
16108                        Slog.w(TAG, "Failed setting process group of " + app.pid
16109                                + " to " + app.curSchedGroup);
16110                        e.printStackTrace();
16111                    } finally {
16112                        Binder.restoreCallingIdentity(oldId);
16113                    }
16114                } else {
16115                    if (app.thread != null) {
16116                        try {
16117                            app.thread.setSchedulingGroup(app.curSchedGroup);
16118                        } catch (RemoteException e) {
16119                        }
16120                    }
16121                }
16122                Process.setSwappiness(app.pid,
16123                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16124            }
16125        }
16126        if (app.repForegroundActivities != app.foregroundActivities) {
16127            app.repForegroundActivities = app.foregroundActivities;
16128            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16129        }
16130        if (app.repProcState != app.curProcState) {
16131            app.repProcState = app.curProcState;
16132            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16133            if (app.thread != null) {
16134                try {
16135                    if (false) {
16136                        //RuntimeException h = new RuntimeException("here");
16137                        Slog.i(TAG, "Sending new process state " + app.repProcState
16138                                + " to " + app /*, h*/);
16139                    }
16140                    app.thread.setProcessState(app.repProcState);
16141                } catch (RemoteException e) {
16142                }
16143            }
16144        }
16145        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16146                app.setProcState)) {
16147            app.lastStateTime = now;
16148            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16149                    isSleeping(), now);
16150            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16151                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16152                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16153                    + (app.nextPssTime-now) + ": " + app);
16154        } else {
16155            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16156                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16157                requestPssLocked(app, app.setProcState);
16158                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16159                        isSleeping(), now);
16160            } else if (false && DEBUG_PSS) {
16161                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16162            }
16163        }
16164        if (app.setProcState != app.curProcState) {
16165            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16166                    "Proc state change of " + app.processName
16167                    + " to " + app.curProcState);
16168            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16169            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16170            if (setImportant && !curImportant) {
16171                // This app is no longer something we consider important enough to allow to
16172                // use arbitrary amounts of battery power.  Note
16173                // its current wake lock time to later know to kill it if
16174                // it is not behaving well.
16175                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16176                synchronized (stats) {
16177                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16178                            app.pid, SystemClock.elapsedRealtime());
16179                }
16180                app.lastCpuTime = app.curCpuTime;
16181
16182            }
16183            app.setProcState = app.curProcState;
16184            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16185                app.notCachedSinceIdle = false;
16186            }
16187            if (!doingAll) {
16188                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16189            } else {
16190                app.procStateChanged = true;
16191            }
16192        }
16193
16194        if (changes != 0) {
16195            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16196            int i = mPendingProcessChanges.size()-1;
16197            ProcessChangeItem item = null;
16198            while (i >= 0) {
16199                item = mPendingProcessChanges.get(i);
16200                if (item.pid == app.pid) {
16201                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16202                    break;
16203                }
16204                i--;
16205            }
16206            if (i < 0) {
16207                // No existing item in pending changes; need a new one.
16208                final int NA = mAvailProcessChanges.size();
16209                if (NA > 0) {
16210                    item = mAvailProcessChanges.remove(NA-1);
16211                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16212                } else {
16213                    item = new ProcessChangeItem();
16214                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16215                }
16216                item.changes = 0;
16217                item.pid = app.pid;
16218                item.uid = app.info.uid;
16219                if (mPendingProcessChanges.size() == 0) {
16220                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16221                            "*** Enqueueing dispatch processes changed!");
16222                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16223                }
16224                mPendingProcessChanges.add(item);
16225            }
16226            item.changes |= changes;
16227            item.processState = app.repProcState;
16228            item.foregroundActivities = app.repForegroundActivities;
16229            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16230                    + Integer.toHexString(System.identityHashCode(item))
16231                    + " " + app.toShortString() + ": changes=" + item.changes
16232                    + " procState=" + item.processState
16233                    + " foreground=" + item.foregroundActivities
16234                    + " type=" + app.adjType + " source=" + app.adjSource
16235                    + " target=" + app.adjTarget);
16236        }
16237
16238        return success;
16239    }
16240
16241    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16242        if (proc.thread != null) {
16243            if (proc.baseProcessTracker != null) {
16244                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16245            }
16246            if (proc.repProcState >= 0) {
16247                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16248                        proc.repProcState);
16249            }
16250        }
16251    }
16252
16253    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16254            ProcessRecord TOP_APP, boolean doingAll, long now) {
16255        if (app.thread == null) {
16256            return false;
16257        }
16258
16259        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16260
16261        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16262    }
16263
16264    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16265            boolean oomAdj) {
16266        if (isForeground != proc.foregroundServices) {
16267            proc.foregroundServices = isForeground;
16268            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16269                    proc.info.uid);
16270            if (isForeground) {
16271                if (curProcs == null) {
16272                    curProcs = new ArrayList<ProcessRecord>();
16273                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16274                }
16275                if (!curProcs.contains(proc)) {
16276                    curProcs.add(proc);
16277                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16278                            proc.info.packageName, proc.info.uid);
16279                }
16280            } else {
16281                if (curProcs != null) {
16282                    if (curProcs.remove(proc)) {
16283                        mBatteryStatsService.noteEvent(
16284                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16285                                proc.info.packageName, proc.info.uid);
16286                        if (curProcs.size() <= 0) {
16287                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16288                        }
16289                    }
16290                }
16291            }
16292            if (oomAdj) {
16293                updateOomAdjLocked();
16294            }
16295        }
16296    }
16297
16298    private final ActivityRecord resumedAppLocked() {
16299        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16300        String pkg;
16301        int uid;
16302        if (act != null) {
16303            pkg = act.packageName;
16304            uid = act.info.applicationInfo.uid;
16305        } else {
16306            pkg = null;
16307            uid = -1;
16308        }
16309        // Has the UID or resumed package name changed?
16310        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16311                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16312            if (mCurResumedPackage != null) {
16313                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16314                        mCurResumedPackage, mCurResumedUid);
16315            }
16316            mCurResumedPackage = pkg;
16317            mCurResumedUid = uid;
16318            if (mCurResumedPackage != null) {
16319                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16320                        mCurResumedPackage, mCurResumedUid);
16321            }
16322        }
16323        return act;
16324    }
16325
16326    final boolean updateOomAdjLocked(ProcessRecord app) {
16327        final ActivityRecord TOP_ACT = resumedAppLocked();
16328        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16329        final boolean wasCached = app.cached;
16330
16331        mAdjSeq++;
16332
16333        // This is the desired cached adjusment we want to tell it to use.
16334        // If our app is currently cached, we know it, and that is it.  Otherwise,
16335        // we don't know it yet, and it needs to now be cached we will then
16336        // need to do a complete oom adj.
16337        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16338                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16339        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16340                SystemClock.uptimeMillis());
16341        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16342            // Changed to/from cached state, so apps after it in the LRU
16343            // list may also be changed.
16344            updateOomAdjLocked();
16345        }
16346        return success;
16347    }
16348
16349    final void updateOomAdjLocked() {
16350        final ActivityRecord TOP_ACT = resumedAppLocked();
16351        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16352        final long now = SystemClock.uptimeMillis();
16353        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16354        final int N = mLruProcesses.size();
16355
16356        if (false) {
16357            RuntimeException e = new RuntimeException();
16358            e.fillInStackTrace();
16359            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16360        }
16361
16362        mAdjSeq++;
16363        mNewNumServiceProcs = 0;
16364        mNewNumAServiceProcs = 0;
16365
16366        final int emptyProcessLimit;
16367        final int cachedProcessLimit;
16368        if (mProcessLimit <= 0) {
16369            emptyProcessLimit = cachedProcessLimit = 0;
16370        } else if (mProcessLimit == 1) {
16371            emptyProcessLimit = 1;
16372            cachedProcessLimit = 0;
16373        } else {
16374            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16375            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16376        }
16377
16378        // Let's determine how many processes we have running vs.
16379        // how many slots we have for background processes; we may want
16380        // to put multiple processes in a slot of there are enough of
16381        // them.
16382        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16383                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16384        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16385        if (numEmptyProcs > cachedProcessLimit) {
16386            // If there are more empty processes than our limit on cached
16387            // processes, then use the cached process limit for the factor.
16388            // This ensures that the really old empty processes get pushed
16389            // down to the bottom, so if we are running low on memory we will
16390            // have a better chance at keeping around more cached processes
16391            // instead of a gazillion empty processes.
16392            numEmptyProcs = cachedProcessLimit;
16393        }
16394        int emptyFactor = numEmptyProcs/numSlots;
16395        if (emptyFactor < 1) emptyFactor = 1;
16396        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16397        if (cachedFactor < 1) cachedFactor = 1;
16398        int stepCached = 0;
16399        int stepEmpty = 0;
16400        int numCached = 0;
16401        int numEmpty = 0;
16402        int numTrimming = 0;
16403
16404        mNumNonCachedProcs = 0;
16405        mNumCachedHiddenProcs = 0;
16406
16407        // First update the OOM adjustment for each of the
16408        // application processes based on their current state.
16409        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16410        int nextCachedAdj = curCachedAdj+1;
16411        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16412        int nextEmptyAdj = curEmptyAdj+2;
16413        for (int i=N-1; i>=0; i--) {
16414            ProcessRecord app = mLruProcesses.get(i);
16415            if (!app.killedByAm && app.thread != null) {
16416                app.procStateChanged = false;
16417                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16418
16419                // If we haven't yet assigned the final cached adj
16420                // to the process, do that now.
16421                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16422                    switch (app.curProcState) {
16423                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16424                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16425                            // This process is a cached process holding activities...
16426                            // assign it the next cached value for that type, and then
16427                            // step that cached level.
16428                            app.curRawAdj = curCachedAdj;
16429                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16430                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16431                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16432                                    + ")");
16433                            if (curCachedAdj != nextCachedAdj) {
16434                                stepCached++;
16435                                if (stepCached >= cachedFactor) {
16436                                    stepCached = 0;
16437                                    curCachedAdj = nextCachedAdj;
16438                                    nextCachedAdj += 2;
16439                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16440                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16441                                    }
16442                                }
16443                            }
16444                            break;
16445                        default:
16446                            // For everything else, assign next empty cached process
16447                            // level and bump that up.  Note that this means that
16448                            // long-running services that have dropped down to the
16449                            // cached level will be treated as empty (since their process
16450                            // state is still as a service), which is what we want.
16451                            app.curRawAdj = curEmptyAdj;
16452                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16453                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16454                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16455                                    + ")");
16456                            if (curEmptyAdj != nextEmptyAdj) {
16457                                stepEmpty++;
16458                                if (stepEmpty >= emptyFactor) {
16459                                    stepEmpty = 0;
16460                                    curEmptyAdj = nextEmptyAdj;
16461                                    nextEmptyAdj += 2;
16462                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16463                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16464                                    }
16465                                }
16466                            }
16467                            break;
16468                    }
16469                }
16470
16471                applyOomAdjLocked(app, TOP_APP, true, now);
16472
16473                // Count the number of process types.
16474                switch (app.curProcState) {
16475                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16476                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16477                        mNumCachedHiddenProcs++;
16478                        numCached++;
16479                        if (numCached > cachedProcessLimit) {
16480                            killUnneededProcessLocked(app, "cached #" + numCached);
16481                        }
16482                        break;
16483                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16484                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16485                                && app.lastActivityTime < oldTime) {
16486                            killUnneededProcessLocked(app, "empty for "
16487                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16488                                    / 1000) + "s");
16489                        } else {
16490                            numEmpty++;
16491                            if (numEmpty > emptyProcessLimit) {
16492                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16493                            }
16494                        }
16495                        break;
16496                    default:
16497                        mNumNonCachedProcs++;
16498                        break;
16499                }
16500
16501                if (app.isolated && app.services.size() <= 0) {
16502                    // If this is an isolated process, and there are no
16503                    // services running in it, then the process is no longer
16504                    // needed.  We agressively kill these because we can by
16505                    // definition not re-use the same process again, and it is
16506                    // good to avoid having whatever code was running in them
16507                    // left sitting around after no longer needed.
16508                    killUnneededProcessLocked(app, "isolated not needed");
16509                }
16510
16511                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16512                        && !app.killedByAm) {
16513                    numTrimming++;
16514                }
16515            }
16516        }
16517
16518        mNumServiceProcs = mNewNumServiceProcs;
16519
16520        // Now determine the memory trimming level of background processes.
16521        // Unfortunately we need to start at the back of the list to do this
16522        // properly.  We only do this if the number of background apps we
16523        // are managing to keep around is less than half the maximum we desire;
16524        // if we are keeping a good number around, we'll let them use whatever
16525        // memory they want.
16526        final int numCachedAndEmpty = numCached + numEmpty;
16527        int memFactor;
16528        if (numCached <= ProcessList.TRIM_CACHED_APPS
16529                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16530            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16531                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16532            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16533                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16534            } else {
16535                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16536            }
16537        } else {
16538            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16539        }
16540        // We always allow the memory level to go up (better).  We only allow it to go
16541        // down if we are in a state where that is allowed, *and* the total number of processes
16542        // has gone down since last time.
16543        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16544                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16545                + " last=" + mLastNumProcesses);
16546        if (memFactor > mLastMemoryLevel) {
16547            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16548                memFactor = mLastMemoryLevel;
16549                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16550            }
16551        }
16552        mLastMemoryLevel = memFactor;
16553        mLastNumProcesses = mLruProcesses.size();
16554        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16555        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16556        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16557            if (mLowRamStartTime == 0) {
16558                mLowRamStartTime = now;
16559            }
16560            int step = 0;
16561            int fgTrimLevel;
16562            switch (memFactor) {
16563                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16564                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16565                    break;
16566                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16567                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16568                    break;
16569                default:
16570                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16571                    break;
16572            }
16573            int factor = numTrimming/3;
16574            int minFactor = 2;
16575            if (mHomeProcess != null) minFactor++;
16576            if (mPreviousProcess != null) minFactor++;
16577            if (factor < minFactor) factor = minFactor;
16578            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16579            for (int i=N-1; i>=0; i--) {
16580                ProcessRecord app = mLruProcesses.get(i);
16581                if (allChanged || app.procStateChanged) {
16582                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16583                    app.procStateChanged = false;
16584                }
16585                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16586                        && !app.killedByAm) {
16587                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16588                        try {
16589                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16590                                    "Trimming memory of " + app.processName
16591                                    + " to " + curLevel);
16592                            app.thread.scheduleTrimMemory(curLevel);
16593                        } catch (RemoteException e) {
16594                        }
16595                        if (false) {
16596                            // For now we won't do this; our memory trimming seems
16597                            // to be good enough at this point that destroying
16598                            // activities causes more harm than good.
16599                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16600                                    && app != mHomeProcess && app != mPreviousProcess) {
16601                                // Need to do this on its own message because the stack may not
16602                                // be in a consistent state at this point.
16603                                // For these apps we will also finish their activities
16604                                // to help them free memory.
16605                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16606                            }
16607                        }
16608                    }
16609                    app.trimMemoryLevel = curLevel;
16610                    step++;
16611                    if (step >= factor) {
16612                        step = 0;
16613                        switch (curLevel) {
16614                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16615                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16616                                break;
16617                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16618                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16619                                break;
16620                        }
16621                    }
16622                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16623                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16624                            && app.thread != null) {
16625                        try {
16626                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16627                                    "Trimming memory of heavy-weight " + app.processName
16628                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16629                            app.thread.scheduleTrimMemory(
16630                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16631                        } catch (RemoteException e) {
16632                        }
16633                    }
16634                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16635                } else {
16636                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16637                            || app.systemNoUi) && app.pendingUiClean) {
16638                        // If this application is now in the background and it
16639                        // had done UI, then give it the special trim level to
16640                        // have it free UI resources.
16641                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16642                        if (app.trimMemoryLevel < level && app.thread != null) {
16643                            try {
16644                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16645                                        "Trimming memory of bg-ui " + app.processName
16646                                        + " to " + level);
16647                                app.thread.scheduleTrimMemory(level);
16648                            } catch (RemoteException e) {
16649                            }
16650                        }
16651                        app.pendingUiClean = false;
16652                    }
16653                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16654                        try {
16655                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16656                                    "Trimming memory of fg " + app.processName
16657                                    + " to " + fgTrimLevel);
16658                            app.thread.scheduleTrimMemory(fgTrimLevel);
16659                        } catch (RemoteException e) {
16660                        }
16661                    }
16662                    app.trimMemoryLevel = fgTrimLevel;
16663                }
16664            }
16665        } else {
16666            if (mLowRamStartTime != 0) {
16667                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16668                mLowRamStartTime = 0;
16669            }
16670            for (int i=N-1; i>=0; i--) {
16671                ProcessRecord app = mLruProcesses.get(i);
16672                if (allChanged || app.procStateChanged) {
16673                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16674                    app.procStateChanged = false;
16675                }
16676                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16677                        || app.systemNoUi) && app.pendingUiClean) {
16678                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16679                            && app.thread != null) {
16680                        try {
16681                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16682                                    "Trimming memory of ui hidden " + app.processName
16683                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16684                            app.thread.scheduleTrimMemory(
16685                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16686                        } catch (RemoteException e) {
16687                        }
16688                    }
16689                    app.pendingUiClean = false;
16690                }
16691                app.trimMemoryLevel = 0;
16692            }
16693        }
16694
16695        if (mAlwaysFinishActivities) {
16696            // Need to do this on its own message because the stack may not
16697            // be in a consistent state at this point.
16698            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16699        }
16700
16701        if (allChanged) {
16702            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16703        }
16704
16705        if (mProcessStats.shouldWriteNowLocked(now)) {
16706            mHandler.post(new Runnable() {
16707                @Override public void run() {
16708                    synchronized (ActivityManagerService.this) {
16709                        mProcessStats.writeStateAsyncLocked();
16710                    }
16711                }
16712            });
16713        }
16714
16715        if (DEBUG_OOM_ADJ) {
16716            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16717        }
16718    }
16719
16720    final void trimApplications() {
16721        synchronized (this) {
16722            int i;
16723
16724            // First remove any unused application processes whose package
16725            // has been removed.
16726            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16727                final ProcessRecord app = mRemovedProcesses.get(i);
16728                if (app.activities.size() == 0
16729                        && app.curReceiver == null && app.services.size() == 0) {
16730                    Slog.i(
16731                        TAG, "Exiting empty application process "
16732                        + app.processName + " ("
16733                        + (app.thread != null ? app.thread.asBinder() : null)
16734                        + ")\n");
16735                    if (app.pid > 0 && app.pid != MY_PID) {
16736                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16737                                app.processName, app.setAdj, "empty");
16738                        app.killedByAm = true;
16739                        Process.killProcessQuiet(app.pid);
16740                        Process.killProcessGroup(app.info.uid, app.pid);
16741                    } else {
16742                        try {
16743                            app.thread.scheduleExit();
16744                        } catch (Exception e) {
16745                            // Ignore exceptions.
16746                        }
16747                    }
16748                    cleanUpApplicationRecordLocked(app, false, true, -1);
16749                    mRemovedProcesses.remove(i);
16750
16751                    if (app.persistent) {
16752                        addAppLocked(app.info, false, null /* ABI override */);
16753                    }
16754                }
16755            }
16756
16757            // Now update the oom adj for all processes.
16758            updateOomAdjLocked();
16759        }
16760    }
16761
16762    /** This method sends the specified signal to each of the persistent apps */
16763    public void signalPersistentProcesses(int sig) throws RemoteException {
16764        if (sig != Process.SIGNAL_USR1) {
16765            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16766        }
16767
16768        synchronized (this) {
16769            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16770                    != PackageManager.PERMISSION_GRANTED) {
16771                throw new SecurityException("Requires permission "
16772                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16773            }
16774
16775            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16776                ProcessRecord r = mLruProcesses.get(i);
16777                if (r.thread != null && r.persistent) {
16778                    Process.sendSignal(r.pid, sig);
16779                }
16780            }
16781        }
16782    }
16783
16784    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16785        if (proc == null || proc == mProfileProc) {
16786            proc = mProfileProc;
16787            path = mProfileFile;
16788            profileType = mProfileType;
16789            clearProfilerLocked();
16790        }
16791        if (proc == null) {
16792            return;
16793        }
16794        try {
16795            proc.thread.profilerControl(false, path, null, profileType);
16796        } catch (RemoteException e) {
16797            throw new IllegalStateException("Process disappeared");
16798        }
16799    }
16800
16801    private void clearProfilerLocked() {
16802        if (mProfileFd != null) {
16803            try {
16804                mProfileFd.close();
16805            } catch (IOException e) {
16806            }
16807        }
16808        mProfileApp = null;
16809        mProfileProc = null;
16810        mProfileFile = null;
16811        mProfileType = 0;
16812        mAutoStopProfiler = false;
16813    }
16814
16815    public boolean profileControl(String process, int userId, boolean start,
16816            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16817
16818        try {
16819            synchronized (this) {
16820                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16821                // its own permission.
16822                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16823                        != PackageManager.PERMISSION_GRANTED) {
16824                    throw new SecurityException("Requires permission "
16825                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16826                }
16827
16828                if (start && fd == null) {
16829                    throw new IllegalArgumentException("null fd");
16830                }
16831
16832                ProcessRecord proc = null;
16833                if (process != null) {
16834                    proc = findProcessLocked(process, userId, "profileControl");
16835                }
16836
16837                if (start && (proc == null || proc.thread == null)) {
16838                    throw new IllegalArgumentException("Unknown process: " + process);
16839                }
16840
16841                if (start) {
16842                    stopProfilerLocked(null, null, 0);
16843                    setProfileApp(proc.info, proc.processName, path, fd, false);
16844                    mProfileProc = proc;
16845                    mProfileType = profileType;
16846                    try {
16847                        fd = fd.dup();
16848                    } catch (IOException e) {
16849                        fd = null;
16850                    }
16851                    proc.thread.profilerControl(start, path, fd, profileType);
16852                    fd = null;
16853                    mProfileFd = null;
16854                } else {
16855                    stopProfilerLocked(proc, path, profileType);
16856                    if (fd != null) {
16857                        try {
16858                            fd.close();
16859                        } catch (IOException e) {
16860                        }
16861                    }
16862                }
16863
16864                return true;
16865            }
16866        } catch (RemoteException e) {
16867            throw new IllegalStateException("Process disappeared");
16868        } finally {
16869            if (fd != null) {
16870                try {
16871                    fd.close();
16872                } catch (IOException e) {
16873                }
16874            }
16875        }
16876    }
16877
16878    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16879        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16880                userId, true, ALLOW_FULL_ONLY, callName, null);
16881        ProcessRecord proc = null;
16882        try {
16883            int pid = Integer.parseInt(process);
16884            synchronized (mPidsSelfLocked) {
16885                proc = mPidsSelfLocked.get(pid);
16886            }
16887        } catch (NumberFormatException e) {
16888        }
16889
16890        if (proc == null) {
16891            ArrayMap<String, SparseArray<ProcessRecord>> all
16892                    = mProcessNames.getMap();
16893            SparseArray<ProcessRecord> procs = all.get(process);
16894            if (procs != null && procs.size() > 0) {
16895                proc = procs.valueAt(0);
16896                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16897                    for (int i=1; i<procs.size(); i++) {
16898                        ProcessRecord thisProc = procs.valueAt(i);
16899                        if (thisProc.userId == userId) {
16900                            proc = thisProc;
16901                            break;
16902                        }
16903                    }
16904                }
16905            }
16906        }
16907
16908        return proc;
16909    }
16910
16911    public boolean dumpHeap(String process, int userId, boolean managed,
16912            String path, ParcelFileDescriptor fd) throws RemoteException {
16913
16914        try {
16915            synchronized (this) {
16916                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16917                // its own permission (same as profileControl).
16918                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16919                        != PackageManager.PERMISSION_GRANTED) {
16920                    throw new SecurityException("Requires permission "
16921                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16922                }
16923
16924                if (fd == null) {
16925                    throw new IllegalArgumentException("null fd");
16926                }
16927
16928                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16929                if (proc == null || proc.thread == null) {
16930                    throw new IllegalArgumentException("Unknown process: " + process);
16931                }
16932
16933                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16934                if (!isDebuggable) {
16935                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16936                        throw new SecurityException("Process not debuggable: " + proc);
16937                    }
16938                }
16939
16940                proc.thread.dumpHeap(managed, path, fd);
16941                fd = null;
16942                return true;
16943            }
16944        } catch (RemoteException e) {
16945            throw new IllegalStateException("Process disappeared");
16946        } finally {
16947            if (fd != null) {
16948                try {
16949                    fd.close();
16950                } catch (IOException e) {
16951                }
16952            }
16953        }
16954    }
16955
16956    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16957    public void monitor() {
16958        synchronized (this) { }
16959    }
16960
16961    void onCoreSettingsChange(Bundle settings) {
16962        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16963            ProcessRecord processRecord = mLruProcesses.get(i);
16964            try {
16965                if (processRecord.thread != null) {
16966                    processRecord.thread.setCoreSettings(settings);
16967                }
16968            } catch (RemoteException re) {
16969                /* ignore */
16970            }
16971        }
16972    }
16973
16974    // Multi-user methods
16975
16976    /**
16977     * Start user, if its not already running, but don't bring it to foreground.
16978     */
16979    @Override
16980    public boolean startUserInBackground(final int userId) {
16981        return startUser(userId, /* foreground */ false);
16982    }
16983
16984    /**
16985     * Refreshes the list of users related to the current user when either a
16986     * user switch happens or when a new related user is started in the
16987     * background.
16988     */
16989    private void updateCurrentProfileIdsLocked() {
16990        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16991                mCurrentUserId, false /* enabledOnly */);
16992        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16993        for (int i = 0; i < currentProfileIds.length; i++) {
16994            currentProfileIds[i] = profiles.get(i).id;
16995        }
16996        mCurrentProfileIds = currentProfileIds;
16997
16998        synchronized (mUserProfileGroupIdsSelfLocked) {
16999            mUserProfileGroupIdsSelfLocked.clear();
17000            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17001            for (int i = 0; i < users.size(); i++) {
17002                UserInfo user = users.get(i);
17003                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17004                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17005                }
17006            }
17007        }
17008    }
17009
17010    private Set getProfileIdsLocked(int userId) {
17011        Set userIds = new HashSet<Integer>();
17012        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17013                userId, false /* enabledOnly */);
17014        for (UserInfo user : profiles) {
17015            userIds.add(Integer.valueOf(user.id));
17016        }
17017        return userIds;
17018    }
17019
17020    @Override
17021    public boolean switchUser(final int userId) {
17022        return startUser(userId, /* foregound */ true);
17023    }
17024
17025    private boolean startUser(final int userId, boolean foreground) {
17026        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17027                != PackageManager.PERMISSION_GRANTED) {
17028            String msg = "Permission Denial: switchUser() from pid="
17029                    + Binder.getCallingPid()
17030                    + ", uid=" + Binder.getCallingUid()
17031                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17032            Slog.w(TAG, msg);
17033            throw new SecurityException(msg);
17034        }
17035
17036        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17037
17038        final long ident = Binder.clearCallingIdentity();
17039        try {
17040            synchronized (this) {
17041                final int oldUserId = mCurrentUserId;
17042                if (oldUserId == userId) {
17043                    return true;
17044                }
17045
17046                mStackSupervisor.setLockTaskModeLocked(null, false);
17047
17048                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17049                if (userInfo == null) {
17050                    Slog.w(TAG, "No user info for user #" + userId);
17051                    return false;
17052                }
17053
17054                if (foreground) {
17055                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17056                            R.anim.screen_user_enter);
17057                }
17058
17059                boolean needStart = false;
17060
17061                // If the user we are switching to is not currently started, then
17062                // we need to start it now.
17063                if (mStartedUsers.get(userId) == null) {
17064                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17065                    updateStartedUserArrayLocked();
17066                    needStart = true;
17067                }
17068
17069                final Integer userIdInt = Integer.valueOf(userId);
17070                mUserLru.remove(userIdInt);
17071                mUserLru.add(userIdInt);
17072
17073                if (foreground) {
17074                    mCurrentUserId = userId;
17075                    updateCurrentProfileIdsLocked();
17076                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17077                    // Once the internal notion of the active user has switched, we lock the device
17078                    // with the option to show the user switcher on the keyguard.
17079                    mWindowManager.lockNow(null);
17080                } else {
17081                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17082                    updateCurrentProfileIdsLocked();
17083                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17084                    mUserLru.remove(currentUserIdInt);
17085                    mUserLru.add(currentUserIdInt);
17086                }
17087
17088                final UserStartedState uss = mStartedUsers.get(userId);
17089
17090                // Make sure user is in the started state.  If it is currently
17091                // stopping, we need to knock that off.
17092                if (uss.mState == UserStartedState.STATE_STOPPING) {
17093                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17094                    // so we can just fairly silently bring the user back from
17095                    // the almost-dead.
17096                    uss.mState = UserStartedState.STATE_RUNNING;
17097                    updateStartedUserArrayLocked();
17098                    needStart = true;
17099                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17100                    // This means ACTION_SHUTDOWN has been sent, so we will
17101                    // need to treat this as a new boot of the user.
17102                    uss.mState = UserStartedState.STATE_BOOTING;
17103                    updateStartedUserArrayLocked();
17104                    needStart = true;
17105                }
17106
17107                if (uss.mState == UserStartedState.STATE_BOOTING) {
17108                    // Booting up a new user, need to tell system services about it.
17109                    // Note that this is on the same handler as scheduling of broadcasts,
17110                    // which is important because it needs to go first.
17111                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17112                }
17113
17114                if (foreground) {
17115                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17116                            oldUserId));
17117                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17118                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17119                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17120                            oldUserId, userId, uss));
17121                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17122                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17123                }
17124
17125                if (needStart) {
17126                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17127                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17128                            | Intent.FLAG_RECEIVER_FOREGROUND);
17129                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17130                    broadcastIntentLocked(null, null, intent,
17131                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17132                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17133                }
17134
17135                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17136                    if (userId != UserHandle.USER_OWNER) {
17137                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17138                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17139                        broadcastIntentLocked(null, null, intent, null,
17140                                new IIntentReceiver.Stub() {
17141                                    public void performReceive(Intent intent, int resultCode,
17142                                            String data, Bundle extras, boolean ordered,
17143                                            boolean sticky, int sendingUser) {
17144                                        userInitialized(uss, userId);
17145                                    }
17146                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17147                                true, false, MY_PID, Process.SYSTEM_UID,
17148                                userId);
17149                        uss.initializing = true;
17150                    } else {
17151                        getUserManagerLocked().makeInitialized(userInfo.id);
17152                    }
17153                }
17154
17155                if (foreground) {
17156                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17157                    if (homeInFront) {
17158                        startHomeActivityLocked(userId);
17159                    } else {
17160                        mStackSupervisor.resumeTopActivitiesLocked();
17161                    }
17162                    EventLogTags.writeAmSwitchUser(userId);
17163                    getUserManagerLocked().userForeground(userId);
17164                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17165                } else {
17166                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17167                }
17168
17169                if (needStart) {
17170                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17171                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17172                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17173                    broadcastIntentLocked(null, null, intent,
17174                            null, new IIntentReceiver.Stub() {
17175                                @Override
17176                                public void performReceive(Intent intent, int resultCode, String data,
17177                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17178                                        throws RemoteException {
17179                                }
17180                            }, 0, null, null,
17181                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17182                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17183                }
17184            }
17185        } finally {
17186            Binder.restoreCallingIdentity(ident);
17187        }
17188
17189        return true;
17190    }
17191
17192    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17193        long ident = Binder.clearCallingIdentity();
17194        try {
17195            Intent intent;
17196            if (oldUserId >= 0) {
17197                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17198                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17199                int count = profiles.size();
17200                for (int i = 0; i < count; i++) {
17201                    int profileUserId = profiles.get(i).id;
17202                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17203                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17204                            | Intent.FLAG_RECEIVER_FOREGROUND);
17205                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17206                    broadcastIntentLocked(null, null, intent,
17207                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17208                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17209                }
17210            }
17211            if (newUserId >= 0) {
17212                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17213                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17214                int count = profiles.size();
17215                for (int i = 0; i < count; i++) {
17216                    int profileUserId = profiles.get(i).id;
17217                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17218                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17219                            | Intent.FLAG_RECEIVER_FOREGROUND);
17220                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17221                    broadcastIntentLocked(null, null, intent,
17222                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17223                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17224                }
17225                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17226                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17227                        | Intent.FLAG_RECEIVER_FOREGROUND);
17228                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17229                broadcastIntentLocked(null, null, intent,
17230                        null, null, 0, null, null,
17231                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17232                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17233            }
17234        } finally {
17235            Binder.restoreCallingIdentity(ident);
17236        }
17237    }
17238
17239    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17240            final int newUserId) {
17241        final int N = mUserSwitchObservers.beginBroadcast();
17242        if (N > 0) {
17243            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17244                int mCount = 0;
17245                @Override
17246                public void sendResult(Bundle data) throws RemoteException {
17247                    synchronized (ActivityManagerService.this) {
17248                        if (mCurUserSwitchCallback == this) {
17249                            mCount++;
17250                            if (mCount == N) {
17251                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17252                            }
17253                        }
17254                    }
17255                }
17256            };
17257            synchronized (this) {
17258                uss.switching = true;
17259                mCurUserSwitchCallback = callback;
17260            }
17261            for (int i=0; i<N; i++) {
17262                try {
17263                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17264                            newUserId, callback);
17265                } catch (RemoteException e) {
17266                }
17267            }
17268        } else {
17269            synchronized (this) {
17270                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17271            }
17272        }
17273        mUserSwitchObservers.finishBroadcast();
17274    }
17275
17276    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17277        synchronized (this) {
17278            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17279            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17280        }
17281    }
17282
17283    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17284        mCurUserSwitchCallback = null;
17285        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17286        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17287                oldUserId, newUserId, uss));
17288    }
17289
17290    void userInitialized(UserStartedState uss, int newUserId) {
17291        completeSwitchAndInitalize(uss, newUserId, true, false);
17292    }
17293
17294    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17295        completeSwitchAndInitalize(uss, newUserId, false, true);
17296    }
17297
17298    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17299            boolean clearInitializing, boolean clearSwitching) {
17300        boolean unfrozen = false;
17301        synchronized (this) {
17302            if (clearInitializing) {
17303                uss.initializing = false;
17304                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17305            }
17306            if (clearSwitching) {
17307                uss.switching = false;
17308            }
17309            if (!uss.switching && !uss.initializing) {
17310                mWindowManager.stopFreezingScreen();
17311                unfrozen = true;
17312            }
17313        }
17314        if (unfrozen) {
17315            final int N = mUserSwitchObservers.beginBroadcast();
17316            for (int i=0; i<N; i++) {
17317                try {
17318                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17319                } catch (RemoteException e) {
17320                }
17321            }
17322            mUserSwitchObservers.finishBroadcast();
17323        }
17324    }
17325
17326    void scheduleStartProfilesLocked() {
17327        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17328            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17329                    DateUtils.SECOND_IN_MILLIS);
17330        }
17331    }
17332
17333    void startProfilesLocked() {
17334        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17335        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17336                mCurrentUserId, false /* enabledOnly */);
17337        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17338        for (UserInfo user : profiles) {
17339            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17340                    && user.id != mCurrentUserId) {
17341                toStart.add(user);
17342            }
17343        }
17344        final int n = toStart.size();
17345        int i = 0;
17346        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17347            startUserInBackground(toStart.get(i).id);
17348        }
17349        if (i < n) {
17350            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17351        }
17352    }
17353
17354    void finishUserBoot(UserStartedState uss) {
17355        synchronized (this) {
17356            if (uss.mState == UserStartedState.STATE_BOOTING
17357                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17358                uss.mState = UserStartedState.STATE_RUNNING;
17359                final int userId = uss.mHandle.getIdentifier();
17360                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17361                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17362                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17363                broadcastIntentLocked(null, null, intent,
17364                        null, null, 0, null, null,
17365                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17366                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17367            }
17368        }
17369    }
17370
17371    void finishUserSwitch(UserStartedState uss) {
17372        synchronized (this) {
17373            finishUserBoot(uss);
17374
17375            startProfilesLocked();
17376
17377            int num = mUserLru.size();
17378            int i = 0;
17379            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17380                Integer oldUserId = mUserLru.get(i);
17381                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17382                if (oldUss == null) {
17383                    // Shouldn't happen, but be sane if it does.
17384                    mUserLru.remove(i);
17385                    num--;
17386                    continue;
17387                }
17388                if (oldUss.mState == UserStartedState.STATE_STOPPING
17389                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17390                    // This user is already stopping, doesn't count.
17391                    num--;
17392                    i++;
17393                    continue;
17394                }
17395                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17396                    // Owner and current can't be stopped, but count as running.
17397                    i++;
17398                    continue;
17399                }
17400                // This is a user to be stopped.
17401                stopUserLocked(oldUserId, null);
17402                num--;
17403                i++;
17404            }
17405        }
17406    }
17407
17408    @Override
17409    public int stopUser(final int userId, final IStopUserCallback callback) {
17410        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17411                != PackageManager.PERMISSION_GRANTED) {
17412            String msg = "Permission Denial: switchUser() from pid="
17413                    + Binder.getCallingPid()
17414                    + ", uid=" + Binder.getCallingUid()
17415                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17416            Slog.w(TAG, msg);
17417            throw new SecurityException(msg);
17418        }
17419        if (userId <= 0) {
17420            throw new IllegalArgumentException("Can't stop primary user " + userId);
17421        }
17422        synchronized (this) {
17423            return stopUserLocked(userId, callback);
17424        }
17425    }
17426
17427    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17428        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17429        if (mCurrentUserId == userId) {
17430            return ActivityManager.USER_OP_IS_CURRENT;
17431        }
17432
17433        final UserStartedState uss = mStartedUsers.get(userId);
17434        if (uss == null) {
17435            // User is not started, nothing to do...  but we do need to
17436            // callback if requested.
17437            if (callback != null) {
17438                mHandler.post(new Runnable() {
17439                    @Override
17440                    public void run() {
17441                        try {
17442                            callback.userStopped(userId);
17443                        } catch (RemoteException e) {
17444                        }
17445                    }
17446                });
17447            }
17448            return ActivityManager.USER_OP_SUCCESS;
17449        }
17450
17451        if (callback != null) {
17452            uss.mStopCallbacks.add(callback);
17453        }
17454
17455        if (uss.mState != UserStartedState.STATE_STOPPING
17456                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17457            uss.mState = UserStartedState.STATE_STOPPING;
17458            updateStartedUserArrayLocked();
17459
17460            long ident = Binder.clearCallingIdentity();
17461            try {
17462                // We are going to broadcast ACTION_USER_STOPPING and then
17463                // once that is done send a final ACTION_SHUTDOWN and then
17464                // stop the user.
17465                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17466                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17467                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17468                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17469                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17470                // This is the result receiver for the final shutdown broadcast.
17471                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17472                    @Override
17473                    public void performReceive(Intent intent, int resultCode, String data,
17474                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17475                        finishUserStop(uss);
17476                    }
17477                };
17478                // This is the result receiver for the initial stopping broadcast.
17479                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17480                    @Override
17481                    public void performReceive(Intent intent, int resultCode, String data,
17482                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17483                        // On to the next.
17484                        synchronized (ActivityManagerService.this) {
17485                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17486                                // Whoops, we are being started back up.  Abort, abort!
17487                                return;
17488                            }
17489                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17490                        }
17491                        mBatteryStatsService.noteEvent(
17492                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17493                                Integer.toString(userId), userId);
17494                        mSystemServiceManager.stopUser(userId);
17495                        broadcastIntentLocked(null, null, shutdownIntent,
17496                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17497                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17498                    }
17499                };
17500                // Kick things off.
17501                broadcastIntentLocked(null, null, stoppingIntent,
17502                        null, stoppingReceiver, 0, null, null,
17503                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17504                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17505            } finally {
17506                Binder.restoreCallingIdentity(ident);
17507            }
17508        }
17509
17510        return ActivityManager.USER_OP_SUCCESS;
17511    }
17512
17513    void finishUserStop(UserStartedState uss) {
17514        final int userId = uss.mHandle.getIdentifier();
17515        boolean stopped;
17516        ArrayList<IStopUserCallback> callbacks;
17517        synchronized (this) {
17518            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17519            if (mStartedUsers.get(userId) != uss) {
17520                stopped = false;
17521            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17522                stopped = false;
17523            } else {
17524                stopped = true;
17525                // User can no longer run.
17526                mStartedUsers.remove(userId);
17527                mUserLru.remove(Integer.valueOf(userId));
17528                updateStartedUserArrayLocked();
17529
17530                // Clean up all state and processes associated with the user.
17531                // Kill all the processes for the user.
17532                forceStopUserLocked(userId, "finish user");
17533            }
17534        }
17535
17536        for (int i=0; i<callbacks.size(); i++) {
17537            try {
17538                if (stopped) callbacks.get(i).userStopped(userId);
17539                else callbacks.get(i).userStopAborted(userId);
17540            } catch (RemoteException e) {
17541            }
17542        }
17543
17544        if (stopped) {
17545            mSystemServiceManager.cleanupUser(userId);
17546            synchronized (this) {
17547                mStackSupervisor.removeUserLocked(userId);
17548            }
17549        }
17550    }
17551
17552    @Override
17553    public UserInfo getCurrentUser() {
17554        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17555                != PackageManager.PERMISSION_GRANTED) && (
17556                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17557                != PackageManager.PERMISSION_GRANTED)) {
17558            String msg = "Permission Denial: getCurrentUser() from pid="
17559                    + Binder.getCallingPid()
17560                    + ", uid=" + Binder.getCallingUid()
17561                    + " requires " + INTERACT_ACROSS_USERS;
17562            Slog.w(TAG, msg);
17563            throw new SecurityException(msg);
17564        }
17565        synchronized (this) {
17566            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17567        }
17568    }
17569
17570    int getCurrentUserIdLocked() {
17571        return mCurrentUserId;
17572    }
17573
17574    @Override
17575    public boolean isUserRunning(int userId, boolean orStopped) {
17576        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17577                != PackageManager.PERMISSION_GRANTED) {
17578            String msg = "Permission Denial: isUserRunning() from pid="
17579                    + Binder.getCallingPid()
17580                    + ", uid=" + Binder.getCallingUid()
17581                    + " requires " + INTERACT_ACROSS_USERS;
17582            Slog.w(TAG, msg);
17583            throw new SecurityException(msg);
17584        }
17585        synchronized (this) {
17586            return isUserRunningLocked(userId, orStopped);
17587        }
17588    }
17589
17590    boolean isUserRunningLocked(int userId, boolean orStopped) {
17591        UserStartedState state = mStartedUsers.get(userId);
17592        if (state == null) {
17593            return false;
17594        }
17595        if (orStopped) {
17596            return true;
17597        }
17598        return state.mState != UserStartedState.STATE_STOPPING
17599                && state.mState != UserStartedState.STATE_SHUTDOWN;
17600    }
17601
17602    @Override
17603    public int[] getRunningUserIds() {
17604        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17605                != PackageManager.PERMISSION_GRANTED) {
17606            String msg = "Permission Denial: isUserRunning() from pid="
17607                    + Binder.getCallingPid()
17608                    + ", uid=" + Binder.getCallingUid()
17609                    + " requires " + INTERACT_ACROSS_USERS;
17610            Slog.w(TAG, msg);
17611            throw new SecurityException(msg);
17612        }
17613        synchronized (this) {
17614            return mStartedUserArray;
17615        }
17616    }
17617
17618    private void updateStartedUserArrayLocked() {
17619        int num = 0;
17620        for (int i=0; i<mStartedUsers.size();  i++) {
17621            UserStartedState uss = mStartedUsers.valueAt(i);
17622            // This list does not include stopping users.
17623            if (uss.mState != UserStartedState.STATE_STOPPING
17624                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17625                num++;
17626            }
17627        }
17628        mStartedUserArray = new int[num];
17629        num = 0;
17630        for (int i=0; i<mStartedUsers.size();  i++) {
17631            UserStartedState uss = mStartedUsers.valueAt(i);
17632            if (uss.mState != UserStartedState.STATE_STOPPING
17633                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17634                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17635                num++;
17636            }
17637        }
17638    }
17639
17640    @Override
17641    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17642        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17643                != PackageManager.PERMISSION_GRANTED) {
17644            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17645                    + Binder.getCallingPid()
17646                    + ", uid=" + Binder.getCallingUid()
17647                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17648            Slog.w(TAG, msg);
17649            throw new SecurityException(msg);
17650        }
17651
17652        mUserSwitchObservers.register(observer);
17653    }
17654
17655    @Override
17656    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17657        mUserSwitchObservers.unregister(observer);
17658    }
17659
17660    private boolean userExists(int userId) {
17661        if (userId == 0) {
17662            return true;
17663        }
17664        UserManagerService ums = getUserManagerLocked();
17665        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17666    }
17667
17668    int[] getUsersLocked() {
17669        UserManagerService ums = getUserManagerLocked();
17670        return ums != null ? ums.getUserIds() : new int[] { 0 };
17671    }
17672
17673    UserManagerService getUserManagerLocked() {
17674        if (mUserManager == null) {
17675            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17676            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17677        }
17678        return mUserManager;
17679    }
17680
17681    private int applyUserId(int uid, int userId) {
17682        return UserHandle.getUid(userId, uid);
17683    }
17684
17685    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17686        if (info == null) return null;
17687        ApplicationInfo newInfo = new ApplicationInfo(info);
17688        newInfo.uid = applyUserId(info.uid, userId);
17689        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17690                + info.packageName;
17691        return newInfo;
17692    }
17693
17694    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17695        if (aInfo == null
17696                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17697            return aInfo;
17698        }
17699
17700        ActivityInfo info = new ActivityInfo(aInfo);
17701        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17702        return info;
17703    }
17704
17705    private final class LocalService extends ActivityManagerInternal {
17706        @Override
17707        public void goingToSleep() {
17708            ActivityManagerService.this.goingToSleep();
17709        }
17710
17711        @Override
17712        public void wakingUp() {
17713            ActivityManagerService.this.wakingUp();
17714        }
17715    }
17716
17717    /**
17718     * An implementation of IAppTask, that allows an app to manage its own tasks via
17719     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17720     * only the process that calls getAppTasks() can call the AppTask methods.
17721     */
17722    class AppTaskImpl extends IAppTask.Stub {
17723        private int mTaskId;
17724        private int mCallingUid;
17725
17726        public AppTaskImpl(int taskId, int callingUid) {
17727            mTaskId = taskId;
17728            mCallingUid = callingUid;
17729        }
17730
17731        @Override
17732        public void finishAndRemoveTask() {
17733            // Ensure that we are called from the same process that created this AppTask
17734            if (mCallingUid != Binder.getCallingUid()) {
17735                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17736                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17737                return;
17738            }
17739
17740            synchronized (ActivityManagerService.this) {
17741                long origId = Binder.clearCallingIdentity();
17742                try {
17743                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17744                    if (tr != null) {
17745                        // Only kill the process if we are not a new document
17746                        int flags = tr.getBaseIntent().getFlags();
17747                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17748                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17749                        removeTaskByIdLocked(mTaskId,
17750                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17751                    }
17752                } finally {
17753                    Binder.restoreCallingIdentity(origId);
17754                }
17755            }
17756        }
17757
17758        @Override
17759        public ActivityManager.RecentTaskInfo getTaskInfo() {
17760            // Ensure that we are called from the same process that created this AppTask
17761            if (mCallingUid != Binder.getCallingUid()) {
17762                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17763                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17764                return null;
17765            }
17766
17767            synchronized (ActivityManagerService.this) {
17768                long origId = Binder.clearCallingIdentity();
17769                try {
17770                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17771                    if (tr != null) {
17772                        return createRecentTaskInfoFromTaskRecord(tr);
17773                    }
17774                } finally {
17775                    Binder.restoreCallingIdentity(origId);
17776                }
17777                return null;
17778            }
17779        }
17780    }
17781}
17782