ActivityManagerService.java revision 3b3f464445d1d369c8e87f526deba606ca62f76c
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.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
28
29import android.app.AppOpsManager;
30import android.app.IActivityContainer;
31import android.app.IActivityContainerCallback;
32import android.appwidget.AppWidgetManager;
33import android.graphics.Rect;
34import android.os.BatteryStats;
35import android.util.ArrayMap;
36
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.os.Zygote;
47import com.android.internal.util.FastPrintWriter;
48import com.android.internal.util.FastXmlSerializer;
49import com.android.internal.util.MemInfoReader;
50import com.android.internal.util.Preconditions;
51import com.android.server.AppOpsService;
52import com.android.server.AttributeCache;
53import com.android.server.IntentResolver;
54import com.android.server.LocalServices;
55import com.android.server.ServiceThread;
56import com.android.server.SystemService;
57import com.android.server.Watchdog;
58import com.android.server.am.ActivityStack.ActivityState;
59import com.android.server.firewall.IntentFirewall;
60import com.android.server.pm.UserManagerService;
61import com.android.server.wm.AppTransition;
62import com.android.server.wm.WindowManagerService;
63import com.google.android.collect.Lists;
64import com.google.android.collect.Maps;
65
66import libcore.io.IoUtils;
67
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlPullParserException;
70import org.xmlpull.v1.XmlSerializer;
71
72import android.app.Activity;
73import android.app.ActivityManager;
74import android.app.ActivityManager.RunningTaskInfo;
75import android.app.ActivityManager.StackInfo;
76import android.app.ActivityManagerInternal;
77import android.app.ActivityManagerNative;
78import android.app.ActivityOptions;
79import android.app.ActivityThread;
80import android.app.AlertDialog;
81import android.app.AppGlobals;
82import android.app.ApplicationErrorReport;
83import android.app.Dialog;
84import android.app.IActivityController;
85import android.app.IApplicationThread;
86import android.app.IInstrumentationWatcher;
87import android.app.INotificationManager;
88import android.app.IProcessObserver;
89import android.app.IServiceConnection;
90import android.app.IStopUserCallback;
91import android.app.IThumbnailReceiver;
92import android.app.IUiAutomationConnection;
93import android.app.IUserSwitchObserver;
94import android.app.Instrumentation;
95import android.app.Notification;
96import android.app.NotificationManager;
97import android.app.PendingIntent;
98import android.app.backup.IBackupManager;
99import android.content.ActivityNotFoundException;
100import android.content.BroadcastReceiver;
101import android.content.ClipData;
102import android.content.ComponentCallbacks2;
103import android.content.ComponentName;
104import android.content.ContentProvider;
105import android.content.ContentResolver;
106import android.content.Context;
107import android.content.DialogInterface;
108import android.content.IContentProvider;
109import android.content.IIntentReceiver;
110import android.content.IIntentSender;
111import android.content.Intent;
112import android.content.IntentFilter;
113import android.content.IntentSender;
114import android.content.pm.ActivityInfo;
115import android.content.pm.ApplicationInfo;
116import android.content.pm.ConfigurationInfo;
117import android.content.pm.IPackageDataObserver;
118import android.content.pm.IPackageManager;
119import android.content.pm.InstrumentationInfo;
120import android.content.pm.PackageInfo;
121import android.content.pm.PackageManager;
122import android.content.pm.ParceledListSlice;
123import android.content.pm.UserInfo;
124import android.content.pm.PackageManager.NameNotFoundException;
125import android.content.pm.PathPermission;
126import android.content.pm.ProviderInfo;
127import android.content.pm.ResolveInfo;
128import android.content.pm.ServiceInfo;
129import android.content.res.CompatibilityInfo;
130import android.content.res.Configuration;
131import android.graphics.Bitmap;
132import android.net.Proxy;
133import android.net.ProxyProperties;
134import android.net.Uri;
135import android.os.Binder;
136import android.os.Build;
137import android.os.Bundle;
138import android.os.Debug;
139import android.os.DropBoxManager;
140import android.os.Environment;
141import android.os.FactoryTest;
142import android.os.FileObserver;
143import android.os.FileUtils;
144import android.os.Handler;
145import android.os.IBinder;
146import android.os.IPermissionController;
147import android.os.IRemoteCallback;
148import android.os.IUserManager;
149import android.os.Looper;
150import android.os.Message;
151import android.os.Parcel;
152import android.os.ParcelFileDescriptor;
153import android.os.Process;
154import android.os.RemoteCallbackList;
155import android.os.RemoteException;
156import android.os.SELinux;
157import android.os.ServiceManager;
158import android.os.StrictMode;
159import android.os.SystemClock;
160import android.os.SystemProperties;
161import android.os.UpdateLock;
162import android.os.UserHandle;
163import android.provider.Settings;
164import android.text.format.DateUtils;
165import android.text.format.Time;
166import android.util.AtomicFile;
167import android.util.EventLog;
168import android.util.Log;
169import android.util.Pair;
170import android.util.PrintWriterPrinter;
171import android.util.Slog;
172import android.util.SparseArray;
173import android.util.TimeUtils;
174import android.util.Xml;
175import android.view.Gravity;
176import android.view.LayoutInflater;
177import android.view.View;
178import android.view.WindowManager;
179
180import java.io.BufferedInputStream;
181import java.io.BufferedOutputStream;
182import java.io.DataInputStream;
183import java.io.DataOutputStream;
184import java.io.File;
185import java.io.FileDescriptor;
186import java.io.FileInputStream;
187import java.io.FileNotFoundException;
188import java.io.FileOutputStream;
189import java.io.IOException;
190import java.io.InputStreamReader;
191import java.io.PrintWriter;
192import java.io.StringWriter;
193import java.lang.ref.WeakReference;
194import java.util.ArrayList;
195import java.util.Arrays;
196import java.util.Collections;
197import java.util.Comparator;
198import java.util.HashMap;
199import java.util.HashSet;
200import java.util.Iterator;
201import java.util.List;
202import java.util.Locale;
203import java.util.Map;
204import java.util.Set;
205import java.util.concurrent.atomic.AtomicBoolean;
206import java.util.concurrent.atomic.AtomicLong;
207
208public final class ActivityManagerService extends ActivityManagerNative
209        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
210    private static final String USER_DATA_DIR = "/data/user/";
211    static final String TAG = "ActivityManager";
212    static final String TAG_MU = "ActivityManagerServiceMU";
213    static final boolean DEBUG = false;
214    static final boolean localLOGV = DEBUG;
215    static final boolean DEBUG_BACKUP = localLOGV || false;
216    static final boolean DEBUG_BROADCAST = localLOGV || false;
217    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
219    static final boolean DEBUG_CLEANUP = localLOGV || false;
220    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
221    static final boolean DEBUG_FOCUS = false;
222    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
223    static final boolean DEBUG_MU = localLOGV || false;
224    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
225    static final boolean DEBUG_LRU = localLOGV || false;
226    static final boolean DEBUG_PAUSE = localLOGV || false;
227    static final boolean DEBUG_POWER = localLOGV || false;
228    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
229    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
230    static final boolean DEBUG_PROCESSES = localLOGV || false;
231    static final boolean DEBUG_PROVIDER = localLOGV || false;
232    static final boolean DEBUG_RESULTS = localLOGV || false;
233    static final boolean DEBUG_SERVICE = localLOGV || false;
234    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
235    static final boolean DEBUG_STACK = localLOGV || false;
236    static final boolean DEBUG_SWITCH = localLOGV || false;
237    static final boolean DEBUG_TASKS = localLOGV || false;
238    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
239    static final boolean DEBUG_TRANSITION = localLOGV || false;
240    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
241    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
242    static final boolean DEBUG_VISBILITY = localLOGV || false;
243    static final boolean DEBUG_PSS = localLOGV || false;
244    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
245    static final boolean VALIDATE_TOKENS = false;
246    static final boolean SHOW_ACTIVITY_START_TIME = true;
247
248    // Control over CPU and battery monitoring.
249    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
250    static final boolean MONITOR_CPU_USAGE = true;
251    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
252    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
253    static final boolean MONITOR_THREAD_CPU_USAGE = false;
254
255    // The flags that are set for all calls we make to the package manager.
256    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
257
258    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
259
260    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
261
262    // Maximum number of recent tasks that we can remember.
263    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
264
265    // Amount of time after a call to stopAppSwitches() during which we will
266    // prevent further untrusted switches from happening.
267    static final long APP_SWITCH_DELAY_TIME = 5*1000;
268
269    // How long we wait for a launched process to attach to the activity manager
270    // before we decide it's never going to come up for real.
271    static final int PROC_START_TIMEOUT = 10*1000;
272
273    // How long we wait for a launched process to attach to the activity manager
274    // before we decide it's never going to come up for real, when the process was
275    // started with a wrapper for instrumentation (such as Valgrind) because it
276    // could take much longer than usual.
277    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
278
279    // How long to wait after going idle before forcing apps to GC.
280    static final int GC_TIMEOUT = 5*1000;
281
282    // The minimum amount of time between successive GC requests for a process.
283    static final int GC_MIN_INTERVAL = 60*1000;
284
285    // The minimum amount of time between successive PSS requests for a process.
286    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
287
288    // The minimum amount of time between successive PSS requests for a process
289    // when the request is due to the memory state being lowered.
290    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
291
292    // The rate at which we check for apps using excessive power -- 15 mins.
293    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
294
295    // The minimum sample duration we will allow before deciding we have
296    // enough data on wake locks to start killing things.
297    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
298
299    // The minimum sample duration we will allow before deciding we have
300    // enough data on CPU usage to start killing things.
301    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
302
303    // How long we allow a receiver to run before giving up on it.
304    static final int BROADCAST_FG_TIMEOUT = 10*1000;
305    static final int BROADCAST_BG_TIMEOUT = 60*1000;
306
307    // How long we wait until we timeout on key dispatching.
308    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
309
310    // How long we wait until we timeout on key dispatching during instrumentation.
311    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
312
313    // Amount of time we wait for observers to handle a user switch before
314    // giving up on them and unfreezing the screen.
315    static final int USER_SWITCH_TIMEOUT = 2*1000;
316
317    // Maximum number of users we allow to be running at a time.
318    static final int MAX_RUNNING_USERS = 3;
319
320    // How long to wait in getAssistContextExtras for the activity and foreground services
321    // to respond with the result.
322    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
323
324    // Maximum number of persisted Uri grants a package is allowed
325    static final int MAX_PERSISTED_URI_GRANTS = 128;
326
327    static final int MY_PID = Process.myPid();
328
329    static final String[] EMPTY_STRING_ARRAY = new String[0];
330
331    // How many bytes to write into the dropbox log before truncating
332    static final int DROPBOX_MAX_SIZE = 256 * 1024;
333
334    /** Run all ActivityStacks through this */
335    ActivityStackSupervisor mStackSupervisor;
336
337    public IntentFirewall mIntentFirewall;
338
339    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
340    // default actuion automatically.  Important for devices without direct input
341    // devices.
342    private boolean mShowDialogs = true;
343
344    /**
345     * Description of a request to start a new activity, which has been held
346     * due to app switches being disabled.
347     */
348    static class PendingActivityLaunch {
349        final ActivityRecord r;
350        final ActivityRecord sourceRecord;
351        final int startFlags;
352        final ActivityStack stack;
353
354        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
355                int _startFlags, ActivityStack _stack) {
356            r = _r;
357            sourceRecord = _sourceRecord;
358            startFlags = _startFlags;
359            stack = _stack;
360        }
361    }
362
363    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
364            = new ArrayList<PendingActivityLaunch>();
365
366    BroadcastQueue mFgBroadcastQueue;
367    BroadcastQueue mBgBroadcastQueue;
368    // Convenient for easy iteration over the queues. Foreground is first
369    // so that dispatch of foreground broadcasts gets precedence.
370    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
371
372    BroadcastQueue broadcastQueueForIntent(Intent intent) {
373        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
374        if (DEBUG_BACKGROUND_BROADCAST) {
375            Slog.i(TAG, "Broadcast intent " + intent + " on "
376                    + (isFg ? "foreground" : "background")
377                    + " queue");
378        }
379        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
380    }
381
382    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
383        for (BroadcastQueue queue : mBroadcastQueues) {
384            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
385            if (r != null) {
386                return r;
387            }
388        }
389        return null;
390    }
391
392    /**
393     * Activity we have told the window manager to have key focus.
394     */
395    ActivityRecord mFocusedActivity = null;
396
397    /**
398     * List of intents that were used to start the most recent tasks.
399     */
400    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
401
402    public class PendingAssistExtras extends Binder implements Runnable {
403        public final ActivityRecord activity;
404        public boolean haveResult = false;
405        public Bundle result = null;
406        public PendingAssistExtras(ActivityRecord _activity) {
407            activity = _activity;
408        }
409        @Override
410        public void run() {
411            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
412            synchronized (this) {
413                haveResult = true;
414                notifyAll();
415            }
416        }
417    }
418
419    final ArrayList<PendingAssistExtras> mPendingAssistExtras
420            = new ArrayList<PendingAssistExtras>();
421
422    /**
423     * Process management.
424     */
425    final ProcessList mProcessList = new ProcessList();
426
427    /**
428     * All of the applications we currently have running organized by name.
429     * The keys are strings of the application package name (as
430     * returned by the package manager), and the keys are ApplicationRecord
431     * objects.
432     */
433    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
434
435    /**
436     * Tracking long-term execution of processes to look for abuse and other
437     * bad app behavior.
438     */
439    final ProcessStatsService mProcessStats;
440
441    /**
442     * The currently running isolated processes.
443     */
444    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
445
446    /**
447     * Counter for assigning isolated process uids, to avoid frequently reusing the
448     * same ones.
449     */
450    int mNextIsolatedProcessUid = 0;
451
452    /**
453     * The currently running heavy-weight process, if any.
454     */
455    ProcessRecord mHeavyWeightProcess = null;
456
457    /**
458     * The last time that various processes have crashed.
459     */
460    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
461
462    /**
463     * Information about a process that is currently marked as bad.
464     */
465    static final class BadProcessInfo {
466        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
467            this.time = time;
468            this.shortMsg = shortMsg;
469            this.longMsg = longMsg;
470            this.stack = stack;
471        }
472
473        final long time;
474        final String shortMsg;
475        final String longMsg;
476        final String stack;
477    }
478
479    /**
480     * Set of applications that we consider to be bad, and will reject
481     * incoming broadcasts from (which the user has no control over).
482     * Processes are added to this set when they have crashed twice within
483     * a minimum amount of time; they are removed from it when they are
484     * later restarted (hopefully due to some user action).  The value is the
485     * time it was added to the list.
486     */
487    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
488
489    /**
490     * All of the processes we currently have running organized by pid.
491     * The keys are the pid running the application.
492     *
493     * <p>NOTE: This object is protected by its own lock, NOT the global
494     * activity manager lock!
495     */
496    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
497
498    /**
499     * All of the processes that have been forced to be foreground.  The key
500     * is the pid of the caller who requested it (we hold a death
501     * link on it).
502     */
503    abstract class ForegroundToken implements IBinder.DeathRecipient {
504        int pid;
505        IBinder token;
506    }
507    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
508
509    /**
510     * List of records for processes that someone had tried to start before the
511     * system was ready.  We don't start them at that point, but ensure they
512     * are started by the time booting is complete.
513     */
514    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
515
516    /**
517     * List of persistent applications that are in the process
518     * of being started.
519     */
520    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
521
522    /**
523     * Processes that are being forcibly torn down.
524     */
525    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of running applications, sorted by recent usage.
529     * The first entry in the list is the least recently used.
530     */
531    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Where in mLruProcesses that the processes hosting activities start.
535     */
536    int mLruProcessActivityStart = 0;
537
538    /**
539     * Where in mLruProcesses that the processes hosting services start.
540     * This is after (lower index) than mLruProcessesActivityStart.
541     */
542    int mLruProcessServiceStart = 0;
543
544    /**
545     * List of processes that should gc as soon as things are idle.
546     */
547    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
548
549    /**
550     * Processes we want to collect PSS data from.
551     */
552    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
553
554    /**
555     * Last time we requested PSS data of all processes.
556     */
557    long mLastFullPssTime = SystemClock.uptimeMillis();
558
559    /**
560     * This is the process holding what we currently consider to be
561     * the "home" activity.
562     */
563    ProcessRecord mHomeProcess;
564
565    /**
566     * This is the process holding the activity the user last visited that
567     * is in a different process from the one they are currently in.
568     */
569    ProcessRecord mPreviousProcess;
570
571    /**
572     * The time at which the previous process was last visible.
573     */
574    long mPreviousProcessVisibleTime;
575
576    /**
577     * Which uses have been started, so are allowed to run code.
578     */
579    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
580
581    /**
582     * LRU list of history of current users.  Most recently current is at the end.
583     */
584    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
585
586    /**
587     * Constant array of the users that are currently started.
588     */
589    int[] mStartedUserArray = new int[] { 0 };
590
591    /**
592     * Registered observers of the user switching mechanics.
593     */
594    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
595            = new RemoteCallbackList<IUserSwitchObserver>();
596
597    /**
598     * Currently active user switch.
599     */
600    Object mCurUserSwitchCallback;
601
602    /**
603     * Packages that the user has asked to have run in screen size
604     * compatibility mode instead of filling the screen.
605     */
606    final CompatModePackages mCompatModePackages;
607
608    /**
609     * Set of IntentSenderRecord objects that are currently active.
610     */
611    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
612            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
613
614    /**
615     * Fingerprints (hashCode()) of stack traces that we've
616     * already logged DropBox entries for.  Guarded by itself.  If
617     * something (rogue user app) forces this over
618     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
619     */
620    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
621    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
622
623    /**
624     * Strict Mode background batched logging state.
625     *
626     * The string buffer is guarded by itself, and its lock is also
627     * used to determine if another batched write is already
628     * in-flight.
629     */
630    private final StringBuilder mStrictModeBuffer = new StringBuilder();
631
632    /**
633     * Keeps track of all IIntentReceivers that have been registered for
634     * broadcasts.  Hash keys are the receiver IBinder, hash value is
635     * a ReceiverList.
636     */
637    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
638            new HashMap<IBinder, ReceiverList>();
639
640    /**
641     * Resolver for broadcast intents to registered receivers.
642     * Holds BroadcastFilter (subclass of IntentFilter).
643     */
644    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
645            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
646        @Override
647        protected boolean allowFilterResult(
648                BroadcastFilter filter, List<BroadcastFilter> dest) {
649            IBinder target = filter.receiverList.receiver.asBinder();
650            for (int i=dest.size()-1; i>=0; i--) {
651                if (dest.get(i).receiverList.receiver.asBinder() == target) {
652                    return false;
653                }
654            }
655            return true;
656        }
657
658        @Override
659        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
660            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
661                    || userId == filter.owningUserId) {
662                return super.newResult(filter, match, userId);
663            }
664            return null;
665        }
666
667        @Override
668        protected BroadcastFilter[] newArray(int size) {
669            return new BroadcastFilter[size];
670        }
671
672        @Override
673        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
674            return packageName.equals(filter.packageName);
675        }
676    };
677
678    /**
679     * State of all active sticky broadcasts per user.  Keys are the action of the
680     * sticky Intent, values are an ArrayList of all broadcasted intents with
681     * that action (which should usually be one).  The SparseArray is keyed
682     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
683     * for stickies that are sent to all users.
684     */
685    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
686            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
687
688    final ActiveServices mServices;
689
690    /**
691     * Backup/restore process management
692     */
693    String mBackupAppName = null;
694    BackupRecord mBackupTarget = null;
695
696    /**
697     * List of PendingThumbnailsRecord objects of clients who are still
698     * waiting to receive all of the thumbnails for a task.
699     */
700    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
701            new ArrayList<PendingThumbnailsRecord>();
702
703    final ProviderMap mProviderMap;
704
705    /**
706     * List of content providers who have clients waiting for them.  The
707     * application is currently being launched and the provider will be
708     * removed from this list once it is published.
709     */
710    final ArrayList<ContentProviderRecord> mLaunchingProviders
711            = new ArrayList<ContentProviderRecord>();
712
713    /**
714     * File storing persisted {@link #mGrantedUriPermissions}.
715     */
716    private final AtomicFile mGrantFile;
717
718    /** XML constants used in {@link #mGrantFile} */
719    private static final String TAG_URI_GRANTS = "uri-grants";
720    private static final String TAG_URI_GRANT = "uri-grant";
721    private static final String ATTR_USER_HANDLE = "userHandle";
722    private static final String ATTR_SOURCE_PKG = "sourcePkg";
723    private static final String ATTR_TARGET_PKG = "targetPkg";
724    private static final String ATTR_URI = "uri";
725    private static final String ATTR_MODE_FLAGS = "modeFlags";
726    private static final String ATTR_CREATED_TIME = "createdTime";
727
728    /**
729     * Global set of specific {@link Uri} permissions that have been granted.
730     * This optimized lookup structure maps from {@link UriPermission#targetUid}
731     * to {@link UriPermission#uri} to {@link UriPermission}.
732     */
733    @GuardedBy("this")
734    private final SparseArray<ArrayMap<Uri, UriPermission>>
735            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
736
737    CoreSettingsObserver mCoreSettingsObserver;
738
739    /**
740     * Thread-local storage used to carry caller permissions over through
741     * indirect content-provider access.
742     */
743    private class Identity {
744        public int pid;
745        public int uid;
746
747        Identity(int _pid, int _uid) {
748            pid = _pid;
749            uid = _uid;
750        }
751    }
752
753    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
754
755    /**
756     * All information we have collected about the runtime performance of
757     * any user id that can impact battery performance.
758     */
759    final BatteryStatsService mBatteryStatsService;
760
761    /**
762     * Information about component usage
763     */
764    final UsageStatsService mUsageStatsService;
765
766    /**
767     * Information about and control over application operations
768     */
769    final AppOpsService mAppOpsService;
770
771    /**
772     * Current configuration information.  HistoryRecord objects are given
773     * a reference to this object to indicate which configuration they are
774     * currently running in, so this object must be kept immutable.
775     */
776    Configuration mConfiguration = new Configuration();
777
778    /**
779     * Current sequencing integer of the configuration, for skipping old
780     * configurations.
781     */
782    int mConfigurationSeq = 0;
783
784    /**
785     * Hardware-reported OpenGLES version.
786     */
787    final int GL_ES_VERSION;
788
789    /**
790     * List of initialization arguments to pass to all processes when binding applications to them.
791     * For example, references to the commonly used services.
792     */
793    HashMap<String, IBinder> mAppBindArgs;
794
795    /**
796     * Temporary to avoid allocations.  Protected by main lock.
797     */
798    final StringBuilder mStringBuilder = new StringBuilder(256);
799
800    /**
801     * Used to control how we initialize the service.
802     */
803    ComponentName mTopComponent;
804    String mTopAction = Intent.ACTION_MAIN;
805    String mTopData;
806    boolean mProcessesReady = false;
807    boolean mSystemReady = false;
808    boolean mBooting = false;
809    boolean mWaitingUpdate = false;
810    boolean mDidUpdate = false;
811    boolean mOnBattery = false;
812    boolean mLaunchWarningShown = false;
813
814    Context mContext;
815
816    int mFactoryTest;
817
818    boolean mCheckedForSetup;
819
820    /**
821     * The time at which we will allow normal application switches again,
822     * after a call to {@link #stopAppSwitches()}.
823     */
824    long mAppSwitchesAllowedTime;
825
826    /**
827     * This is set to true after the first switch after mAppSwitchesAllowedTime
828     * is set; any switches after that will clear the time.
829     */
830    boolean mDidAppSwitch;
831
832    /**
833     * Last time (in realtime) at which we checked for power usage.
834     */
835    long mLastPowerCheckRealtime;
836
837    /**
838     * Last time (in uptime) at which we checked for power usage.
839     */
840    long mLastPowerCheckUptime;
841
842    /**
843     * Set while we are wanting to sleep, to prevent any
844     * activities from being started/resumed.
845     */
846    boolean mSleeping = false;
847
848    /**
849     * State of external calls telling us if the device is asleep.
850     */
851    boolean mWentToSleep = false;
852
853    /**
854     * State of external call telling us if the lock screen is shown.
855     */
856    boolean mLockScreenShown = false;
857
858    /**
859     * Set if we are shutting down the system, similar to sleeping.
860     */
861    boolean mShuttingDown = false;
862
863    /**
864     * Current sequence id for oom_adj computation traversal.
865     */
866    int mAdjSeq = 0;
867
868    /**
869     * Current sequence id for process LRU updating.
870     */
871    int mLruSeq = 0;
872
873    /**
874     * Keep track of the non-cached/empty process we last found, to help
875     * determine how to distribute cached/empty processes next time.
876     */
877    int mNumNonCachedProcs = 0;
878
879    /**
880     * Keep track of the number of cached hidden procs, to balance oom adj
881     * distribution between those and empty procs.
882     */
883    int mNumCachedHiddenProcs = 0;
884
885    /**
886     * Keep track of the number of service processes we last found, to
887     * determine on the next iteration which should be B services.
888     */
889    int mNumServiceProcs = 0;
890    int mNewNumAServiceProcs = 0;
891    int mNewNumServiceProcs = 0;
892
893    /**
894     * Allow the current computed overall memory level of the system to go down?
895     * This is set to false when we are killing processes for reasons other than
896     * memory management, so that the now smaller process list will not be taken as
897     * an indication that memory is tighter.
898     */
899    boolean mAllowLowerMemLevel = false;
900
901    /**
902     * The last computed memory level, for holding when we are in a state that
903     * processes are going away for other reasons.
904     */
905    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
906
907    /**
908     * The last total number of process we have, to determine if changes actually look
909     * like a shrinking number of process due to lower RAM.
910     */
911    int mLastNumProcesses;
912
913    /**
914     * The uptime of the last time we performed idle maintenance.
915     */
916    long mLastIdleTime = SystemClock.uptimeMillis();
917
918    /**
919     * Total time spent with RAM that has been added in the past since the last idle time.
920     */
921    long mLowRamTimeSinceLastIdle = 0;
922
923    /**
924     * If RAM is currently low, when that horrible situation started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * For reporting to battery stats the current top application.
930     */
931    private String mCurResumedPackage = null;
932    private int mCurResumedUid = -1;
933
934    /**
935     * For reporting to battery stats the apps currently running foreground
936     * service.  The ProcessMap is package/uid tuples; each of these contain
937     * an array of the currently foreground processes.
938     */
939    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
940            = new ProcessMap<ArrayList<ProcessRecord>>();
941
942    /**
943     * This is set if we had to do a delayed dexopt of an app before launching
944     * it, to increasing the ANR timeouts in that case.
945     */
946    boolean mDidDexOpt;
947
948    /**
949     * Set if the systemServer made a call to enterSafeMode.
950     */
951    boolean mSafeMode;
952
953    String mDebugApp = null;
954    boolean mWaitForDebugger = false;
955    boolean mDebugTransient = false;
956    String mOrigDebugApp = null;
957    boolean mOrigWaitForDebugger = false;
958    boolean mAlwaysFinishActivities = false;
959    IActivityController mController = null;
960    String mProfileApp = null;
961    ProcessRecord mProfileProc = null;
962    String mProfileFile;
963    ParcelFileDescriptor mProfileFd;
964    int mProfileType = 0;
965    boolean mAutoStopProfiler = false;
966    String mOpenGlTraceApp = null;
967
968    static class ProcessChangeItem {
969        static final int CHANGE_ACTIVITIES = 1<<0;
970        static final int CHANGE_IMPORTANCE= 1<<1;
971        int changes;
972        int uid;
973        int pid;
974        int importance;
975        boolean foregroundActivities;
976    }
977
978    final RemoteCallbackList<IProcessObserver> mProcessObservers
979            = new RemoteCallbackList<IProcessObserver>();
980    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
981
982    final ArrayList<ProcessChangeItem> mPendingProcessChanges
983            = new ArrayList<ProcessChangeItem>();
984    final ArrayList<ProcessChangeItem> mAvailProcessChanges
985            = new ArrayList<ProcessChangeItem>();
986
987    /**
988     * Runtime CPU use collection thread.  This object's lock is used to
989     * protect all related state.
990     */
991    final Thread mProcessCpuThread;
992
993    /**
994     * Used to collect process stats when showing not responding dialog.
995     * Protected by mProcessCpuThread.
996     */
997    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
998            MONITOR_THREAD_CPU_USAGE);
999    final AtomicLong mLastCpuTime = new AtomicLong(0);
1000    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1001
1002    long mLastWriteTime = 0;
1003
1004    /**
1005     * Used to retain an update lock when the foreground activity is in
1006     * immersive mode.
1007     */
1008    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1009
1010    /**
1011     * Set to true after the system has finished booting.
1012     */
1013    boolean mBooted = false;
1014
1015    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1016    int mProcessLimitOverride = -1;
1017
1018    WindowManagerService mWindowManager;
1019
1020    final ActivityThread mSystemThread;
1021
1022    int mCurrentUserId = 0;
1023    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1024    private UserManagerService mUserManager;
1025
1026    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1027        final ProcessRecord mApp;
1028        final int mPid;
1029        final IApplicationThread mAppThread;
1030
1031        AppDeathRecipient(ProcessRecord app, int pid,
1032                IApplicationThread thread) {
1033            if (localLOGV) Slog.v(
1034                TAG, "New death recipient " + this
1035                + " for thread " + thread.asBinder());
1036            mApp = app;
1037            mPid = pid;
1038            mAppThread = thread;
1039        }
1040
1041        @Override
1042        public void binderDied() {
1043            if (localLOGV) Slog.v(
1044                TAG, "Death received in " + this
1045                + " for thread " + mAppThread.asBinder());
1046            synchronized(ActivityManagerService.this) {
1047                appDiedLocked(mApp, mPid, mAppThread);
1048            }
1049        }
1050    }
1051
1052    static final int SHOW_ERROR_MSG = 1;
1053    static final int SHOW_NOT_RESPONDING_MSG = 2;
1054    static final int SHOW_FACTORY_ERROR_MSG = 3;
1055    static final int UPDATE_CONFIGURATION_MSG = 4;
1056    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1057    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1058    static final int SERVICE_TIMEOUT_MSG = 12;
1059    static final int UPDATE_TIME_ZONE = 13;
1060    static final int SHOW_UID_ERROR_MSG = 14;
1061    static final int IM_FEELING_LUCKY_MSG = 15;
1062    static final int PROC_START_TIMEOUT_MSG = 20;
1063    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1064    static final int KILL_APPLICATION_MSG = 22;
1065    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1066    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1067    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1068    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1069    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1070    static final int CLEAR_DNS_CACHE_MSG = 28;
1071    static final int UPDATE_HTTP_PROXY_MSG = 29;
1072    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1073    static final int DISPATCH_PROCESSES_CHANGED = 31;
1074    static final int DISPATCH_PROCESS_DIED = 32;
1075    static final int REPORT_MEM_USAGE_MSG = 33;
1076    static final int REPORT_USER_SWITCH_MSG = 34;
1077    static final int CONTINUE_USER_SWITCH_MSG = 35;
1078    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1079    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1080    static final int PERSIST_URI_GRANTS_MSG = 38;
1081    static final int REQUEST_ALL_PSS_MSG = 39;
1082    static final int START_PROFILES_MSG = 40;
1083    static final int UPDATE_TIME = 41;
1084
1085    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1086    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1087    static final int FIRST_COMPAT_MODE_MSG = 300;
1088    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1089
1090    AlertDialog mUidAlert;
1091    CompatModeDialog mCompatModeDialog;
1092    long mLastMemUsageReportTime = 0;
1093
1094    /**
1095     * Flag whether the current user is a "monkey", i.e. whether
1096     * the UI is driven by a UI automation tool.
1097     */
1098    private boolean mUserIsMonkey;
1099
1100    final ServiceThread mHandlerThread;
1101    final MainHandler mHandler;
1102
1103    final class MainHandler extends Handler {
1104        public MainHandler(Looper looper) {
1105            super(looper, null, true);
1106        }
1107
1108        @Override
1109        public void handleMessage(Message msg) {
1110            switch (msg.what) {
1111            case SHOW_ERROR_MSG: {
1112                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1113                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1114                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1115                synchronized (ActivityManagerService.this) {
1116                    ProcessRecord proc = (ProcessRecord)data.get("app");
1117                    AppErrorResult res = (AppErrorResult) data.get("result");
1118                    if (proc != null && proc.crashDialog != null) {
1119                        Slog.e(TAG, "App already has crash dialog: " + proc);
1120                        if (res != null) {
1121                            res.set(0);
1122                        }
1123                        return;
1124                    }
1125                    if (!showBackground && UserHandle.getAppId(proc.uid)
1126                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1127                            && proc.pid != MY_PID) {
1128                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1129                        if (res != null) {
1130                            res.set(0);
1131                        }
1132                        return;
1133                    }
1134                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1135                        Dialog d = new AppErrorDialog(mContext,
1136                                ActivityManagerService.this, res, proc);
1137                        d.show();
1138                        proc.crashDialog = d;
1139                    } else {
1140                        // The device is asleep, so just pretend that the user
1141                        // saw a crash dialog and hit "force quit".
1142                        if (res != null) {
1143                            res.set(0);
1144                        }
1145                    }
1146                }
1147
1148                ensureBootCompleted();
1149            } break;
1150            case SHOW_NOT_RESPONDING_MSG: {
1151                synchronized (ActivityManagerService.this) {
1152                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1153                    ProcessRecord proc = (ProcessRecord)data.get("app");
1154                    if (proc != null && proc.anrDialog != null) {
1155                        Slog.e(TAG, "App already has anr dialog: " + proc);
1156                        return;
1157                    }
1158
1159                    Intent intent = new Intent("android.intent.action.ANR");
1160                    if (!mProcessesReady) {
1161                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1162                                | Intent.FLAG_RECEIVER_FOREGROUND);
1163                    }
1164                    broadcastIntentLocked(null, null, intent,
1165                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1166                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1167
1168                    if (mShowDialogs) {
1169                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1170                                mContext, proc, (ActivityRecord)data.get("activity"),
1171                                msg.arg1 != 0);
1172                        d.show();
1173                        proc.anrDialog = d;
1174                    } else {
1175                        // Just kill the app if there is no dialog to be shown.
1176                        killAppAtUsersRequest(proc, null);
1177                    }
1178                }
1179
1180                ensureBootCompleted();
1181            } break;
1182            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1183                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1184                synchronized (ActivityManagerService.this) {
1185                    ProcessRecord proc = (ProcessRecord) data.get("app");
1186                    if (proc == null) {
1187                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1188                        break;
1189                    }
1190                    if (proc.crashDialog != null) {
1191                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1192                        return;
1193                    }
1194                    AppErrorResult res = (AppErrorResult) data.get("result");
1195                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1196                        Dialog d = new StrictModeViolationDialog(mContext,
1197                                ActivityManagerService.this, res, proc);
1198                        d.show();
1199                        proc.crashDialog = d;
1200                    } else {
1201                        // The device is asleep, so just pretend that the user
1202                        // saw a crash dialog and hit "force quit".
1203                        res.set(0);
1204                    }
1205                }
1206                ensureBootCompleted();
1207            } break;
1208            case SHOW_FACTORY_ERROR_MSG: {
1209                Dialog d = new FactoryErrorDialog(
1210                    mContext, msg.getData().getCharSequence("msg"));
1211                d.show();
1212                ensureBootCompleted();
1213            } break;
1214            case UPDATE_CONFIGURATION_MSG: {
1215                final ContentResolver resolver = mContext.getContentResolver();
1216                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1217            } break;
1218            case GC_BACKGROUND_PROCESSES_MSG: {
1219                synchronized (ActivityManagerService.this) {
1220                    performAppGcsIfAppropriateLocked();
1221                }
1222            } break;
1223            case WAIT_FOR_DEBUGGER_MSG: {
1224                synchronized (ActivityManagerService.this) {
1225                    ProcessRecord app = (ProcessRecord)msg.obj;
1226                    if (msg.arg1 != 0) {
1227                        if (!app.waitedForDebugger) {
1228                            Dialog d = new AppWaitingForDebuggerDialog(
1229                                    ActivityManagerService.this,
1230                                    mContext, app);
1231                            app.waitDialog = d;
1232                            app.waitedForDebugger = true;
1233                            d.show();
1234                        }
1235                    } else {
1236                        if (app.waitDialog != null) {
1237                            app.waitDialog.dismiss();
1238                            app.waitDialog = null;
1239                        }
1240                    }
1241                }
1242            } break;
1243            case SERVICE_TIMEOUT_MSG: {
1244                if (mDidDexOpt) {
1245                    mDidDexOpt = false;
1246                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1247                    nmsg.obj = msg.obj;
1248                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1249                    return;
1250                }
1251                mServices.serviceTimeout((ProcessRecord)msg.obj);
1252            } break;
1253            case UPDATE_TIME_ZONE: {
1254                synchronized (ActivityManagerService.this) {
1255                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1256                        ProcessRecord r = mLruProcesses.get(i);
1257                        if (r.thread != null) {
1258                            try {
1259                                r.thread.updateTimeZone();
1260                            } catch (RemoteException ex) {
1261                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1262                            }
1263                        }
1264                    }
1265                }
1266            } break;
1267            case CLEAR_DNS_CACHE_MSG: {
1268                synchronized (ActivityManagerService.this) {
1269                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1270                        ProcessRecord r = mLruProcesses.get(i);
1271                        if (r.thread != null) {
1272                            try {
1273                                r.thread.clearDnsCache();
1274                            } catch (RemoteException ex) {
1275                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1276                            }
1277                        }
1278                    }
1279                }
1280            } break;
1281            case UPDATE_HTTP_PROXY_MSG: {
1282                ProxyProperties proxy = (ProxyProperties)msg.obj;
1283                String host = "";
1284                String port = "";
1285                String exclList = "";
1286                String pacFileUrl = null;
1287                if (proxy != null) {
1288                    host = proxy.getHost();
1289                    port = Integer.toString(proxy.getPort());
1290                    exclList = proxy.getExclusionList();
1291                    pacFileUrl = proxy.getPacFileUrl();
1292                }
1293                synchronized (ActivityManagerService.this) {
1294                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1295                        ProcessRecord r = mLruProcesses.get(i);
1296                        if (r.thread != null) {
1297                            try {
1298                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1299                            } catch (RemoteException ex) {
1300                                Slog.w(TAG, "Failed to update http proxy for: " +
1301                                        r.info.processName);
1302                            }
1303                        }
1304                    }
1305                }
1306            } break;
1307            case SHOW_UID_ERROR_MSG: {
1308                String title = "System UIDs Inconsistent";
1309                String text = "UIDs on the system are inconsistent, you need to wipe your"
1310                        + " data partition or your device will be unstable.";
1311                Log.e(TAG, title + ": " + text);
1312                if (mShowDialogs) {
1313                    // XXX This is a temporary dialog, no need to localize.
1314                    AlertDialog d = new BaseErrorDialog(mContext);
1315                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1316                    d.setCancelable(false);
1317                    d.setTitle(title);
1318                    d.setMessage(text);
1319                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1320                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1321                    mUidAlert = d;
1322                    d.show();
1323                }
1324            } break;
1325            case IM_FEELING_LUCKY_MSG: {
1326                if (mUidAlert != null) {
1327                    mUidAlert.dismiss();
1328                    mUidAlert = null;
1329                }
1330            } break;
1331            case PROC_START_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1337                    return;
1338                }
1339                ProcessRecord app = (ProcessRecord)msg.obj;
1340                synchronized (ActivityManagerService.this) {
1341                    processStartTimedOutLocked(app);
1342                }
1343            } break;
1344            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    doPendingActivityLaunchesLocked(true);
1347                }
1348            } break;
1349            case KILL_APPLICATION_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    int appid = msg.arg1;
1352                    boolean restart = (msg.arg2 == 1);
1353                    Bundle bundle = (Bundle)msg.obj;
1354                    String pkg = bundle.getString("pkg");
1355                    String reason = bundle.getString("reason");
1356                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1357                            false, UserHandle.USER_ALL, reason);
1358                }
1359            } break;
1360            case FINALIZE_PENDING_INTENT_MSG: {
1361                ((PendingIntentRecord)msg.obj).completeFinalize();
1362            } break;
1363            case POST_HEAVY_NOTIFICATION_MSG: {
1364                INotificationManager inm = NotificationManager.getService();
1365                if (inm == null) {
1366                    return;
1367                }
1368
1369                ActivityRecord root = (ActivityRecord)msg.obj;
1370                ProcessRecord process = root.app;
1371                if (process == null) {
1372                    return;
1373                }
1374
1375                try {
1376                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1377                    String text = mContext.getString(R.string.heavy_weight_notification,
1378                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1379                    Notification notification = new Notification();
1380                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1381                    notification.when = 0;
1382                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1383                    notification.tickerText = text;
1384                    notification.defaults = 0; // please be quiet
1385                    notification.sound = null;
1386                    notification.vibrate = null;
1387                    notification.setLatestEventInfo(context, text,
1388                            mContext.getText(R.string.heavy_weight_notification_detail),
1389                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1390                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1391                                    new UserHandle(root.userId)));
1392
1393                    try {
1394                        int[] outId = new int[1];
1395                        inm.enqueueNotificationWithTag("android", "android", null,
1396                                R.string.heavy_weight_notification,
1397                                notification, outId, root.userId);
1398                    } catch (RuntimeException e) {
1399                        Slog.w(ActivityManagerService.TAG,
1400                                "Error showing notification for heavy-weight app", e);
1401                    } catch (RemoteException e) {
1402                    }
1403                } catch (NameNotFoundException e) {
1404                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1405                }
1406            } break;
1407            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1408                INotificationManager inm = NotificationManager.getService();
1409                if (inm == null) {
1410                    return;
1411                }
1412                try {
1413                    inm.cancelNotificationWithTag("android", null,
1414                            R.string.heavy_weight_notification,  msg.arg1);
1415                } catch (RuntimeException e) {
1416                    Slog.w(ActivityManagerService.TAG,
1417                            "Error canceling notification for service", e);
1418                } catch (RemoteException e) {
1419                }
1420            } break;
1421            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1422                synchronized (ActivityManagerService.this) {
1423                    checkExcessivePowerUsageLocked(true);
1424                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1425                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1426                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1427                }
1428            } break;
1429            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1430                synchronized (ActivityManagerService.this) {
1431                    ActivityRecord ar = (ActivityRecord)msg.obj;
1432                    if (mCompatModeDialog != null) {
1433                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1434                                ar.info.applicationInfo.packageName)) {
1435                            return;
1436                        }
1437                        mCompatModeDialog.dismiss();
1438                        mCompatModeDialog = null;
1439                    }
1440                    if (ar != null && false) {
1441                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1442                                ar.packageName)) {
1443                            int mode = mCompatModePackages.computeCompatModeLocked(
1444                                    ar.info.applicationInfo);
1445                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1446                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1447                                mCompatModeDialog = new CompatModeDialog(
1448                                        ActivityManagerService.this, mContext,
1449                                        ar.info.applicationInfo);
1450                                mCompatModeDialog.show();
1451                            }
1452                        }
1453                    }
1454                }
1455                break;
1456            }
1457            case DISPATCH_PROCESSES_CHANGED: {
1458                dispatchProcessesChanged();
1459                break;
1460            }
1461            case DISPATCH_PROCESS_DIED: {
1462                final int pid = msg.arg1;
1463                final int uid = msg.arg2;
1464                dispatchProcessDied(pid, uid);
1465                break;
1466            }
1467            case REPORT_MEM_USAGE_MSG: {
1468                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1469                Thread thread = new Thread() {
1470                    @Override public void run() {
1471                        final SparseArray<ProcessMemInfo> infoMap
1472                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1473                        for (int i=0, N=memInfos.size(); i<N; i++) {
1474                            ProcessMemInfo mi = memInfos.get(i);
1475                            infoMap.put(mi.pid, mi);
1476                        }
1477                        updateCpuStatsNow();
1478                        synchronized (mProcessCpuThread) {
1479                            final int N = mProcessCpuTracker.countStats();
1480                            for (int i=0; i<N; i++) {
1481                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1482                                if (st.vsize > 0) {
1483                                    long pss = Debug.getPss(st.pid, null);
1484                                    if (pss > 0) {
1485                                        if (infoMap.indexOfKey(st.pid) < 0) {
1486                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1487                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1488                                            mi.pss = pss;
1489                                            memInfos.add(mi);
1490                                        }
1491                                    }
1492                                }
1493                            }
1494                        }
1495
1496                        long totalPss = 0;
1497                        for (int i=0, N=memInfos.size(); i<N; i++) {
1498                            ProcessMemInfo mi = memInfos.get(i);
1499                            if (mi.pss == 0) {
1500                                mi.pss = Debug.getPss(mi.pid, null);
1501                            }
1502                            totalPss += mi.pss;
1503                        }
1504                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1505                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1506                                if (lhs.oomAdj != rhs.oomAdj) {
1507                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1508                                }
1509                                if (lhs.pss != rhs.pss) {
1510                                    return lhs.pss < rhs.pss ? 1 : -1;
1511                                }
1512                                return 0;
1513                            }
1514                        });
1515
1516                        StringBuilder tag = new StringBuilder(128);
1517                        StringBuilder stack = new StringBuilder(128);
1518                        tag.append("Low on memory -- ");
1519                        appendMemBucket(tag, totalPss, "total", false);
1520                        appendMemBucket(stack, totalPss, "total", true);
1521
1522                        StringBuilder logBuilder = new StringBuilder(1024);
1523                        logBuilder.append("Low on memory:\n");
1524
1525                        boolean firstLine = true;
1526                        int lastOomAdj = Integer.MIN_VALUE;
1527                        for (int i=0, N=memInfos.size(); i<N; i++) {
1528                            ProcessMemInfo mi = memInfos.get(i);
1529
1530                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1531                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1532                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1533                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1534                                if (lastOomAdj != mi.oomAdj) {
1535                                    lastOomAdj = mi.oomAdj;
1536                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1537                                        tag.append(" / ");
1538                                    }
1539                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1540                                        if (firstLine) {
1541                                            stack.append(":");
1542                                            firstLine = false;
1543                                        }
1544                                        stack.append("\n\t at ");
1545                                    } else {
1546                                        stack.append("$");
1547                                    }
1548                                } else {
1549                                    tag.append(" ");
1550                                    stack.append("$");
1551                                }
1552                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1553                                    appendMemBucket(tag, mi.pss, mi.name, false);
1554                                }
1555                                appendMemBucket(stack, mi.pss, mi.name, true);
1556                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1557                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1558                                    stack.append("(");
1559                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1560                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1561                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1562                                            stack.append(":");
1563                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1564                                        }
1565                                    }
1566                                    stack.append(")");
1567                                }
1568                            }
1569
1570                            logBuilder.append("  ");
1571                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1572                            logBuilder.append(' ');
1573                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1574                            logBuilder.append(' ');
1575                            ProcessList.appendRamKb(logBuilder, mi.pss);
1576                            logBuilder.append(" kB: ");
1577                            logBuilder.append(mi.name);
1578                            logBuilder.append(" (");
1579                            logBuilder.append(mi.pid);
1580                            logBuilder.append(") ");
1581                            logBuilder.append(mi.adjType);
1582                            logBuilder.append('\n');
1583                            if (mi.adjReason != null) {
1584                                logBuilder.append("                      ");
1585                                logBuilder.append(mi.adjReason);
1586                                logBuilder.append('\n');
1587                            }
1588                        }
1589
1590                        logBuilder.append("           ");
1591                        ProcessList.appendRamKb(logBuilder, totalPss);
1592                        logBuilder.append(" kB: TOTAL\n");
1593
1594                        long[] infos = new long[Debug.MEMINFO_COUNT];
1595                        Debug.getMemInfo(infos);
1596                        logBuilder.append("  MemInfo: ");
1597                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1598                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1599                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1600                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1601                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1602                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1603                            logBuilder.append("  ZRAM: ");
1604                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1605                            logBuilder.append(" kB RAM, ");
1606                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1607                            logBuilder.append(" kB swap total, ");
1608                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1609                            logBuilder.append(" kB swap free\n");
1610                        }
1611                        Slog.i(TAG, logBuilder.toString());
1612
1613                        StringBuilder dropBuilder = new StringBuilder(1024);
1614                        /*
1615                        StringWriter oomSw = new StringWriter();
1616                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1617                        StringWriter catSw = new StringWriter();
1618                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1619                        String[] emptyArgs = new String[] { };
1620                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1621                        oomPw.flush();
1622                        String oomString = oomSw.toString();
1623                        */
1624                        dropBuilder.append(stack);
1625                        dropBuilder.append('\n');
1626                        dropBuilder.append('\n');
1627                        dropBuilder.append(logBuilder);
1628                        dropBuilder.append('\n');
1629                        /*
1630                        dropBuilder.append(oomString);
1631                        dropBuilder.append('\n');
1632                        */
1633                        StringWriter catSw = new StringWriter();
1634                        synchronized (ActivityManagerService.this) {
1635                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1636                            String[] emptyArgs = new String[] { };
1637                            catPw.println();
1638                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1639                            catPw.println();
1640                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1641                                    false, false, null);
1642                            catPw.println();
1643                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1644                            catPw.flush();
1645                        }
1646                        dropBuilder.append(catSw.toString());
1647                        addErrorToDropBox("lowmem", null, "system_server", null,
1648                                null, tag.toString(), dropBuilder.toString(), null, null);
1649                        //Slog.i(TAG, "Sent to dropbox:");
1650                        //Slog.i(TAG, dropBuilder.toString());
1651                        synchronized (ActivityManagerService.this) {
1652                            long now = SystemClock.uptimeMillis();
1653                            if (mLastMemUsageReportTime < now) {
1654                                mLastMemUsageReportTime = now;
1655                            }
1656                        }
1657                    }
1658                };
1659                thread.start();
1660                break;
1661            }
1662            case REPORT_USER_SWITCH_MSG: {
1663                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1664                break;
1665            }
1666            case CONTINUE_USER_SWITCH_MSG: {
1667                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1668                break;
1669            }
1670            case USER_SWITCH_TIMEOUT_MSG: {
1671                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1672                break;
1673            }
1674            case IMMERSIVE_MODE_LOCK_MSG: {
1675                final boolean nextState = (msg.arg1 != 0);
1676                if (mUpdateLock.isHeld() != nextState) {
1677                    if (DEBUG_IMMERSIVE) {
1678                        final ActivityRecord r = (ActivityRecord) msg.obj;
1679                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1680                    }
1681                    if (nextState) {
1682                        mUpdateLock.acquire();
1683                    } else {
1684                        mUpdateLock.release();
1685                    }
1686                }
1687                break;
1688            }
1689            case PERSIST_URI_GRANTS_MSG: {
1690                writeGrantedUriPermissions();
1691                break;
1692            }
1693            case REQUEST_ALL_PSS_MSG: {
1694                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1695                break;
1696            }
1697            case START_PROFILES_MSG: {
1698                synchronized (ActivityManagerService.this) {
1699                    startProfilesLocked();
1700                }
1701                break;
1702            }
1703            case UPDATE_TIME: {
1704                synchronized (ActivityManagerService.this) {
1705                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1706                        ProcessRecord r = mLruProcesses.get(i);
1707                        if (r.thread != null) {
1708                            try {
1709                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1710                            } catch (RemoteException ex) {
1711                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1712                            }
1713                        }
1714                    }
1715                }
1716                break;
1717            }
1718            }
1719        }
1720    };
1721
1722    static final int COLLECT_PSS_BG_MSG = 1;
1723
1724    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1725        @Override
1726        public void handleMessage(Message msg) {
1727            switch (msg.what) {
1728            case COLLECT_PSS_BG_MSG: {
1729                int i=0, num=0;
1730                long start = SystemClock.uptimeMillis();
1731                long[] tmp = new long[1];
1732                do {
1733                    ProcessRecord proc;
1734                    int procState;
1735                    int pid;
1736                    synchronized (ActivityManagerService.this) {
1737                        if (i >= mPendingPssProcesses.size()) {
1738                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1739                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1740                            mPendingPssProcesses.clear();
1741                            return;
1742                        }
1743                        proc = mPendingPssProcesses.get(i);
1744                        procState = proc.pssProcState;
1745                        if (proc.thread != null && procState == proc.setProcState) {
1746                            pid = proc.pid;
1747                        } else {
1748                            proc = null;
1749                            pid = 0;
1750                        }
1751                        i++;
1752                    }
1753                    if (proc != null) {
1754                        long pss = Debug.getPss(pid, tmp);
1755                        synchronized (ActivityManagerService.this) {
1756                            if (proc.thread != null && proc.setProcState == procState
1757                                    && proc.pid == pid) {
1758                                num++;
1759                                proc.lastPssTime = SystemClock.uptimeMillis();
1760                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1761                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1762                                        + ": " + pss + " lastPss=" + proc.lastPss
1763                                        + " state=" + ProcessList.makeProcStateString(procState));
1764                                if (proc.initialIdlePss == 0) {
1765                                    proc.initialIdlePss = pss;
1766                                }
1767                                proc.lastPss = pss;
1768                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1769                                    proc.lastCachedPss = pss;
1770                                }
1771                            }
1772                        }
1773                    }
1774                } while (true);
1775            }
1776            }
1777        }
1778    };
1779
1780    public void setSystemProcess() {
1781        try {
1782            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1783            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1784            ServiceManager.addService("meminfo", new MemBinder(this));
1785            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1786            ServiceManager.addService("dbinfo", new DbBinder(this));
1787            if (MONITOR_CPU_USAGE) {
1788                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1789            }
1790            ServiceManager.addService("permission", new PermissionController(this));
1791
1792            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1793                    "android", STOCK_PM_FLAGS);
1794            mSystemThread.installSystemApplicationInfo(info);
1795
1796            synchronized (this) {
1797                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1798                app.persistent = true;
1799                app.pid = MY_PID;
1800                app.maxAdj = ProcessList.SYSTEM_ADJ;
1801                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1802                mProcessNames.put(app.processName, app.uid, app);
1803                synchronized (mPidsSelfLocked) {
1804                    mPidsSelfLocked.put(app.pid, app);
1805                }
1806                updateLruProcessLocked(app, false, null);
1807                updateOomAdjLocked();
1808            }
1809        } catch (PackageManager.NameNotFoundException e) {
1810            throw new RuntimeException(
1811                    "Unable to find android system package", e);
1812        }
1813    }
1814
1815    public void setWindowManager(WindowManagerService wm) {
1816        mWindowManager = wm;
1817        mStackSupervisor.setWindowManager(wm);
1818    }
1819
1820    public void startObservingNativeCrashes() {
1821        final NativeCrashListener ncl = new NativeCrashListener(this);
1822        ncl.start();
1823    }
1824
1825    public IAppOpsService getAppOpsService() {
1826        return mAppOpsService;
1827    }
1828
1829    static class MemBinder extends Binder {
1830        ActivityManagerService mActivityManagerService;
1831        MemBinder(ActivityManagerService activityManagerService) {
1832            mActivityManagerService = activityManagerService;
1833        }
1834
1835        @Override
1836        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1837            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1838                    != PackageManager.PERMISSION_GRANTED) {
1839                pw.println("Permission Denial: can't dump meminfo from from pid="
1840                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1841                        + " without permission " + android.Manifest.permission.DUMP);
1842                return;
1843            }
1844
1845            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1846        }
1847    }
1848
1849    static class GraphicsBinder extends Binder {
1850        ActivityManagerService mActivityManagerService;
1851        GraphicsBinder(ActivityManagerService activityManagerService) {
1852            mActivityManagerService = activityManagerService;
1853        }
1854
1855        @Override
1856        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1857            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1858                    != PackageManager.PERMISSION_GRANTED) {
1859                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1860                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1861                        + " without permission " + android.Manifest.permission.DUMP);
1862                return;
1863            }
1864
1865            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1866        }
1867    }
1868
1869    static class DbBinder extends Binder {
1870        ActivityManagerService mActivityManagerService;
1871        DbBinder(ActivityManagerService activityManagerService) {
1872            mActivityManagerService = activityManagerService;
1873        }
1874
1875        @Override
1876        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1877            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1878                    != PackageManager.PERMISSION_GRANTED) {
1879                pw.println("Permission Denial: can't dump dbinfo from from pid="
1880                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1881                        + " without permission " + android.Manifest.permission.DUMP);
1882                return;
1883            }
1884
1885            mActivityManagerService.dumpDbInfo(fd, pw, args);
1886        }
1887    }
1888
1889    static class CpuBinder extends Binder {
1890        ActivityManagerService mActivityManagerService;
1891        CpuBinder(ActivityManagerService activityManagerService) {
1892            mActivityManagerService = activityManagerService;
1893        }
1894
1895        @Override
1896        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1897            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1898                    != PackageManager.PERMISSION_GRANTED) {
1899                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1900                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1901                        + " without permission " + android.Manifest.permission.DUMP);
1902                return;
1903            }
1904
1905            synchronized (mActivityManagerService.mProcessCpuThread) {
1906                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1907                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1908                        SystemClock.uptimeMillis()));
1909            }
1910        }
1911    }
1912
1913    public static final class Lifecycle extends SystemService {
1914        private final ActivityManagerService mService;
1915
1916        public Lifecycle(Context context) {
1917            super(context);
1918            mService = new ActivityManagerService(context);
1919        }
1920
1921        @Override
1922        public void onStart() {
1923            mService.start();
1924        }
1925
1926        public ActivityManagerService getService() {
1927            return mService;
1928        }
1929    }
1930
1931    // Note: This method is invoked on the main thread but may need to attach various
1932    // handlers to other threads.  So take care to be explicit about the looper.
1933    public ActivityManagerService(Context systemContext) {
1934        mContext = systemContext;
1935        mFactoryTest = FactoryTest.getMode();
1936        mSystemThread = ActivityThread.currentActivityThread();
1937
1938        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1939
1940        mHandlerThread = new ServiceThread(TAG,
1941                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1942        mHandlerThread.start();
1943        mHandler = new MainHandler(mHandlerThread.getLooper());
1944
1945        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1946                "foreground", BROADCAST_FG_TIMEOUT, false);
1947        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1948                "background", BROADCAST_BG_TIMEOUT, true);
1949        mBroadcastQueues[0] = mFgBroadcastQueue;
1950        mBroadcastQueues[1] = mBgBroadcastQueue;
1951
1952        mServices = new ActiveServices(this);
1953        mProviderMap = new ProviderMap(this);
1954
1955        // TODO: Move creation of battery stats service outside of activity manager service.
1956        File dataDir = Environment.getDataDirectory();
1957        File systemDir = new File(dataDir, "system");
1958        systemDir.mkdirs();
1959        mBatteryStatsService = new BatteryStatsService(new File(
1960                systemDir, "batterystats.bin").toString(), mHandler);
1961        mBatteryStatsService.getActiveStatistics().readLocked();
1962        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1963        mOnBattery = DEBUG_POWER ? true
1964                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1965        mBatteryStatsService.getActiveStatistics().setCallback(this);
1966
1967        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1968
1969        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1970        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1971
1972        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1973
1974        // User 0 is the first and only user that runs at boot.
1975        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1976        mUserLru.add(Integer.valueOf(0));
1977        updateStartedUserArrayLocked();
1978
1979        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1980            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1981
1982        mConfiguration.setToDefaults();
1983        mConfiguration.setLocale(Locale.getDefault());
1984
1985        mConfigurationSeq = mConfiguration.seq = 1;
1986        mProcessCpuTracker.init();
1987
1988        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1989        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1990        mStackSupervisor = new ActivityStackSupervisor(this);
1991
1992        mProcessCpuThread = new Thread("CpuTracker") {
1993            @Override
1994            public void run() {
1995                while (true) {
1996                    try {
1997                        try {
1998                            synchronized(this) {
1999                                final long now = SystemClock.uptimeMillis();
2000                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2001                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2002                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2003                                //        + ", write delay=" + nextWriteDelay);
2004                                if (nextWriteDelay < nextCpuDelay) {
2005                                    nextCpuDelay = nextWriteDelay;
2006                                }
2007                                if (nextCpuDelay > 0) {
2008                                    mProcessCpuMutexFree.set(true);
2009                                    this.wait(nextCpuDelay);
2010                                }
2011                            }
2012                        } catch (InterruptedException e) {
2013                        }
2014                        updateCpuStatsNow();
2015                    } catch (Exception e) {
2016                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2017                    }
2018                }
2019            }
2020        };
2021
2022        Watchdog.getInstance().addMonitor(this);
2023        Watchdog.getInstance().addThread(mHandler);
2024    }
2025
2026    private void start() {
2027        mProcessCpuThread.start();
2028
2029        mBatteryStatsService.publish(mContext);
2030        mUsageStatsService.publish(mContext);
2031        mAppOpsService.publish(mContext);
2032
2033        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2034    }
2035
2036    @Override
2037    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2038            throws RemoteException {
2039        if (code == SYSPROPS_TRANSACTION) {
2040            // We need to tell all apps about the system property change.
2041            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2042            synchronized(this) {
2043                final int NP = mProcessNames.getMap().size();
2044                for (int ip=0; ip<NP; ip++) {
2045                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2046                    final int NA = apps.size();
2047                    for (int ia=0; ia<NA; ia++) {
2048                        ProcessRecord app = apps.valueAt(ia);
2049                        if (app.thread != null) {
2050                            procs.add(app.thread.asBinder());
2051                        }
2052                    }
2053                }
2054            }
2055
2056            int N = procs.size();
2057            for (int i=0; i<N; i++) {
2058                Parcel data2 = Parcel.obtain();
2059                try {
2060                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2061                } catch (RemoteException e) {
2062                }
2063                data2.recycle();
2064            }
2065        }
2066        try {
2067            return super.onTransact(code, data, reply, flags);
2068        } catch (RuntimeException e) {
2069            // The activity manager only throws security exceptions, so let's
2070            // log all others.
2071            if (!(e instanceof SecurityException)) {
2072                Slog.wtf(TAG, "Activity Manager Crash", e);
2073            }
2074            throw e;
2075        }
2076    }
2077
2078    void updateCpuStats() {
2079        final long now = SystemClock.uptimeMillis();
2080        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2081            return;
2082        }
2083        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2084            synchronized (mProcessCpuThread) {
2085                mProcessCpuThread.notify();
2086            }
2087        }
2088    }
2089
2090    void updateCpuStatsNow() {
2091        synchronized (mProcessCpuThread) {
2092            mProcessCpuMutexFree.set(false);
2093            final long now = SystemClock.uptimeMillis();
2094            boolean haveNewCpuStats = false;
2095
2096            if (MONITOR_CPU_USAGE &&
2097                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2098                mLastCpuTime.set(now);
2099                haveNewCpuStats = true;
2100                mProcessCpuTracker.update();
2101                //Slog.i(TAG, mProcessCpu.printCurrentState());
2102                //Slog.i(TAG, "Total CPU usage: "
2103                //        + mProcessCpu.getTotalCpuPercent() + "%");
2104
2105                // Slog the cpu usage if the property is set.
2106                if ("true".equals(SystemProperties.get("events.cpu"))) {
2107                    int user = mProcessCpuTracker.getLastUserTime();
2108                    int system = mProcessCpuTracker.getLastSystemTime();
2109                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2110                    int irq = mProcessCpuTracker.getLastIrqTime();
2111                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2112                    int idle = mProcessCpuTracker.getLastIdleTime();
2113
2114                    int total = user + system + iowait + irq + softIrq + idle;
2115                    if (total == 0) total = 1;
2116
2117                    EventLog.writeEvent(EventLogTags.CPU,
2118                            ((user+system+iowait+irq+softIrq) * 100) / total,
2119                            (user * 100) / total,
2120                            (system * 100) / total,
2121                            (iowait * 100) / total,
2122                            (irq * 100) / total,
2123                            (softIrq * 100) / total);
2124                }
2125            }
2126
2127            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2128            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2129            synchronized(bstats) {
2130                synchronized(mPidsSelfLocked) {
2131                    if (haveNewCpuStats) {
2132                        if (mOnBattery) {
2133                            int perc = bstats.startAddingCpuLocked();
2134                            int totalUTime = 0;
2135                            int totalSTime = 0;
2136                            final int N = mProcessCpuTracker.countStats();
2137                            for (int i=0; i<N; i++) {
2138                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2139                                if (!st.working) {
2140                                    continue;
2141                                }
2142                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2143                                int otherUTime = (st.rel_utime*perc)/100;
2144                                int otherSTime = (st.rel_stime*perc)/100;
2145                                totalUTime += otherUTime;
2146                                totalSTime += otherSTime;
2147                                if (pr != null) {
2148                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2149                                    if (ps == null || !ps.isActive()) {
2150                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2151                                                pr.info.uid, pr.processName);
2152                                    }
2153                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2154                                            st.rel_stime-otherSTime);
2155                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2156                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2157                                } else {
2158                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2159                                    if (ps == null || !ps.isActive()) {
2160                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2161                                                bstats.mapUid(st.uid), st.name);
2162                                    }
2163                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2164                                            st.rel_stime-otherSTime);
2165                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2166                                }
2167                            }
2168                            bstats.finishAddingCpuLocked(perc, totalUTime,
2169                                    totalSTime, cpuSpeedTimes);
2170                        }
2171                    }
2172                }
2173
2174                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2175                    mLastWriteTime = now;
2176                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2177                }
2178            }
2179        }
2180    }
2181
2182    @Override
2183    public void batteryNeedsCpuUpdate() {
2184        updateCpuStatsNow();
2185    }
2186
2187    @Override
2188    public void batteryPowerChanged(boolean onBattery) {
2189        // When plugging in, update the CPU stats first before changing
2190        // the plug state.
2191        updateCpuStatsNow();
2192        synchronized (this) {
2193            synchronized(mPidsSelfLocked) {
2194                mOnBattery = DEBUG_POWER ? true : onBattery;
2195            }
2196        }
2197    }
2198
2199    /**
2200     * Initialize the application bind args. These are passed to each
2201     * process when the bindApplication() IPC is sent to the process. They're
2202     * lazily setup to make sure the services are running when they're asked for.
2203     */
2204    private HashMap<String, IBinder> getCommonServicesLocked() {
2205        if (mAppBindArgs == null) {
2206            mAppBindArgs = new HashMap<String, IBinder>();
2207
2208            // Setup the application init args
2209            mAppBindArgs.put("package", ServiceManager.getService("package"));
2210            mAppBindArgs.put("window", ServiceManager.getService("window"));
2211            mAppBindArgs.put(Context.ALARM_SERVICE,
2212                    ServiceManager.getService(Context.ALARM_SERVICE));
2213        }
2214        return mAppBindArgs;
2215    }
2216
2217    final void setFocusedActivityLocked(ActivityRecord r) {
2218        if (mFocusedActivity != r) {
2219            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2220            mFocusedActivity = r;
2221            mStackSupervisor.setFocusedStack(r);
2222            if (r != null) {
2223                mWindowManager.setFocusedApp(r.appToken, true);
2224            }
2225            applyUpdateLockStateLocked(r);
2226        }
2227    }
2228
2229    @Override
2230    public void setFocusedStack(int stackId) {
2231        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2232        synchronized (ActivityManagerService.this) {
2233            ActivityStack stack = mStackSupervisor.getStack(stackId);
2234            if (stack != null) {
2235                ActivityRecord r = stack.topRunningActivityLocked(null);
2236                if (r != null) {
2237                    setFocusedActivityLocked(r);
2238                }
2239            }
2240        }
2241    }
2242
2243    @Override
2244    public void notifyActivityDrawn(IBinder token) {
2245        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2246        synchronized (this) {
2247            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2248            if (r != null) {
2249                r.task.stack.notifyActivityDrawnLocked(r);
2250            }
2251        }
2252    }
2253
2254    final void applyUpdateLockStateLocked(ActivityRecord r) {
2255        // Modifications to the UpdateLock state are done on our handler, outside
2256        // the activity manager's locks.  The new state is determined based on the
2257        // state *now* of the relevant activity record.  The object is passed to
2258        // the handler solely for logging detail, not to be consulted/modified.
2259        final boolean nextState = r != null && r.immersive;
2260        mHandler.sendMessage(
2261                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2262    }
2263
2264    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2265        Message msg = Message.obtain();
2266        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2267        msg.obj = r.task.askedCompatMode ? null : r;
2268        mHandler.sendMessage(msg);
2269    }
2270
2271    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2272            String what, Object obj, ProcessRecord srcApp) {
2273        app.lastActivityTime = now;
2274
2275        if (app.activities.size() > 0) {
2276            // Don't want to touch dependent processes that are hosting activities.
2277            return index;
2278        }
2279
2280        int lrui = mLruProcesses.lastIndexOf(app);
2281        if (lrui < 0) {
2282            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2283                    + what + " " + obj + " from " + srcApp);
2284            return index;
2285        }
2286
2287        if (lrui >= index) {
2288            // Don't want to cause this to move dependent processes *back* in the
2289            // list as if they were less frequently used.
2290            return index;
2291        }
2292
2293        if (lrui >= mLruProcessActivityStart) {
2294            // Don't want to touch dependent processes that are hosting activities.
2295            return index;
2296        }
2297
2298        mLruProcesses.remove(lrui);
2299        if (index > 0) {
2300            index--;
2301        }
2302        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2303                + " in LRU list: " + app);
2304        mLruProcesses.add(index, app);
2305        return index;
2306    }
2307
2308    final void removeLruProcessLocked(ProcessRecord app) {
2309        int lrui = mLruProcesses.lastIndexOf(app);
2310        if (lrui >= 0) {
2311            if (lrui <= mLruProcessActivityStart) {
2312                mLruProcessActivityStart--;
2313            }
2314            if (lrui <= mLruProcessServiceStart) {
2315                mLruProcessServiceStart--;
2316            }
2317            mLruProcesses.remove(lrui);
2318        }
2319    }
2320
2321    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2322            ProcessRecord client) {
2323        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2324                || app.treatLikeActivity;
2325        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2326        if (!activityChange && hasActivity) {
2327            // The process has activities, so we are only allowing activity-based adjustments
2328            // to move it.  It should be kept in the front of the list with other
2329            // processes that have activities, and we don't want those to change their
2330            // order except due to activity operations.
2331            return;
2332        }
2333
2334        mLruSeq++;
2335        final long now = SystemClock.uptimeMillis();
2336        app.lastActivityTime = now;
2337
2338        // First a quick reject: if the app is already at the position we will
2339        // put it, then there is nothing to do.
2340        if (hasActivity) {
2341            final int N = mLruProcesses.size();
2342            if (N > 0 && mLruProcesses.get(N-1) == app) {
2343                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2344                return;
2345            }
2346        } else {
2347            if (mLruProcessServiceStart > 0
2348                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2349                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2350                return;
2351            }
2352        }
2353
2354        int lrui = mLruProcesses.lastIndexOf(app);
2355
2356        if (app.persistent && lrui >= 0) {
2357            // We don't care about the position of persistent processes, as long as
2358            // they are in the list.
2359            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2360            return;
2361        }
2362
2363        /* In progress: compute new position first, so we can avoid doing work
2364           if the process is not actually going to move.  Not yet working.
2365        int addIndex;
2366        int nextIndex;
2367        boolean inActivity = false, inService = false;
2368        if (hasActivity) {
2369            // Process has activities, put it at the very tipsy-top.
2370            addIndex = mLruProcesses.size();
2371            nextIndex = mLruProcessServiceStart;
2372            inActivity = true;
2373        } else if (hasService) {
2374            // Process has services, put it at the top of the service list.
2375            addIndex = mLruProcessActivityStart;
2376            nextIndex = mLruProcessServiceStart;
2377            inActivity = true;
2378            inService = true;
2379        } else  {
2380            // Process not otherwise of interest, it goes to the top of the non-service area.
2381            addIndex = mLruProcessServiceStart;
2382            if (client != null) {
2383                int clientIndex = mLruProcesses.lastIndexOf(client);
2384                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2385                        + app);
2386                if (clientIndex >= 0 && addIndex > clientIndex) {
2387                    addIndex = clientIndex;
2388                }
2389            }
2390            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2391        }
2392
2393        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2394                + mLruProcessActivityStart + "): " + app);
2395        */
2396
2397        if (lrui >= 0) {
2398            if (lrui < mLruProcessActivityStart) {
2399                mLruProcessActivityStart--;
2400            }
2401            if (lrui < mLruProcessServiceStart) {
2402                mLruProcessServiceStart--;
2403            }
2404            /*
2405            if (addIndex > lrui) {
2406                addIndex--;
2407            }
2408            if (nextIndex > lrui) {
2409                nextIndex--;
2410            }
2411            */
2412            mLruProcesses.remove(lrui);
2413        }
2414
2415        /*
2416        mLruProcesses.add(addIndex, app);
2417        if (inActivity) {
2418            mLruProcessActivityStart++;
2419        }
2420        if (inService) {
2421            mLruProcessActivityStart++;
2422        }
2423        */
2424
2425        int nextIndex;
2426        if (hasActivity) {
2427            final int N = mLruProcesses.size();
2428            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2429                // Process doesn't have activities, but has clients with
2430                // activities...  move it up, but one below the top (the top
2431                // should always have a real activity).
2432                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2433                mLruProcesses.add(N-1, app);
2434                // To keep it from spamming the LRU list (by making a bunch of clients),
2435                // we will push down any other entries owned by the app.
2436                final int uid = app.info.uid;
2437                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2438                    ProcessRecord subProc = mLruProcesses.get(i);
2439                    if (subProc.info.uid == uid) {
2440                        // We want to push this one down the list.  If the process after
2441                        // it is for the same uid, however, don't do so, because we don't
2442                        // want them internally to be re-ordered.
2443                        if (mLruProcesses.get(i-1).info.uid != uid) {
2444                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2445                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2446                            ProcessRecord tmp = mLruProcesses.get(i);
2447                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2448                            mLruProcesses.set(i-1, tmp);
2449                            i--;
2450                        }
2451                    } else {
2452                        // A gap, we can stop here.
2453                        break;
2454                    }
2455                }
2456            } else {
2457                // Process has activities, put it at the very tipsy-top.
2458                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2459                mLruProcesses.add(app);
2460            }
2461            nextIndex = mLruProcessServiceStart;
2462        } else if (hasService) {
2463            // Process has services, put it at the top of the service list.
2464            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2465            mLruProcesses.add(mLruProcessActivityStart, app);
2466            nextIndex = mLruProcessServiceStart;
2467            mLruProcessActivityStart++;
2468        } else  {
2469            // Process not otherwise of interest, it goes to the top of the non-service area.
2470            int index = mLruProcessServiceStart;
2471            if (client != null) {
2472                // If there is a client, don't allow the process to be moved up higher
2473                // in the list than that client.
2474                int clientIndex = mLruProcesses.lastIndexOf(client);
2475                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2476                        + " when updating " + app);
2477                if (clientIndex <= lrui) {
2478                    // Don't allow the client index restriction to push it down farther in the
2479                    // list than it already is.
2480                    clientIndex = lrui;
2481                }
2482                if (clientIndex >= 0 && index > clientIndex) {
2483                    index = clientIndex;
2484                }
2485            }
2486            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2487            mLruProcesses.add(index, app);
2488            nextIndex = index-1;
2489            mLruProcessActivityStart++;
2490            mLruProcessServiceStart++;
2491        }
2492
2493        // If the app is currently using a content provider or service,
2494        // bump those processes as well.
2495        for (int j=app.connections.size()-1; j>=0; j--) {
2496            ConnectionRecord cr = app.connections.valueAt(j);
2497            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2498                    && cr.binding.service.app != null
2499                    && cr.binding.service.app.lruSeq != mLruSeq
2500                    && !cr.binding.service.app.persistent) {
2501                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2502                        "service connection", cr, app);
2503            }
2504        }
2505        for (int j=app.conProviders.size()-1; j>=0; j--) {
2506            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2507            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2508                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2509                        "provider reference", cpr, app);
2510            }
2511        }
2512    }
2513
2514    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2515        if (uid == Process.SYSTEM_UID) {
2516            // The system gets to run in any process.  If there are multiple
2517            // processes with the same uid, just pick the first (this
2518            // should never happen).
2519            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2520            if (procs == null) return null;
2521            final int N = procs.size();
2522            for (int i = 0; i < N; i++) {
2523                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2524            }
2525        }
2526        ProcessRecord proc = mProcessNames.get(processName, uid);
2527        if (false && proc != null && !keepIfLarge
2528                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2529                && proc.lastCachedPss >= 4000) {
2530            // Turn this condition on to cause killing to happen regularly, for testing.
2531            if (proc.baseProcessTracker != null) {
2532                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2533            }
2534            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2535                    + "k from cached");
2536        } else if (proc != null && !keepIfLarge
2537                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2538                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2539            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2540            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2541                if (proc.baseProcessTracker != null) {
2542                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2543                }
2544                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2545                        + "k from cached");
2546            }
2547        }
2548        return proc;
2549    }
2550
2551    void ensurePackageDexOpt(String packageName) {
2552        IPackageManager pm = AppGlobals.getPackageManager();
2553        try {
2554            if (pm.performDexOpt(packageName)) {
2555                mDidDexOpt = true;
2556            }
2557        } catch (RemoteException e) {
2558        }
2559    }
2560
2561    boolean isNextTransitionForward() {
2562        int transit = mWindowManager.getPendingAppTransition();
2563        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2564                || transit == AppTransition.TRANSIT_TASK_OPEN
2565                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2566    }
2567
2568    final ProcessRecord startProcessLocked(String processName,
2569            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2570            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2571            boolean isolated, boolean keepIfLarge) {
2572        ProcessRecord app;
2573        if (!isolated) {
2574            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2575        } else {
2576            // If this is an isolated process, it can't re-use an existing process.
2577            app = null;
2578        }
2579        // We don't have to do anything more if:
2580        // (1) There is an existing application record; and
2581        // (2) The caller doesn't think it is dead, OR there is no thread
2582        //     object attached to it so we know it couldn't have crashed; and
2583        // (3) There is a pid assigned to it, so it is either starting or
2584        //     already running.
2585        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2586                + " app=" + app + " knownToBeDead=" + knownToBeDead
2587                + " thread=" + (app != null ? app.thread : null)
2588                + " pid=" + (app != null ? app.pid : -1));
2589        if (app != null && app.pid > 0) {
2590            if (!knownToBeDead || app.thread == null) {
2591                // We already have the app running, or are waiting for it to
2592                // come up (we have a pid but not yet its thread), so keep it.
2593                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2594                // If this is a new package in the process, add the package to the list
2595                app.addPackage(info.packageName, mProcessStats);
2596                return app;
2597            }
2598
2599            // An application record is attached to a previous process,
2600            // clean it up now.
2601            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2602            handleAppDiedLocked(app, true, true);
2603        }
2604
2605        String hostingNameStr = hostingName != null
2606                ? hostingName.flattenToShortString() : null;
2607
2608        if (!isolated) {
2609            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2610                // If we are in the background, then check to see if this process
2611                // is bad.  If so, we will just silently fail.
2612                if (mBadProcesses.get(info.processName, info.uid) != null) {
2613                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2614                            + "/" + info.processName);
2615                    return null;
2616                }
2617            } else {
2618                // When the user is explicitly starting a process, then clear its
2619                // crash count so that we won't make it bad until they see at
2620                // least one crash dialog again, and make the process good again
2621                // if it had been bad.
2622                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2623                        + "/" + info.processName);
2624                mProcessCrashTimes.remove(info.processName, info.uid);
2625                if (mBadProcesses.get(info.processName, info.uid) != null) {
2626                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2627                            UserHandle.getUserId(info.uid), info.uid,
2628                            info.processName);
2629                    mBadProcesses.remove(info.processName, info.uid);
2630                    if (app != null) {
2631                        app.bad = false;
2632                    }
2633                }
2634            }
2635        }
2636
2637        if (app == null) {
2638            app = newProcessRecordLocked(info, processName, isolated);
2639            if (app == null) {
2640                Slog.w(TAG, "Failed making new process record for "
2641                        + processName + "/" + info.uid + " isolated=" + isolated);
2642                return null;
2643            }
2644            mProcessNames.put(processName, app.uid, app);
2645            if (isolated) {
2646                mIsolatedProcesses.put(app.uid, app);
2647            }
2648        } else {
2649            // If this is a new package in the process, add the package to the list
2650            app.addPackage(info.packageName, mProcessStats);
2651        }
2652
2653        // If the system is not ready yet, then hold off on starting this
2654        // process until it is.
2655        if (!mProcessesReady
2656                && !isAllowedWhileBooting(info)
2657                && !allowWhileBooting) {
2658            if (!mProcessesOnHold.contains(app)) {
2659                mProcessesOnHold.add(app);
2660            }
2661            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2662            return app;
2663        }
2664
2665        startProcessLocked(app, hostingType, hostingNameStr);
2666        return (app.pid != 0) ? app : null;
2667    }
2668
2669    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2670        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2671    }
2672
2673    private final void startProcessLocked(ProcessRecord app,
2674            String hostingType, String hostingNameStr) {
2675        if (app.pid > 0 && app.pid != MY_PID) {
2676            synchronized (mPidsSelfLocked) {
2677                mPidsSelfLocked.remove(app.pid);
2678                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2679            }
2680            app.setPid(0);
2681        }
2682
2683        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2684                "startProcessLocked removing on hold: " + app);
2685        mProcessesOnHold.remove(app);
2686
2687        updateCpuStats();
2688
2689        try {
2690            int uid = app.uid;
2691
2692            int[] gids = null;
2693            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2694            if (!app.isolated) {
2695                int[] permGids = null;
2696                try {
2697                    final PackageManager pm = mContext.getPackageManager();
2698                    permGids = pm.getPackageGids(app.info.packageName);
2699
2700                    if (Environment.isExternalStorageEmulated()) {
2701                        if (pm.checkPermission(
2702                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2703                                app.info.packageName) == PERMISSION_GRANTED) {
2704                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2705                        } else {
2706                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2707                        }
2708                    }
2709                } catch (PackageManager.NameNotFoundException e) {
2710                    Slog.w(TAG, "Unable to retrieve gids", e);
2711                }
2712
2713                /*
2714                 * Add shared application GID so applications can share some
2715                 * resources like shared libraries
2716                 */
2717                if (permGids == null) {
2718                    gids = new int[1];
2719                } else {
2720                    gids = new int[permGids.length + 1];
2721                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2722                }
2723                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2724            }
2725            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2726                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2727                        && mTopComponent != null
2728                        && app.processName.equals(mTopComponent.getPackageName())) {
2729                    uid = 0;
2730                }
2731                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2732                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2733                    uid = 0;
2734                }
2735            }
2736            int debugFlags = 0;
2737            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2738                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2739                // Also turn on CheckJNI for debuggable apps. It's quite
2740                // awkward to turn on otherwise.
2741                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2742            }
2743            // Run the app in safe mode if its manifest requests so or the
2744            // system is booted in safe mode.
2745            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2746                mSafeMode == true) {
2747                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2748            }
2749            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2750                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2751            }
2752            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2753                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2754            }
2755            if ("1".equals(SystemProperties.get("debug.assert"))) {
2756                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2757            }
2758
2759            String requiredAbi = app.info.requiredCpuAbi;
2760            if (requiredAbi == null) {
2761                requiredAbi = Build.SUPPORTED_ABIS[0];
2762            }
2763
2764            // Start the process.  It will either succeed and return a result containing
2765            // the PID of the new process, or else throw a RuntimeException.
2766            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2767                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2768                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2769
2770            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2771            synchronized (bs) {
2772                if (bs.isOnBattery()) {
2773                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2774                }
2775            }
2776
2777            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2778                    UserHandle.getUserId(uid), startResult.pid, uid,
2779                    app.processName, hostingType,
2780                    hostingNameStr != null ? hostingNameStr : "");
2781
2782            if (app.persistent) {
2783                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2784            }
2785
2786            StringBuilder buf = mStringBuilder;
2787            buf.setLength(0);
2788            buf.append("Start proc ");
2789            buf.append(app.processName);
2790            buf.append(" for ");
2791            buf.append(hostingType);
2792            if (hostingNameStr != null) {
2793                buf.append(" ");
2794                buf.append(hostingNameStr);
2795            }
2796            buf.append(": pid=");
2797            buf.append(startResult.pid);
2798            buf.append(" uid=");
2799            buf.append(uid);
2800            buf.append(" gids={");
2801            if (gids != null) {
2802                for (int gi=0; gi<gids.length; gi++) {
2803                    if (gi != 0) buf.append(", ");
2804                    buf.append(gids[gi]);
2805
2806                }
2807            }
2808            buf.append("}");
2809            Slog.i(TAG, buf.toString());
2810            app.setPid(startResult.pid);
2811            app.usingWrapper = startResult.usingWrapper;
2812            app.removed = false;
2813            synchronized (mPidsSelfLocked) {
2814                this.mPidsSelfLocked.put(startResult.pid, app);
2815                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2816                msg.obj = app;
2817                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2818                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2819            }
2820            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2821                    app.processName, app.info.uid);
2822            if (app.isolated) {
2823                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2824            }
2825        } catch (RuntimeException e) {
2826            // XXX do better error recovery.
2827            app.setPid(0);
2828            Slog.e(TAG, "Failure starting process " + app.processName, e);
2829        }
2830    }
2831
2832    void updateUsageStats(ActivityRecord component, boolean resumed) {
2833        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2834        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2835        if (resumed) {
2836            mUsageStatsService.noteResumeComponent(component.realActivity);
2837            synchronized (stats) {
2838                stats.noteActivityResumedLocked(component.app.uid);
2839            }
2840        } else {
2841            mUsageStatsService.notePauseComponent(component.realActivity);
2842            synchronized (stats) {
2843                stats.noteActivityPausedLocked(component.app.uid);
2844            }
2845        }
2846    }
2847
2848    Intent getHomeIntent() {
2849        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2850        intent.setComponent(mTopComponent);
2851        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2852            intent.addCategory(Intent.CATEGORY_HOME);
2853        }
2854        return intent;
2855    }
2856
2857    boolean startHomeActivityLocked(int userId) {
2858        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2859                && mTopAction == null) {
2860            // We are running in factory test mode, but unable to find
2861            // the factory test app, so just sit around displaying the
2862            // error message and don't try to start anything.
2863            return false;
2864        }
2865        Intent intent = getHomeIntent();
2866        ActivityInfo aInfo =
2867            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2868        if (aInfo != null) {
2869            intent.setComponent(new ComponentName(
2870                    aInfo.applicationInfo.packageName, aInfo.name));
2871            // Don't do this if the home app is currently being
2872            // instrumented.
2873            aInfo = new ActivityInfo(aInfo);
2874            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2875            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2876                    aInfo.applicationInfo.uid, true);
2877            if (app == null || app.instrumentationClass == null) {
2878                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2879                mStackSupervisor.startHomeActivity(intent, aInfo);
2880            }
2881        }
2882
2883        return true;
2884    }
2885
2886    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2887        ActivityInfo ai = null;
2888        ComponentName comp = intent.getComponent();
2889        try {
2890            if (comp != null) {
2891                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2892            } else {
2893                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2894                        intent,
2895                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2896                            flags, userId);
2897
2898                if (info != null) {
2899                    ai = info.activityInfo;
2900                }
2901            }
2902        } catch (RemoteException e) {
2903            // ignore
2904        }
2905
2906        return ai;
2907    }
2908
2909    /**
2910     * Starts the "new version setup screen" if appropriate.
2911     */
2912    void startSetupActivityLocked() {
2913        // Only do this once per boot.
2914        if (mCheckedForSetup) {
2915            return;
2916        }
2917
2918        // We will show this screen if the current one is a different
2919        // version than the last one shown, and we are not running in
2920        // low-level factory test mode.
2921        final ContentResolver resolver = mContext.getContentResolver();
2922        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2923                Settings.Global.getInt(resolver,
2924                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2925            mCheckedForSetup = true;
2926
2927            // See if we should be showing the platform update setup UI.
2928            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2929            List<ResolveInfo> ris = mContext.getPackageManager()
2930                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2931
2932            // We don't allow third party apps to replace this.
2933            ResolveInfo ri = null;
2934            for (int i=0; ris != null && i<ris.size(); i++) {
2935                if ((ris.get(i).activityInfo.applicationInfo.flags
2936                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2937                    ri = ris.get(i);
2938                    break;
2939                }
2940            }
2941
2942            if (ri != null) {
2943                String vers = ri.activityInfo.metaData != null
2944                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2945                        : null;
2946                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2947                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2948                            Intent.METADATA_SETUP_VERSION);
2949                }
2950                String lastVers = Settings.Secure.getString(
2951                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2952                if (vers != null && !vers.equals(lastVers)) {
2953                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2954                    intent.setComponent(new ComponentName(
2955                            ri.activityInfo.packageName, ri.activityInfo.name));
2956                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2957                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2958                }
2959            }
2960        }
2961    }
2962
2963    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2964        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2965    }
2966
2967    void enforceNotIsolatedCaller(String caller) {
2968        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2969            throw new SecurityException("Isolated process not allowed to call " + caller);
2970        }
2971    }
2972
2973    @Override
2974    public int getFrontActivityScreenCompatMode() {
2975        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2976        synchronized (this) {
2977            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2978        }
2979    }
2980
2981    @Override
2982    public void setFrontActivityScreenCompatMode(int mode) {
2983        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2984                "setFrontActivityScreenCompatMode");
2985        synchronized (this) {
2986            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2987        }
2988    }
2989
2990    @Override
2991    public int getPackageScreenCompatMode(String packageName) {
2992        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2993        synchronized (this) {
2994            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2995        }
2996    }
2997
2998    @Override
2999    public void setPackageScreenCompatMode(String packageName, int mode) {
3000        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3001                "setPackageScreenCompatMode");
3002        synchronized (this) {
3003            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3004        }
3005    }
3006
3007    @Override
3008    public boolean getPackageAskScreenCompat(String packageName) {
3009        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3010        synchronized (this) {
3011            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3012        }
3013    }
3014
3015    @Override
3016    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3017        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3018                "setPackageAskScreenCompat");
3019        synchronized (this) {
3020            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3021        }
3022    }
3023
3024    private void dispatchProcessesChanged() {
3025        int N;
3026        synchronized (this) {
3027            N = mPendingProcessChanges.size();
3028            if (mActiveProcessChanges.length < N) {
3029                mActiveProcessChanges = new ProcessChangeItem[N];
3030            }
3031            mPendingProcessChanges.toArray(mActiveProcessChanges);
3032            mAvailProcessChanges.addAll(mPendingProcessChanges);
3033            mPendingProcessChanges.clear();
3034            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3035        }
3036
3037        int i = mProcessObservers.beginBroadcast();
3038        while (i > 0) {
3039            i--;
3040            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3041            if (observer != null) {
3042                try {
3043                    for (int j=0; j<N; j++) {
3044                        ProcessChangeItem item = mActiveProcessChanges[j];
3045                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3046                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3047                                    + item.pid + " uid=" + item.uid + ": "
3048                                    + item.foregroundActivities);
3049                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3050                                    item.foregroundActivities);
3051                        }
3052                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3053                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3054                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3055                            observer.onImportanceChanged(item.pid, item.uid,
3056                                    item.importance);
3057                        }
3058                    }
3059                } catch (RemoteException e) {
3060                }
3061            }
3062        }
3063        mProcessObservers.finishBroadcast();
3064    }
3065
3066    private void dispatchProcessDied(int pid, int uid) {
3067        int i = mProcessObservers.beginBroadcast();
3068        while (i > 0) {
3069            i--;
3070            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3071            if (observer != null) {
3072                try {
3073                    observer.onProcessDied(pid, uid);
3074                } catch (RemoteException e) {
3075                }
3076            }
3077        }
3078        mProcessObservers.finishBroadcast();
3079    }
3080
3081    final void doPendingActivityLaunchesLocked(boolean doResume) {
3082        final int N = mPendingActivityLaunches.size();
3083        if (N <= 0) {
3084            return;
3085        }
3086        for (int i=0; i<N; i++) {
3087            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3088            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3089                    doResume && i == (N-1), null);
3090        }
3091        mPendingActivityLaunches.clear();
3092    }
3093
3094    @Override
3095    public final int startActivity(IApplicationThread caller, String callingPackage,
3096            Intent intent, String resolvedType, IBinder resultTo,
3097            String resultWho, int requestCode, int startFlags,
3098            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3099        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3100                resultWho, requestCode,
3101                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3102    }
3103
3104    @Override
3105    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3106            Intent intent, String resolvedType, IBinder resultTo,
3107            String resultWho, int requestCode, int startFlags,
3108            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3109        enforceNotIsolatedCaller("startActivity");
3110        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3111                false, true, "startActivity", null);
3112        // TODO: Switch to user app stacks here.
3113        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3114                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3115                null, null, options, userId, null);
3116    }
3117
3118    @Override
3119    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3120            Intent intent, String resolvedType, IBinder resultTo,
3121            String resultWho, int requestCode, int startFlags, String profileFile,
3122            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3123        enforceNotIsolatedCaller("startActivityAndWait");
3124        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3125                false, true, "startActivityAndWait", null);
3126        WaitResult res = new WaitResult();
3127        // TODO: Switch to user app stacks here.
3128        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3129                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3130                res, null, options, UserHandle.getCallingUserId(), null);
3131        return res;
3132    }
3133
3134    @Override
3135    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3136            Intent intent, String resolvedType, IBinder resultTo,
3137            String resultWho, int requestCode, int startFlags, Configuration config,
3138            Bundle options, int userId) {
3139        enforceNotIsolatedCaller("startActivityWithConfig");
3140        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3141                false, true, "startActivityWithConfig", null);
3142        // TODO: Switch to user app stacks here.
3143        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3144                resolvedType, resultTo, resultWho, requestCode, startFlags,
3145                null, null, null, config, options, userId, null);
3146        return ret;
3147    }
3148
3149    @Override
3150    public int startActivityIntentSender(IApplicationThread caller,
3151            IntentSender intent, Intent fillInIntent, String resolvedType,
3152            IBinder resultTo, String resultWho, int requestCode,
3153            int flagsMask, int flagsValues, Bundle options) {
3154        enforceNotIsolatedCaller("startActivityIntentSender");
3155        // Refuse possible leaked file descriptors
3156        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3157            throw new IllegalArgumentException("File descriptors passed in Intent");
3158        }
3159
3160        IIntentSender sender = intent.getTarget();
3161        if (!(sender instanceof PendingIntentRecord)) {
3162            throw new IllegalArgumentException("Bad PendingIntent object");
3163        }
3164
3165        PendingIntentRecord pir = (PendingIntentRecord)sender;
3166
3167        synchronized (this) {
3168            // If this is coming from the currently resumed activity, it is
3169            // effectively saying that app switches are allowed at this point.
3170            final ActivityStack stack = getFocusedStack();
3171            if (stack.mResumedActivity != null &&
3172                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3173                mAppSwitchesAllowedTime = 0;
3174            }
3175        }
3176        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3177                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3178        return ret;
3179    }
3180
3181    @Override
3182    public boolean startNextMatchingActivity(IBinder callingActivity,
3183            Intent intent, Bundle options) {
3184        // Refuse possible leaked file descriptors
3185        if (intent != null && intent.hasFileDescriptors() == true) {
3186            throw new IllegalArgumentException("File descriptors passed in Intent");
3187        }
3188
3189        synchronized (this) {
3190            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3191            if (r == null) {
3192                ActivityOptions.abort(options);
3193                return false;
3194            }
3195            if (r.app == null || r.app.thread == null) {
3196                // The caller is not running...  d'oh!
3197                ActivityOptions.abort(options);
3198                return false;
3199            }
3200            intent = new Intent(intent);
3201            // The caller is not allowed to change the data.
3202            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3203            // And we are resetting to find the next component...
3204            intent.setComponent(null);
3205
3206            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3207
3208            ActivityInfo aInfo = null;
3209            try {
3210                List<ResolveInfo> resolves =
3211                    AppGlobals.getPackageManager().queryIntentActivities(
3212                            intent, r.resolvedType,
3213                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3214                            UserHandle.getCallingUserId());
3215
3216                // Look for the original activity in the list...
3217                final int N = resolves != null ? resolves.size() : 0;
3218                for (int i=0; i<N; i++) {
3219                    ResolveInfo rInfo = resolves.get(i);
3220                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3221                            && rInfo.activityInfo.name.equals(r.info.name)) {
3222                        // We found the current one...  the next matching is
3223                        // after it.
3224                        i++;
3225                        if (i<N) {
3226                            aInfo = resolves.get(i).activityInfo;
3227                        }
3228                        if (debug) {
3229                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3230                                    + "/" + r.info.name);
3231                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3232                                    + "/" + aInfo.name);
3233                        }
3234                        break;
3235                    }
3236                }
3237            } catch (RemoteException e) {
3238            }
3239
3240            if (aInfo == null) {
3241                // Nobody who is next!
3242                ActivityOptions.abort(options);
3243                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3244                return false;
3245            }
3246
3247            intent.setComponent(new ComponentName(
3248                    aInfo.applicationInfo.packageName, aInfo.name));
3249            intent.setFlags(intent.getFlags()&~(
3250                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3251                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3252                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3253                    Intent.FLAG_ACTIVITY_NEW_TASK));
3254
3255            // Okay now we need to start the new activity, replacing the
3256            // currently running activity.  This is a little tricky because
3257            // we want to start the new one as if the current one is finished,
3258            // but not finish the current one first so that there is no flicker.
3259            // And thus...
3260            final boolean wasFinishing = r.finishing;
3261            r.finishing = true;
3262
3263            // Propagate reply information over to the new activity.
3264            final ActivityRecord resultTo = r.resultTo;
3265            final String resultWho = r.resultWho;
3266            final int requestCode = r.requestCode;
3267            r.resultTo = null;
3268            if (resultTo != null) {
3269                resultTo.removeResultsLocked(r, resultWho, requestCode);
3270            }
3271
3272            final long origId = Binder.clearCallingIdentity();
3273            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3274                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3275                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3276                    options, false, null, null);
3277            Binder.restoreCallingIdentity(origId);
3278
3279            r.finishing = wasFinishing;
3280            if (res != ActivityManager.START_SUCCESS) {
3281                return false;
3282            }
3283            return true;
3284        }
3285    }
3286
3287    final int startActivityInPackage(int uid, String callingPackage,
3288            Intent intent, String resolvedType, IBinder resultTo,
3289            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3290                    IActivityContainer container) {
3291
3292        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3293                false, true, "startActivityInPackage", null);
3294
3295        // TODO: Switch to user app stacks here.
3296        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3297                resultTo, resultWho, requestCode, startFlags,
3298                null, null, null, null, options, userId, container);
3299        return ret;
3300    }
3301
3302    @Override
3303    public final int startActivities(IApplicationThread caller, String callingPackage,
3304            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3305            int userId) {
3306        enforceNotIsolatedCaller("startActivities");
3307        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3308                false, true, "startActivity", null);
3309        // TODO: Switch to user app stacks here.
3310        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3311                resolvedTypes, resultTo, options, userId);
3312        return ret;
3313    }
3314
3315    final int startActivitiesInPackage(int uid, String callingPackage,
3316            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3317            Bundle options, int userId) {
3318
3319        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3320                false, true, "startActivityInPackage", null);
3321        // TODO: Switch to user app stacks here.
3322        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3323                resultTo, options, userId);
3324        return ret;
3325    }
3326
3327    final void addRecentTaskLocked(TaskRecord task) {
3328        int N = mRecentTasks.size();
3329        // Quick case: check if the top-most recent task is the same.
3330        if (N > 0 && mRecentTasks.get(0) == task) {
3331            return;
3332        }
3333        // Remove any existing entries that are the same kind of task.
3334        final Intent intent = task.intent;
3335        final boolean document = intent != null && intent.isDocument();
3336        for (int i=0; i<N; i++) {
3337            TaskRecord tr = mRecentTasks.get(i);
3338            if (task != tr) {
3339                if (task.userId != tr.userId) {
3340                    continue;
3341                }
3342                final Intent trIntent = tr.intent;
3343                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3344                    (intent == null || !intent.filterEquals(trIntent))) {
3345                    continue;
3346                }
3347                if (document || trIntent != null && trIntent.isDocument()) {
3348                    // Document tasks do not match other tasks.
3349                    continue;
3350                }
3351            }
3352
3353            // Either task and tr are the same or, their affinities match or their intents match
3354            // and neither of them is a document.
3355            tr.disposeThumbnail();
3356            mRecentTasks.remove(i);
3357            i--;
3358            N--;
3359            if (task.intent == null) {
3360                // If the new recent task we are adding is not fully
3361                // specified, then replace it with the existing recent task.
3362                task = tr;
3363            }
3364        }
3365        if (N >= MAX_RECENT_TASKS) {
3366            mRecentTasks.remove(N-1).disposeThumbnail();
3367        }
3368        mRecentTasks.add(0, task);
3369    }
3370
3371    @Override
3372    public void reportActivityFullyDrawn(IBinder token) {
3373        synchronized (this) {
3374            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3375            if (r == null) {
3376                return;
3377            }
3378            r.reportFullyDrawnLocked();
3379        }
3380    }
3381
3382    @Override
3383    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3384        synchronized (this) {
3385            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3386            if (r == null) {
3387                return;
3388            }
3389            final long origId = Binder.clearCallingIdentity();
3390            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3391            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3392                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3393            if (config != null) {
3394                r.frozenBeforeDestroy = true;
3395                if (!updateConfigurationLocked(config, r, false, false)) {
3396                    mStackSupervisor.resumeTopActivitiesLocked();
3397                }
3398            }
3399            Binder.restoreCallingIdentity(origId);
3400        }
3401    }
3402
3403    @Override
3404    public int getRequestedOrientation(IBinder token) {
3405        synchronized (this) {
3406            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3407            if (r == null) {
3408                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3409            }
3410            return mWindowManager.getAppOrientation(r.appToken);
3411        }
3412    }
3413
3414    /**
3415     * This is the internal entry point for handling Activity.finish().
3416     *
3417     * @param token The Binder token referencing the Activity we want to finish.
3418     * @param resultCode Result code, if any, from this Activity.
3419     * @param resultData Result data (Intent), if any, from this Activity.
3420     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3421     *            the root Activity in the task.
3422     *
3423     * @return Returns true if the activity successfully finished, or false if it is still running.
3424     */
3425    @Override
3426    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3427            boolean finishTask) {
3428        // Refuse possible leaked file descriptors
3429        if (resultData != null && resultData.hasFileDescriptors() == true) {
3430            throw new IllegalArgumentException("File descriptors passed in Intent");
3431        }
3432
3433        synchronized(this) {
3434            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3435            if (r == null) {
3436                return true;
3437            }
3438            // Keep track of the root activity of the task before we finish it
3439            TaskRecord tr = r.task;
3440            ActivityRecord rootR = tr.getRootActivity();
3441            if (mController != null) {
3442                // Find the first activity that is not finishing.
3443                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3444                if (next != null) {
3445                    // ask watcher if this is allowed
3446                    boolean resumeOK = true;
3447                    try {
3448                        resumeOK = mController.activityResuming(next.packageName);
3449                    } catch (RemoteException e) {
3450                        mController = null;
3451                        Watchdog.getInstance().setActivityController(null);
3452                    }
3453
3454                    if (!resumeOK) {
3455                        return false;
3456                    }
3457                }
3458            }
3459            final long origId = Binder.clearCallingIdentity();
3460            try {
3461                boolean res;
3462                if (finishTask && r == rootR) {
3463                    // If requested, remove the task that is associated to this activity only if it
3464                    // was the root activity in the task.  The result code and data is ignored because
3465                    // we don't support returning them across task boundaries.
3466                    res = removeTaskByIdLocked(tr.taskId, 0);
3467                } else {
3468                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3469                            resultData, "app-request", true);
3470                }
3471                return res;
3472            } finally {
3473                Binder.restoreCallingIdentity(origId);
3474            }
3475        }
3476    }
3477
3478    @Override
3479    public final void finishHeavyWeightApp() {
3480        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3481                != PackageManager.PERMISSION_GRANTED) {
3482            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3483                    + Binder.getCallingPid()
3484                    + ", uid=" + Binder.getCallingUid()
3485                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3486            Slog.w(TAG, msg);
3487            throw new SecurityException(msg);
3488        }
3489
3490        synchronized(this) {
3491            if (mHeavyWeightProcess == null) {
3492                return;
3493            }
3494
3495            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3496                    mHeavyWeightProcess.activities);
3497            for (int i=0; i<activities.size(); i++) {
3498                ActivityRecord r = activities.get(i);
3499                if (!r.finishing) {
3500                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3501                            null, "finish-heavy", true);
3502                }
3503            }
3504
3505            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3506                    mHeavyWeightProcess.userId, 0));
3507            mHeavyWeightProcess = null;
3508        }
3509    }
3510
3511    @Override
3512    public void crashApplication(int uid, int initialPid, String packageName,
3513            String message) {
3514        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3515                != PackageManager.PERMISSION_GRANTED) {
3516            String msg = "Permission Denial: crashApplication() from pid="
3517                    + Binder.getCallingPid()
3518                    + ", uid=" + Binder.getCallingUid()
3519                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3520            Slog.w(TAG, msg);
3521            throw new SecurityException(msg);
3522        }
3523
3524        synchronized(this) {
3525            ProcessRecord proc = null;
3526
3527            // Figure out which process to kill.  We don't trust that initialPid
3528            // still has any relation to current pids, so must scan through the
3529            // list.
3530            synchronized (mPidsSelfLocked) {
3531                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3532                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3533                    if (p.uid != uid) {
3534                        continue;
3535                    }
3536                    if (p.pid == initialPid) {
3537                        proc = p;
3538                        break;
3539                    }
3540                    if (p.pkgList.containsKey(packageName)) {
3541                        proc = p;
3542                    }
3543                }
3544            }
3545
3546            if (proc == null) {
3547                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3548                        + " initialPid=" + initialPid
3549                        + " packageName=" + packageName);
3550                return;
3551            }
3552
3553            if (proc.thread != null) {
3554                if (proc.pid == Process.myPid()) {
3555                    Log.w(TAG, "crashApplication: trying to crash self!");
3556                    return;
3557                }
3558                long ident = Binder.clearCallingIdentity();
3559                try {
3560                    proc.thread.scheduleCrash(message);
3561                } catch (RemoteException e) {
3562                }
3563                Binder.restoreCallingIdentity(ident);
3564            }
3565        }
3566    }
3567
3568    @Override
3569    public final void finishSubActivity(IBinder token, String resultWho,
3570            int requestCode) {
3571        synchronized(this) {
3572            final long origId = Binder.clearCallingIdentity();
3573            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3574            if (r != null) {
3575                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3576            }
3577            Binder.restoreCallingIdentity(origId);
3578        }
3579    }
3580
3581    @Override
3582    public boolean finishActivityAffinity(IBinder token) {
3583        synchronized(this) {
3584            final long origId = Binder.clearCallingIdentity();
3585            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3586            boolean res = false;
3587            if (r != null) {
3588                res = r.task.stack.finishActivityAffinityLocked(r);
3589            }
3590            Binder.restoreCallingIdentity(origId);
3591            return res;
3592        }
3593    }
3594
3595    @Override
3596    public boolean willActivityBeVisible(IBinder token) {
3597        synchronized(this) {
3598            ActivityStack stack = ActivityRecord.getStackLocked(token);
3599            if (stack != null) {
3600                return stack.willActivityBeVisibleLocked(token);
3601            }
3602            return false;
3603        }
3604    }
3605
3606    @Override
3607    public void overridePendingTransition(IBinder token, String packageName,
3608            int enterAnim, int exitAnim) {
3609        synchronized(this) {
3610            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3611            if (self == null) {
3612                return;
3613            }
3614
3615            final long origId = Binder.clearCallingIdentity();
3616
3617            if (self.state == ActivityState.RESUMED
3618                    || self.state == ActivityState.PAUSING) {
3619                mWindowManager.overridePendingAppTransition(packageName,
3620                        enterAnim, exitAnim, null);
3621            }
3622
3623            Binder.restoreCallingIdentity(origId);
3624        }
3625    }
3626
3627    /**
3628     * Main function for removing an existing process from the activity manager
3629     * as a result of that process going away.  Clears out all connections
3630     * to the process.
3631     */
3632    private final void handleAppDiedLocked(ProcessRecord app,
3633            boolean restarting, boolean allowRestart) {
3634        int pid = app.pid;
3635        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3636        if (!restarting) {
3637            removeLruProcessLocked(app);
3638            if (pid > 0) {
3639                ProcessList.remove(pid);
3640            }
3641        }
3642
3643        if (mProfileProc == app) {
3644            clearProfilerLocked();
3645        }
3646
3647        // Remove this application's activities from active lists.
3648        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3649
3650        app.activities.clear();
3651
3652        if (app.instrumentationClass != null) {
3653            Slog.w(TAG, "Crash of app " + app.processName
3654                  + " running instrumentation " + app.instrumentationClass);
3655            Bundle info = new Bundle();
3656            info.putString("shortMsg", "Process crashed.");
3657            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3658        }
3659
3660        if (!restarting) {
3661            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3662                // If there was nothing to resume, and we are not already
3663                // restarting this process, but there is a visible activity that
3664                // is hosted by the process...  then make sure all visible
3665                // activities are running, taking care of restarting this
3666                // process.
3667                if (hasVisibleActivities) {
3668                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3669                }
3670            }
3671        }
3672    }
3673
3674    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3675        IBinder threadBinder = thread.asBinder();
3676        // Find the application record.
3677        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3678            ProcessRecord rec = mLruProcesses.get(i);
3679            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3680                return i;
3681            }
3682        }
3683        return -1;
3684    }
3685
3686    final ProcessRecord getRecordForAppLocked(
3687            IApplicationThread thread) {
3688        if (thread == null) {
3689            return null;
3690        }
3691
3692        int appIndex = getLRURecordIndexForAppLocked(thread);
3693        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3694    }
3695
3696    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3697        // If there are no longer any background processes running,
3698        // and the app that died was not running instrumentation,
3699        // then tell everyone we are now low on memory.
3700        boolean haveBg = false;
3701        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3702            ProcessRecord rec = mLruProcesses.get(i);
3703            if (rec.thread != null
3704                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3705                haveBg = true;
3706                break;
3707            }
3708        }
3709
3710        if (!haveBg) {
3711            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3712            if (doReport) {
3713                long now = SystemClock.uptimeMillis();
3714                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3715                    doReport = false;
3716                } else {
3717                    mLastMemUsageReportTime = now;
3718                }
3719            }
3720            final ArrayList<ProcessMemInfo> memInfos
3721                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3722            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3723            long now = SystemClock.uptimeMillis();
3724            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3725                ProcessRecord rec = mLruProcesses.get(i);
3726                if (rec == dyingProc || rec.thread == null) {
3727                    continue;
3728                }
3729                if (doReport) {
3730                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3731                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3732                }
3733                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3734                    // The low memory report is overriding any current
3735                    // state for a GC request.  Make sure to do
3736                    // heavy/important/visible/foreground processes first.
3737                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3738                        rec.lastRequestedGc = 0;
3739                    } else {
3740                        rec.lastRequestedGc = rec.lastLowMemory;
3741                    }
3742                    rec.reportLowMemory = true;
3743                    rec.lastLowMemory = now;
3744                    mProcessesToGc.remove(rec);
3745                    addProcessToGcListLocked(rec);
3746                }
3747            }
3748            if (doReport) {
3749                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3750                mHandler.sendMessage(msg);
3751            }
3752            scheduleAppGcsLocked();
3753        }
3754    }
3755
3756    final void appDiedLocked(ProcessRecord app, int pid,
3757            IApplicationThread thread) {
3758
3759        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3760        synchronized (stats) {
3761            stats.noteProcessDiedLocked(app.info.uid, pid);
3762        }
3763
3764        // Clean up already done if the process has been re-started.
3765        if (app.pid == pid && app.thread != null &&
3766                app.thread.asBinder() == thread.asBinder()) {
3767            boolean doLowMem = app.instrumentationClass == null;
3768            boolean doOomAdj = doLowMem;
3769            if (!app.killedByAm) {
3770                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3771                        + ") has died.");
3772                mAllowLowerMemLevel = true;
3773            } else {
3774                // Note that we always want to do oom adj to update our state with the
3775                // new number of procs.
3776                mAllowLowerMemLevel = false;
3777                doLowMem = false;
3778            }
3779            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3780            if (DEBUG_CLEANUP) Slog.v(
3781                TAG, "Dying app: " + app + ", pid: " + pid
3782                + ", thread: " + thread.asBinder());
3783            handleAppDiedLocked(app, false, true);
3784
3785            if (doOomAdj) {
3786                updateOomAdjLocked();
3787            }
3788            if (doLowMem) {
3789                doLowMemReportIfNeededLocked(app);
3790            }
3791        } else if (app.pid != pid) {
3792            // A new process has already been started.
3793            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3794                    + ") has died and restarted (pid " + app.pid + ").");
3795            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3796        } else if (DEBUG_PROCESSES) {
3797            Slog.d(TAG, "Received spurious death notification for thread "
3798                    + thread.asBinder());
3799        }
3800    }
3801
3802    /**
3803     * If a stack trace dump file is configured, dump process stack traces.
3804     * @param clearTraces causes the dump file to be erased prior to the new
3805     *    traces being written, if true; when false, the new traces will be
3806     *    appended to any existing file content.
3807     * @param firstPids of dalvik VM processes to dump stack traces for first
3808     * @param lastPids of dalvik VM processes to dump stack traces for last
3809     * @param nativeProcs optional list of native process names to dump stack crawls
3810     * @return file containing stack traces, or null if no dump file is configured
3811     */
3812    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3813            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3814        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3815        if (tracesPath == null || tracesPath.length() == 0) {
3816            return null;
3817        }
3818
3819        File tracesFile = new File(tracesPath);
3820        try {
3821            File tracesDir = tracesFile.getParentFile();
3822            if (!tracesDir.exists()) {
3823                tracesFile.mkdirs();
3824                if (!SELinux.restorecon(tracesDir)) {
3825                    return null;
3826                }
3827            }
3828            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3829
3830            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3831            tracesFile.createNewFile();
3832            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3833        } catch (IOException e) {
3834            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3835            return null;
3836        }
3837
3838        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3839        return tracesFile;
3840    }
3841
3842    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3843            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3844        // Use a FileObserver to detect when traces finish writing.
3845        // The order of traces is considered important to maintain for legibility.
3846        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3847            @Override
3848            public synchronized void onEvent(int event, String path) { notify(); }
3849        };
3850
3851        try {
3852            observer.startWatching();
3853
3854            // First collect all of the stacks of the most important pids.
3855            if (firstPids != null) {
3856                try {
3857                    int num = firstPids.size();
3858                    for (int i = 0; i < num; i++) {
3859                        synchronized (observer) {
3860                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3861                            observer.wait(200);  // Wait for write-close, give up after 200msec
3862                        }
3863                    }
3864                } catch (InterruptedException e) {
3865                    Log.wtf(TAG, e);
3866                }
3867            }
3868
3869            // Next collect the stacks of the native pids
3870            if (nativeProcs != null) {
3871                int[] pids = Process.getPidsForCommands(nativeProcs);
3872                if (pids != null) {
3873                    for (int pid : pids) {
3874                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3875                    }
3876                }
3877            }
3878
3879            // Lastly, measure CPU usage.
3880            if (processCpuTracker != null) {
3881                processCpuTracker.init();
3882                System.gc();
3883                processCpuTracker.update();
3884                try {
3885                    synchronized (processCpuTracker) {
3886                        processCpuTracker.wait(500); // measure over 1/2 second.
3887                    }
3888                } catch (InterruptedException e) {
3889                }
3890                processCpuTracker.update();
3891
3892                // We'll take the stack crawls of just the top apps using CPU.
3893                final int N = processCpuTracker.countWorkingStats();
3894                int numProcs = 0;
3895                for (int i=0; i<N && numProcs<5; i++) {
3896                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3897                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3898                        numProcs++;
3899                        try {
3900                            synchronized (observer) {
3901                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3902                                observer.wait(200);  // Wait for write-close, give up after 200msec
3903                            }
3904                        } catch (InterruptedException e) {
3905                            Log.wtf(TAG, e);
3906                        }
3907
3908                    }
3909                }
3910            }
3911        } finally {
3912            observer.stopWatching();
3913        }
3914    }
3915
3916    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3917        if (true || IS_USER_BUILD) {
3918            return;
3919        }
3920        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3921        if (tracesPath == null || tracesPath.length() == 0) {
3922            return;
3923        }
3924
3925        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3926        StrictMode.allowThreadDiskWrites();
3927        try {
3928            final File tracesFile = new File(tracesPath);
3929            final File tracesDir = tracesFile.getParentFile();
3930            final File tracesTmp = new File(tracesDir, "__tmp__");
3931            try {
3932                if (!tracesDir.exists()) {
3933                    tracesFile.mkdirs();
3934                    if (!SELinux.restorecon(tracesDir.getPath())) {
3935                        return;
3936                    }
3937                }
3938                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3939
3940                if (tracesFile.exists()) {
3941                    tracesTmp.delete();
3942                    tracesFile.renameTo(tracesTmp);
3943                }
3944                StringBuilder sb = new StringBuilder();
3945                Time tobj = new Time();
3946                tobj.set(System.currentTimeMillis());
3947                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3948                sb.append(": ");
3949                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3950                sb.append(" since ");
3951                sb.append(msg);
3952                FileOutputStream fos = new FileOutputStream(tracesFile);
3953                fos.write(sb.toString().getBytes());
3954                if (app == null) {
3955                    fos.write("\n*** No application process!".getBytes());
3956                }
3957                fos.close();
3958                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3959            } catch (IOException e) {
3960                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3961                return;
3962            }
3963
3964            if (app != null) {
3965                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3966                firstPids.add(app.pid);
3967                dumpStackTraces(tracesPath, firstPids, null, null, null);
3968            }
3969
3970            File lastTracesFile = null;
3971            File curTracesFile = null;
3972            for (int i=9; i>=0; i--) {
3973                String name = String.format(Locale.US, "slow%02d.txt", i);
3974                curTracesFile = new File(tracesDir, name);
3975                if (curTracesFile.exists()) {
3976                    if (lastTracesFile != null) {
3977                        curTracesFile.renameTo(lastTracesFile);
3978                    } else {
3979                        curTracesFile.delete();
3980                    }
3981                }
3982                lastTracesFile = curTracesFile;
3983            }
3984            tracesFile.renameTo(curTracesFile);
3985            if (tracesTmp.exists()) {
3986                tracesTmp.renameTo(tracesFile);
3987            }
3988        } finally {
3989            StrictMode.setThreadPolicy(oldPolicy);
3990        }
3991    }
3992
3993    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3994            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3995        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3996        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3997
3998        if (mController != null) {
3999            try {
4000                // 0 == continue, -1 = kill process immediately
4001                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4002                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4003            } catch (RemoteException e) {
4004                mController = null;
4005                Watchdog.getInstance().setActivityController(null);
4006            }
4007        }
4008
4009        long anrTime = SystemClock.uptimeMillis();
4010        if (MONITOR_CPU_USAGE) {
4011            updateCpuStatsNow();
4012        }
4013
4014        synchronized (this) {
4015            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4016            if (mShuttingDown) {
4017                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4018                return;
4019            } else if (app.notResponding) {
4020                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4021                return;
4022            } else if (app.crashing) {
4023                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4024                return;
4025            }
4026
4027            // In case we come through here for the same app before completing
4028            // this one, mark as anring now so we will bail out.
4029            app.notResponding = true;
4030
4031            // Log the ANR to the event log.
4032            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4033                    app.processName, app.info.flags, annotation);
4034
4035            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4036            firstPids.add(app.pid);
4037
4038            int parentPid = app.pid;
4039            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4040            if (parentPid != app.pid) firstPids.add(parentPid);
4041
4042            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4043
4044            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4045                ProcessRecord r = mLruProcesses.get(i);
4046                if (r != null && r.thread != null) {
4047                    int pid = r.pid;
4048                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4049                        if (r.persistent) {
4050                            firstPids.add(pid);
4051                        } else {
4052                            lastPids.put(pid, Boolean.TRUE);
4053                        }
4054                    }
4055                }
4056            }
4057        }
4058
4059        // Log the ANR to the main log.
4060        StringBuilder info = new StringBuilder();
4061        info.setLength(0);
4062        info.append("ANR in ").append(app.processName);
4063        if (activity != null && activity.shortComponentName != null) {
4064            info.append(" (").append(activity.shortComponentName).append(")");
4065        }
4066        info.append("\n");
4067        info.append("PID: ").append(app.pid).append("\n");
4068        if (annotation != null) {
4069            info.append("Reason: ").append(annotation).append("\n");
4070        }
4071        if (parent != null && parent != activity) {
4072            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4073        }
4074
4075        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4076
4077        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4078                NATIVE_STACKS_OF_INTEREST);
4079
4080        String cpuInfo = null;
4081        if (MONITOR_CPU_USAGE) {
4082            updateCpuStatsNow();
4083            synchronized (mProcessCpuThread) {
4084                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4085            }
4086            info.append(processCpuTracker.printCurrentLoad());
4087            info.append(cpuInfo);
4088        }
4089
4090        info.append(processCpuTracker.printCurrentState(anrTime));
4091
4092        Slog.e(TAG, info.toString());
4093        if (tracesFile == null) {
4094            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4095            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4096        }
4097
4098        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4099                cpuInfo, tracesFile, null);
4100
4101        if (mController != null) {
4102            try {
4103                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4104                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4105                if (res != 0) {
4106                    if (res < 0 && app.pid != MY_PID) {
4107                        Process.killProcess(app.pid);
4108                    } else {
4109                        synchronized (this) {
4110                            mServices.scheduleServiceTimeoutLocked(app);
4111                        }
4112                    }
4113                    return;
4114                }
4115            } catch (RemoteException e) {
4116                mController = null;
4117                Watchdog.getInstance().setActivityController(null);
4118            }
4119        }
4120
4121        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4122        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4123                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4124
4125        synchronized (this) {
4126            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4127                killUnneededProcessLocked(app, "background ANR");
4128                return;
4129            }
4130
4131            // Set the app's notResponding state, and look up the errorReportReceiver
4132            makeAppNotRespondingLocked(app,
4133                    activity != null ? activity.shortComponentName : null,
4134                    annotation != null ? "ANR " + annotation : "ANR",
4135                    info.toString());
4136
4137            // Bring up the infamous App Not Responding dialog
4138            Message msg = Message.obtain();
4139            HashMap<String, Object> map = new HashMap<String, Object>();
4140            msg.what = SHOW_NOT_RESPONDING_MSG;
4141            msg.obj = map;
4142            msg.arg1 = aboveSystem ? 1 : 0;
4143            map.put("app", app);
4144            if (activity != null) {
4145                map.put("activity", activity);
4146            }
4147
4148            mHandler.sendMessage(msg);
4149        }
4150    }
4151
4152    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4153        if (!mLaunchWarningShown) {
4154            mLaunchWarningShown = true;
4155            mHandler.post(new Runnable() {
4156                @Override
4157                public void run() {
4158                    synchronized (ActivityManagerService.this) {
4159                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4160                        d.show();
4161                        mHandler.postDelayed(new Runnable() {
4162                            @Override
4163                            public void run() {
4164                                synchronized (ActivityManagerService.this) {
4165                                    d.dismiss();
4166                                    mLaunchWarningShown = false;
4167                                }
4168                            }
4169                        }, 4000);
4170                    }
4171                }
4172            });
4173        }
4174    }
4175
4176    @Override
4177    public boolean clearApplicationUserData(final String packageName,
4178            final IPackageDataObserver observer, int userId) {
4179        enforceNotIsolatedCaller("clearApplicationUserData");
4180        int uid = Binder.getCallingUid();
4181        int pid = Binder.getCallingPid();
4182        userId = handleIncomingUser(pid, uid,
4183                userId, false, true, "clearApplicationUserData", null);
4184        long callingId = Binder.clearCallingIdentity();
4185        try {
4186            IPackageManager pm = AppGlobals.getPackageManager();
4187            int pkgUid = -1;
4188            synchronized(this) {
4189                try {
4190                    pkgUid = pm.getPackageUid(packageName, userId);
4191                } catch (RemoteException e) {
4192                }
4193                if (pkgUid == -1) {
4194                    Slog.w(TAG, "Invalid packageName: " + packageName);
4195                    if (observer != null) {
4196                        try {
4197                            observer.onRemoveCompleted(packageName, false);
4198                        } catch (RemoteException e) {
4199                            Slog.i(TAG, "Observer no longer exists.");
4200                        }
4201                    }
4202                    return false;
4203                }
4204                if (uid == pkgUid || checkComponentPermission(
4205                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4206                        pid, uid, -1, true)
4207                        == PackageManager.PERMISSION_GRANTED) {
4208                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4209                } else {
4210                    throw new SecurityException("PID " + pid + " does not have permission "
4211                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4212                                    + " of package " + packageName);
4213                }
4214            }
4215
4216            try {
4217                // Clear application user data
4218                pm.clearApplicationUserData(packageName, observer, userId);
4219
4220                // Remove all permissions granted from/to this package
4221                removeUriPermissionsForPackageLocked(packageName, userId, true);
4222
4223                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4224                        Uri.fromParts("package", packageName, null));
4225                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4226                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4227                        null, null, 0, null, null, null, false, false, userId);
4228            } catch (RemoteException e) {
4229            }
4230        } finally {
4231            Binder.restoreCallingIdentity(callingId);
4232        }
4233        return true;
4234    }
4235
4236    @Override
4237    public void killBackgroundProcesses(final String packageName, int userId) {
4238        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4239                != PackageManager.PERMISSION_GRANTED &&
4240                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4241                        != PackageManager.PERMISSION_GRANTED) {
4242            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4243                    + Binder.getCallingPid()
4244                    + ", uid=" + Binder.getCallingUid()
4245                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4246            Slog.w(TAG, msg);
4247            throw new SecurityException(msg);
4248        }
4249
4250        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4251                userId, true, true, "killBackgroundProcesses", null);
4252        long callingId = Binder.clearCallingIdentity();
4253        try {
4254            IPackageManager pm = AppGlobals.getPackageManager();
4255            synchronized(this) {
4256                int appId = -1;
4257                try {
4258                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4259                } catch (RemoteException e) {
4260                }
4261                if (appId == -1) {
4262                    Slog.w(TAG, "Invalid packageName: " + packageName);
4263                    return;
4264                }
4265                killPackageProcessesLocked(packageName, appId, userId,
4266                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4267            }
4268        } finally {
4269            Binder.restoreCallingIdentity(callingId);
4270        }
4271    }
4272
4273    @Override
4274    public void killAllBackgroundProcesses() {
4275        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4276                != PackageManager.PERMISSION_GRANTED) {
4277            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4278                    + Binder.getCallingPid()
4279                    + ", uid=" + Binder.getCallingUid()
4280                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4281            Slog.w(TAG, msg);
4282            throw new SecurityException(msg);
4283        }
4284
4285        long callingId = Binder.clearCallingIdentity();
4286        try {
4287            synchronized(this) {
4288                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4289                final int NP = mProcessNames.getMap().size();
4290                for (int ip=0; ip<NP; ip++) {
4291                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4292                    final int NA = apps.size();
4293                    for (int ia=0; ia<NA; ia++) {
4294                        ProcessRecord app = apps.valueAt(ia);
4295                        if (app.persistent) {
4296                            // we don't kill persistent processes
4297                            continue;
4298                        }
4299                        if (app.removed) {
4300                            procs.add(app);
4301                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4302                            app.removed = true;
4303                            procs.add(app);
4304                        }
4305                    }
4306                }
4307
4308                int N = procs.size();
4309                for (int i=0; i<N; i++) {
4310                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4311                }
4312                mAllowLowerMemLevel = true;
4313                updateOomAdjLocked();
4314                doLowMemReportIfNeededLocked(null);
4315            }
4316        } finally {
4317            Binder.restoreCallingIdentity(callingId);
4318        }
4319    }
4320
4321    @Override
4322    public void forceStopPackage(final String packageName, int userId) {
4323        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4324                != PackageManager.PERMISSION_GRANTED) {
4325            String msg = "Permission Denial: forceStopPackage() from pid="
4326                    + Binder.getCallingPid()
4327                    + ", uid=" + Binder.getCallingUid()
4328                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4329            Slog.w(TAG, msg);
4330            throw new SecurityException(msg);
4331        }
4332        final int callingPid = Binder.getCallingPid();
4333        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4334                userId, true, true, "forceStopPackage", null);
4335        long callingId = Binder.clearCallingIdentity();
4336        try {
4337            IPackageManager pm = AppGlobals.getPackageManager();
4338            synchronized(this) {
4339                int[] users = userId == UserHandle.USER_ALL
4340                        ? getUsersLocked() : new int[] { userId };
4341                for (int user : users) {
4342                    int pkgUid = -1;
4343                    try {
4344                        pkgUid = pm.getPackageUid(packageName, user);
4345                    } catch (RemoteException e) {
4346                    }
4347                    if (pkgUid == -1) {
4348                        Slog.w(TAG, "Invalid packageName: " + packageName);
4349                        continue;
4350                    }
4351                    try {
4352                        pm.setPackageStoppedState(packageName, true, user);
4353                    } catch (RemoteException e) {
4354                    } catch (IllegalArgumentException e) {
4355                        Slog.w(TAG, "Failed trying to unstop package "
4356                                + packageName + ": " + e);
4357                    }
4358                    if (isUserRunningLocked(user, false)) {
4359                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4360                    }
4361                }
4362            }
4363        } finally {
4364            Binder.restoreCallingIdentity(callingId);
4365        }
4366    }
4367
4368    /*
4369     * The pkg name and app id have to be specified.
4370     */
4371    @Override
4372    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4373        if (pkg == null) {
4374            return;
4375        }
4376        // Make sure the uid is valid.
4377        if (appid < 0) {
4378            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4379            return;
4380        }
4381        int callerUid = Binder.getCallingUid();
4382        // Only the system server can kill an application
4383        if (callerUid == Process.SYSTEM_UID) {
4384            // Post an aysnc message to kill the application
4385            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4386            msg.arg1 = appid;
4387            msg.arg2 = 0;
4388            Bundle bundle = new Bundle();
4389            bundle.putString("pkg", pkg);
4390            bundle.putString("reason", reason);
4391            msg.obj = bundle;
4392            mHandler.sendMessage(msg);
4393        } else {
4394            throw new SecurityException(callerUid + " cannot kill pkg: " +
4395                    pkg);
4396        }
4397    }
4398
4399    @Override
4400    public void closeSystemDialogs(String reason) {
4401        enforceNotIsolatedCaller("closeSystemDialogs");
4402
4403        final int pid = Binder.getCallingPid();
4404        final int uid = Binder.getCallingUid();
4405        final long origId = Binder.clearCallingIdentity();
4406        try {
4407            synchronized (this) {
4408                // Only allow this from foreground processes, so that background
4409                // applications can't abuse it to prevent system UI from being shown.
4410                if (uid >= Process.FIRST_APPLICATION_UID) {
4411                    ProcessRecord proc;
4412                    synchronized (mPidsSelfLocked) {
4413                        proc = mPidsSelfLocked.get(pid);
4414                    }
4415                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4416                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4417                                + " from background process " + proc);
4418                        return;
4419                    }
4420                }
4421                closeSystemDialogsLocked(reason);
4422            }
4423        } finally {
4424            Binder.restoreCallingIdentity(origId);
4425        }
4426    }
4427
4428    void closeSystemDialogsLocked(String reason) {
4429        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4430        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4431                | Intent.FLAG_RECEIVER_FOREGROUND);
4432        if (reason != null) {
4433            intent.putExtra("reason", reason);
4434        }
4435        mWindowManager.closeSystemDialogs(reason);
4436
4437        mStackSupervisor.closeSystemDialogsLocked();
4438
4439        broadcastIntentLocked(null, null, intent, null,
4440                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4441                Process.SYSTEM_UID, UserHandle.USER_ALL);
4442    }
4443
4444    @Override
4445    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4446        enforceNotIsolatedCaller("getProcessMemoryInfo");
4447        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4448        for (int i=pids.length-1; i>=0; i--) {
4449            ProcessRecord proc;
4450            int oomAdj;
4451            synchronized (this) {
4452                synchronized (mPidsSelfLocked) {
4453                    proc = mPidsSelfLocked.get(pids[i]);
4454                    oomAdj = proc != null ? proc.setAdj : 0;
4455                }
4456            }
4457            infos[i] = new Debug.MemoryInfo();
4458            Debug.getMemoryInfo(pids[i], infos[i]);
4459            if (proc != null) {
4460                synchronized (this) {
4461                    if (proc.thread != null && proc.setAdj == oomAdj) {
4462                        // Record this for posterity if the process has been stable.
4463                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4464                                infos[i].getTotalUss(), false, proc.pkgList);
4465                    }
4466                }
4467            }
4468        }
4469        return infos;
4470    }
4471
4472    @Override
4473    public long[] getProcessPss(int[] pids) {
4474        enforceNotIsolatedCaller("getProcessPss");
4475        long[] pss = new long[pids.length];
4476        for (int i=pids.length-1; i>=0; i--) {
4477            ProcessRecord proc;
4478            int oomAdj;
4479            synchronized (this) {
4480                synchronized (mPidsSelfLocked) {
4481                    proc = mPidsSelfLocked.get(pids[i]);
4482                    oomAdj = proc != null ? proc.setAdj : 0;
4483                }
4484            }
4485            long[] tmpUss = new long[1];
4486            pss[i] = Debug.getPss(pids[i], tmpUss);
4487            if (proc != null) {
4488                synchronized (this) {
4489                    if (proc.thread != null && proc.setAdj == oomAdj) {
4490                        // Record this for posterity if the process has been stable.
4491                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4492                    }
4493                }
4494            }
4495        }
4496        return pss;
4497    }
4498
4499    @Override
4500    public void killApplicationProcess(String processName, int uid) {
4501        if (processName == null) {
4502            return;
4503        }
4504
4505        int callerUid = Binder.getCallingUid();
4506        // Only the system server can kill an application
4507        if (callerUid == Process.SYSTEM_UID) {
4508            synchronized (this) {
4509                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4510                if (app != null && app.thread != null) {
4511                    try {
4512                        app.thread.scheduleSuicide();
4513                    } catch (RemoteException e) {
4514                        // If the other end already died, then our work here is done.
4515                    }
4516                } else {
4517                    Slog.w(TAG, "Process/uid not found attempting kill of "
4518                            + processName + " / " + uid);
4519                }
4520            }
4521        } else {
4522            throw new SecurityException(callerUid + " cannot kill app process: " +
4523                    processName);
4524        }
4525    }
4526
4527    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4528        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4529                false, true, false, false, UserHandle.getUserId(uid), reason);
4530        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4531                Uri.fromParts("package", packageName, null));
4532        if (!mProcessesReady) {
4533            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4534                    | Intent.FLAG_RECEIVER_FOREGROUND);
4535        }
4536        intent.putExtra(Intent.EXTRA_UID, uid);
4537        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4538        broadcastIntentLocked(null, null, intent,
4539                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4540                false, false,
4541                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4542    }
4543
4544    private void forceStopUserLocked(int userId, String reason) {
4545        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4546        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4547        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4548                | Intent.FLAG_RECEIVER_FOREGROUND);
4549        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4550        broadcastIntentLocked(null, null, intent,
4551                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4552                false, false,
4553                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4554    }
4555
4556    private final boolean killPackageProcessesLocked(String packageName, int appId,
4557            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4558            boolean doit, boolean evenPersistent, String reason) {
4559        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4560
4561        // Remove all processes this package may have touched: all with the
4562        // same UID (except for the system or root user), and all whose name
4563        // matches the package name.
4564        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4565        final int NP = mProcessNames.getMap().size();
4566        for (int ip=0; ip<NP; ip++) {
4567            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4568            final int NA = apps.size();
4569            for (int ia=0; ia<NA; ia++) {
4570                ProcessRecord app = apps.valueAt(ia);
4571                if (app.persistent && !evenPersistent) {
4572                    // we don't kill persistent processes
4573                    continue;
4574                }
4575                if (app.removed) {
4576                    if (doit) {
4577                        procs.add(app);
4578                    }
4579                    continue;
4580                }
4581
4582                // Skip process if it doesn't meet our oom adj requirement.
4583                if (app.setAdj < minOomAdj) {
4584                    continue;
4585                }
4586
4587                // If no package is specified, we call all processes under the
4588                // give user id.
4589                if (packageName == null) {
4590                    if (app.userId != userId) {
4591                        continue;
4592                    }
4593                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4594                        continue;
4595                    }
4596                // Package has been specified, we want to hit all processes
4597                // that match it.  We need to qualify this by the processes
4598                // that are running under the specified app and user ID.
4599                } else {
4600                    if (UserHandle.getAppId(app.uid) != appId) {
4601                        continue;
4602                    }
4603                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4604                        continue;
4605                    }
4606                    if (!app.pkgList.containsKey(packageName)) {
4607                        continue;
4608                    }
4609                }
4610
4611                // Process has passed all conditions, kill it!
4612                if (!doit) {
4613                    return true;
4614                }
4615                app.removed = true;
4616                procs.add(app);
4617            }
4618        }
4619
4620        int N = procs.size();
4621        for (int i=0; i<N; i++) {
4622            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4623        }
4624        updateOomAdjLocked();
4625        return N > 0;
4626    }
4627
4628    private final boolean forceStopPackageLocked(String name, int appId,
4629            boolean callerWillRestart, boolean purgeCache, boolean doit,
4630            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4631        int i;
4632        int N;
4633
4634        if (userId == UserHandle.USER_ALL && name == null) {
4635            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4636        }
4637
4638        if (appId < 0 && name != null) {
4639            try {
4640                appId = UserHandle.getAppId(
4641                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4642            } catch (RemoteException e) {
4643            }
4644        }
4645
4646        if (doit) {
4647            if (name != null) {
4648                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4649                        + " user=" + userId + ": " + reason);
4650            } else {
4651                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4652            }
4653
4654            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4655            for (int ip=pmap.size()-1; ip>=0; ip--) {
4656                SparseArray<Long> ba = pmap.valueAt(ip);
4657                for (i=ba.size()-1; i>=0; i--) {
4658                    boolean remove = false;
4659                    final int entUid = ba.keyAt(i);
4660                    if (name != null) {
4661                        if (userId == UserHandle.USER_ALL) {
4662                            if (UserHandle.getAppId(entUid) == appId) {
4663                                remove = true;
4664                            }
4665                        } else {
4666                            if (entUid == UserHandle.getUid(userId, appId)) {
4667                                remove = true;
4668                            }
4669                        }
4670                    } else if (UserHandle.getUserId(entUid) == userId) {
4671                        remove = true;
4672                    }
4673                    if (remove) {
4674                        ba.removeAt(i);
4675                    }
4676                }
4677                if (ba.size() == 0) {
4678                    pmap.removeAt(ip);
4679                }
4680            }
4681        }
4682
4683        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4684                -100, callerWillRestart, true, doit, evenPersistent,
4685                name == null ? ("stop user " + userId) : ("stop " + name));
4686
4687        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4688            if (!doit) {
4689                return true;
4690            }
4691            didSomething = true;
4692        }
4693
4694        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4695            if (!doit) {
4696                return true;
4697            }
4698            didSomething = true;
4699        }
4700
4701        if (name == null) {
4702            // Remove all sticky broadcasts from this user.
4703            mStickyBroadcasts.remove(userId);
4704        }
4705
4706        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4707        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4708                userId, providers)) {
4709            if (!doit) {
4710                return true;
4711            }
4712            didSomething = true;
4713        }
4714        N = providers.size();
4715        for (i=0; i<N; i++) {
4716            removeDyingProviderLocked(null, providers.get(i), true);
4717        }
4718
4719        // Remove transient permissions granted from/to this package/user
4720        removeUriPermissionsForPackageLocked(name, userId, false);
4721
4722        if (name == null || uninstalling) {
4723            // Remove pending intents.  For now we only do this when force
4724            // stopping users, because we have some problems when doing this
4725            // for packages -- app widgets are not currently cleaned up for
4726            // such packages, so they can be left with bad pending intents.
4727            if (mIntentSenderRecords.size() > 0) {
4728                Iterator<WeakReference<PendingIntentRecord>> it
4729                        = mIntentSenderRecords.values().iterator();
4730                while (it.hasNext()) {
4731                    WeakReference<PendingIntentRecord> wpir = it.next();
4732                    if (wpir == null) {
4733                        it.remove();
4734                        continue;
4735                    }
4736                    PendingIntentRecord pir = wpir.get();
4737                    if (pir == null) {
4738                        it.remove();
4739                        continue;
4740                    }
4741                    if (name == null) {
4742                        // Stopping user, remove all objects for the user.
4743                        if (pir.key.userId != userId) {
4744                            // Not the same user, skip it.
4745                            continue;
4746                        }
4747                    } else {
4748                        if (UserHandle.getAppId(pir.uid) != appId) {
4749                            // Different app id, skip it.
4750                            continue;
4751                        }
4752                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4753                            // Different user, skip it.
4754                            continue;
4755                        }
4756                        if (!pir.key.packageName.equals(name)) {
4757                            // Different package, skip it.
4758                            continue;
4759                        }
4760                    }
4761                    if (!doit) {
4762                        return true;
4763                    }
4764                    didSomething = true;
4765                    it.remove();
4766                    pir.canceled = true;
4767                    if (pir.key.activity != null) {
4768                        pir.key.activity.pendingResults.remove(pir.ref);
4769                    }
4770                }
4771            }
4772        }
4773
4774        if (doit) {
4775            if (purgeCache && name != null) {
4776                AttributeCache ac = AttributeCache.instance();
4777                if (ac != null) {
4778                    ac.removePackage(name);
4779                }
4780            }
4781            if (mBooted) {
4782                mStackSupervisor.resumeTopActivitiesLocked();
4783                mStackSupervisor.scheduleIdleLocked();
4784            }
4785        }
4786
4787        return didSomething;
4788    }
4789
4790    private final boolean removeProcessLocked(ProcessRecord app,
4791            boolean callerWillRestart, boolean allowRestart, String reason) {
4792        final String name = app.processName;
4793        final int uid = app.uid;
4794        if (DEBUG_PROCESSES) Slog.d(
4795            TAG, "Force removing proc " + app.toShortString() + " (" + name
4796            + "/" + uid + ")");
4797
4798        mProcessNames.remove(name, uid);
4799        mIsolatedProcesses.remove(app.uid);
4800        if (mHeavyWeightProcess == app) {
4801            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4802                    mHeavyWeightProcess.userId, 0));
4803            mHeavyWeightProcess = null;
4804        }
4805        boolean needRestart = false;
4806        if (app.pid > 0 && app.pid != MY_PID) {
4807            int pid = app.pid;
4808            synchronized (mPidsSelfLocked) {
4809                mPidsSelfLocked.remove(pid);
4810                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4811            }
4812            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4813                    app.processName, app.info.uid);
4814            if (app.isolated) {
4815                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4816            }
4817            killUnneededProcessLocked(app, reason);
4818            handleAppDiedLocked(app, true, allowRestart);
4819            removeLruProcessLocked(app);
4820
4821            if (app.persistent && !app.isolated) {
4822                if (!callerWillRestart) {
4823                    addAppLocked(app.info, false);
4824                } else {
4825                    needRestart = true;
4826                }
4827            }
4828        } else {
4829            mRemovedProcesses.add(app);
4830        }
4831
4832        return needRestart;
4833    }
4834
4835    private final void processStartTimedOutLocked(ProcessRecord app) {
4836        final int pid = app.pid;
4837        boolean gone = false;
4838        synchronized (mPidsSelfLocked) {
4839            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4840            if (knownApp != null && knownApp.thread == null) {
4841                mPidsSelfLocked.remove(pid);
4842                gone = true;
4843            }
4844        }
4845
4846        if (gone) {
4847            Slog.w(TAG, "Process " + app + " failed to attach");
4848            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4849                    pid, app.uid, app.processName);
4850            mProcessNames.remove(app.processName, app.uid);
4851            mIsolatedProcesses.remove(app.uid);
4852            if (mHeavyWeightProcess == app) {
4853                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4854                        mHeavyWeightProcess.userId, 0));
4855                mHeavyWeightProcess = null;
4856            }
4857            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4858                    app.processName, app.info.uid);
4859            if (app.isolated) {
4860                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4861            }
4862            // Take care of any launching providers waiting for this process.
4863            checkAppInLaunchingProvidersLocked(app, true);
4864            // Take care of any services that are waiting for the process.
4865            mServices.processStartTimedOutLocked(app);
4866            killUnneededProcessLocked(app, "start timeout");
4867            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4868                Slog.w(TAG, "Unattached app died before backup, skipping");
4869                try {
4870                    IBackupManager bm = IBackupManager.Stub.asInterface(
4871                            ServiceManager.getService(Context.BACKUP_SERVICE));
4872                    bm.agentDisconnected(app.info.packageName);
4873                } catch (RemoteException e) {
4874                    // Can't happen; the backup manager is local
4875                }
4876            }
4877            if (isPendingBroadcastProcessLocked(pid)) {
4878                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4879                skipPendingBroadcastLocked(pid);
4880            }
4881        } else {
4882            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4883        }
4884    }
4885
4886    private final boolean attachApplicationLocked(IApplicationThread thread,
4887            int pid) {
4888
4889        // Find the application record that is being attached...  either via
4890        // the pid if we are running in multiple processes, or just pull the
4891        // next app record if we are emulating process with anonymous threads.
4892        ProcessRecord app;
4893        if (pid != MY_PID && pid >= 0) {
4894            synchronized (mPidsSelfLocked) {
4895                app = mPidsSelfLocked.get(pid);
4896            }
4897        } else {
4898            app = null;
4899        }
4900
4901        if (app == null) {
4902            Slog.w(TAG, "No pending application record for pid " + pid
4903                    + " (IApplicationThread " + thread + "); dropping process");
4904            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4905            if (pid > 0 && pid != MY_PID) {
4906                Process.killProcessQuiet(pid);
4907            } else {
4908                try {
4909                    thread.scheduleExit();
4910                } catch (Exception e) {
4911                    // Ignore exceptions.
4912                }
4913            }
4914            return false;
4915        }
4916
4917        // If this application record is still attached to a previous
4918        // process, clean it up now.
4919        if (app.thread != null) {
4920            handleAppDiedLocked(app, true, true);
4921        }
4922
4923        // Tell the process all about itself.
4924
4925        if (localLOGV) Slog.v(
4926                TAG, "Binding process pid " + pid + " to record " + app);
4927
4928        final String processName = app.processName;
4929        try {
4930            AppDeathRecipient adr = new AppDeathRecipient(
4931                    app, pid, thread);
4932            thread.asBinder().linkToDeath(adr, 0);
4933            app.deathRecipient = adr;
4934        } catch (RemoteException e) {
4935            app.resetPackageList(mProcessStats);
4936            startProcessLocked(app, "link fail", processName);
4937            return false;
4938        }
4939
4940        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4941
4942        app.makeActive(thread, mProcessStats);
4943        app.curAdj = app.setAdj = -100;
4944        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4945        app.forcingToForeground = null;
4946        updateProcessForegroundLocked(app, false, false);
4947        app.hasShownUi = false;
4948        app.debugging = false;
4949        app.cached = false;
4950
4951        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4952
4953        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4954        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4955
4956        if (!normalMode) {
4957            Slog.i(TAG, "Launching preboot mode app: " + app);
4958        }
4959
4960        if (localLOGV) Slog.v(
4961            TAG, "New app record " + app
4962            + " thread=" + thread.asBinder() + " pid=" + pid);
4963        try {
4964            int testMode = IApplicationThread.DEBUG_OFF;
4965            if (mDebugApp != null && mDebugApp.equals(processName)) {
4966                testMode = mWaitForDebugger
4967                    ? IApplicationThread.DEBUG_WAIT
4968                    : IApplicationThread.DEBUG_ON;
4969                app.debugging = true;
4970                if (mDebugTransient) {
4971                    mDebugApp = mOrigDebugApp;
4972                    mWaitForDebugger = mOrigWaitForDebugger;
4973                }
4974            }
4975            String profileFile = app.instrumentationProfileFile;
4976            ParcelFileDescriptor profileFd = null;
4977            boolean profileAutoStop = false;
4978            if (mProfileApp != null && mProfileApp.equals(processName)) {
4979                mProfileProc = app;
4980                profileFile = mProfileFile;
4981                profileFd = mProfileFd;
4982                profileAutoStop = mAutoStopProfiler;
4983            }
4984            boolean enableOpenGlTrace = false;
4985            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4986                enableOpenGlTrace = true;
4987                mOpenGlTraceApp = null;
4988            }
4989
4990            // If the app is being launched for restore or full backup, set it up specially
4991            boolean isRestrictedBackupMode = false;
4992            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4993                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4994                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4995                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4996            }
4997
4998            ensurePackageDexOpt(app.instrumentationInfo != null
4999                    ? app.instrumentationInfo.packageName
5000                    : app.info.packageName);
5001            if (app.instrumentationClass != null) {
5002                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5003            }
5004            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5005                    + processName + " with config " + mConfiguration);
5006            ApplicationInfo appInfo = app.instrumentationInfo != null
5007                    ? app.instrumentationInfo : app.info;
5008            app.compat = compatibilityInfoForPackageLocked(appInfo);
5009            if (profileFd != null) {
5010                profileFd = profileFd.dup();
5011            }
5012            thread.bindApplication(processName, appInfo, providers,
5013                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5014                    app.instrumentationArguments, app.instrumentationWatcher,
5015                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5016                    isRestrictedBackupMode || !normalMode, app.persistent,
5017                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5018                    mCoreSettingsObserver.getCoreSettingsLocked());
5019            updateLruProcessLocked(app, false, null);
5020            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5021        } catch (Exception e) {
5022            // todo: Yikes!  What should we do?  For now we will try to
5023            // start another process, but that could easily get us in
5024            // an infinite loop of restarting processes...
5025            Slog.w(TAG, "Exception thrown during bind!", e);
5026
5027            app.resetPackageList(mProcessStats);
5028            app.unlinkDeathRecipient();
5029            startProcessLocked(app, "bind fail", processName);
5030            return false;
5031        }
5032
5033        // Remove this record from the list of starting applications.
5034        mPersistentStartingProcesses.remove(app);
5035        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5036                "Attach application locked removing on hold: " + app);
5037        mProcessesOnHold.remove(app);
5038
5039        boolean badApp = false;
5040        boolean didSomething = false;
5041
5042        // See if the top visible activity is waiting to run in this process...
5043        if (normalMode) {
5044            try {
5045                if (mStackSupervisor.attachApplicationLocked(app)) {
5046                    didSomething = true;
5047                }
5048            } catch (Exception e) {
5049                badApp = true;
5050            }
5051        }
5052
5053        // Find any services that should be running in this process...
5054        if (!badApp) {
5055            try {
5056                didSomething |= mServices.attachApplicationLocked(app, processName);
5057            } catch (Exception e) {
5058                badApp = true;
5059            }
5060        }
5061
5062        // Check if a next-broadcast receiver is in this process...
5063        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5064            try {
5065                didSomething |= sendPendingBroadcastsLocked(app);
5066            } catch (Exception e) {
5067                // If the app died trying to launch the receiver we declare it 'bad'
5068                badApp = true;
5069            }
5070        }
5071
5072        // Check whether the next backup agent is in this process...
5073        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5074            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5075            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5076            try {
5077                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5078                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5079                        mBackupTarget.backupMode);
5080            } catch (Exception e) {
5081                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5082                e.printStackTrace();
5083            }
5084        }
5085
5086        if (badApp) {
5087            // todo: Also need to kill application to deal with all
5088            // kinds of exceptions.
5089            handleAppDiedLocked(app, false, true);
5090            return false;
5091        }
5092
5093        if (!didSomething) {
5094            updateOomAdjLocked();
5095        }
5096
5097        return true;
5098    }
5099
5100    @Override
5101    public final void attachApplication(IApplicationThread thread) {
5102        synchronized (this) {
5103            int callingPid = Binder.getCallingPid();
5104            final long origId = Binder.clearCallingIdentity();
5105            attachApplicationLocked(thread, callingPid);
5106            Binder.restoreCallingIdentity(origId);
5107        }
5108    }
5109
5110    @Override
5111    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5112        final long origId = Binder.clearCallingIdentity();
5113        synchronized (this) {
5114            ActivityStack stack = ActivityRecord.getStackLocked(token);
5115            if (stack != null) {
5116                ActivityRecord r =
5117                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5118                if (stopProfiling) {
5119                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5120                        try {
5121                            mProfileFd.close();
5122                        } catch (IOException e) {
5123                        }
5124                        clearProfilerLocked();
5125                    }
5126                }
5127            }
5128        }
5129        Binder.restoreCallingIdentity(origId);
5130    }
5131
5132    void enableScreenAfterBoot() {
5133        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5134                SystemClock.uptimeMillis());
5135        mWindowManager.enableScreenAfterBoot();
5136
5137        synchronized (this) {
5138            updateEventDispatchingLocked();
5139        }
5140    }
5141
5142    @Override
5143    public void showBootMessage(final CharSequence msg, final boolean always) {
5144        enforceNotIsolatedCaller("showBootMessage");
5145        mWindowManager.showBootMessage(msg, always);
5146    }
5147
5148    @Override
5149    public void dismissKeyguardOnNextActivity() {
5150        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5151        final long token = Binder.clearCallingIdentity();
5152        try {
5153            synchronized (this) {
5154                if (DEBUG_LOCKSCREEN) logLockScreen("");
5155                if (mLockScreenShown) {
5156                    mLockScreenShown = false;
5157                    comeOutOfSleepIfNeededLocked();
5158                }
5159                mStackSupervisor.setDismissKeyguard(true);
5160            }
5161        } finally {
5162            Binder.restoreCallingIdentity(token);
5163        }
5164    }
5165
5166    final void finishBooting() {
5167        IntentFilter pkgFilter = new IntentFilter();
5168        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5169        pkgFilter.addDataScheme("package");
5170        mContext.registerReceiver(new BroadcastReceiver() {
5171            @Override
5172            public void onReceive(Context context, Intent intent) {
5173                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5174                if (pkgs != null) {
5175                    for (String pkg : pkgs) {
5176                        synchronized (ActivityManagerService.this) {
5177                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5178                                    "finished booting")) {
5179                                setResultCode(Activity.RESULT_OK);
5180                                return;
5181                            }
5182                        }
5183                    }
5184                }
5185            }
5186        }, pkgFilter);
5187
5188        synchronized (this) {
5189            // Ensure that any processes we had put on hold are now started
5190            // up.
5191            final int NP = mProcessesOnHold.size();
5192            if (NP > 0) {
5193                ArrayList<ProcessRecord> procs =
5194                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5195                for (int ip=0; ip<NP; ip++) {
5196                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5197                            + procs.get(ip));
5198                    startProcessLocked(procs.get(ip), "on-hold", null);
5199                }
5200            }
5201
5202            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5203                // Start looking for apps that are abusing wake locks.
5204                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5205                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5206                // Tell anyone interested that we are done booting!
5207                SystemProperties.set("sys.boot_completed", "1");
5208                SystemProperties.set("dev.bootcomplete", "1");
5209                for (int i=0; i<mStartedUsers.size(); i++) {
5210                    UserStartedState uss = mStartedUsers.valueAt(i);
5211                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5212                        uss.mState = UserStartedState.STATE_RUNNING;
5213                        final int userId = mStartedUsers.keyAt(i);
5214                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5215                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5216                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5217                        broadcastIntentLocked(null, null, intent, null,
5218                                new IIntentReceiver.Stub() {
5219                                    @Override
5220                                    public void performReceive(Intent intent, int resultCode,
5221                                            String data, Bundle extras, boolean ordered,
5222                                            boolean sticky, int sendingUser) {
5223                                        synchronized (ActivityManagerService.this) {
5224                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5225                                                    true, false);
5226                                        }
5227                                    }
5228                                },
5229                                0, null, null,
5230                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5231                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5232                                userId);
5233                    }
5234                }
5235                scheduleStartProfilesLocked();
5236            }
5237        }
5238    }
5239
5240    final void ensureBootCompleted() {
5241        boolean booting;
5242        boolean enableScreen;
5243        synchronized (this) {
5244            booting = mBooting;
5245            mBooting = false;
5246            enableScreen = !mBooted;
5247            mBooted = true;
5248        }
5249
5250        if (booting) {
5251            finishBooting();
5252        }
5253
5254        if (enableScreen) {
5255            enableScreenAfterBoot();
5256        }
5257    }
5258
5259    @Override
5260    public final void activityResumed(IBinder token) {
5261        final long origId = Binder.clearCallingIdentity();
5262        synchronized(this) {
5263            ActivityStack stack = ActivityRecord.getStackLocked(token);
5264            if (stack != null) {
5265                ActivityRecord.activityResumedLocked(token);
5266            }
5267        }
5268        Binder.restoreCallingIdentity(origId);
5269    }
5270
5271    @Override
5272    public final void activityPaused(IBinder token) {
5273        final long origId = Binder.clearCallingIdentity();
5274        synchronized(this) {
5275            ActivityStack stack = ActivityRecord.getStackLocked(token);
5276            if (stack != null) {
5277                stack.activityPausedLocked(token, false);
5278            }
5279        }
5280        Binder.restoreCallingIdentity(origId);
5281    }
5282
5283    @Override
5284    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5285            CharSequence description) {
5286        if (localLOGV) Slog.v(
5287            TAG, "Activity stopped: token=" + token);
5288
5289        // Refuse possible leaked file descriptors
5290        if (icicle != null && icicle.hasFileDescriptors()) {
5291            throw new IllegalArgumentException("File descriptors passed in Bundle");
5292        }
5293
5294        ActivityRecord r = null;
5295
5296        final long origId = Binder.clearCallingIdentity();
5297
5298        synchronized (this) {
5299            r = ActivityRecord.isInStackLocked(token);
5300            if (r != null) {
5301                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5302            }
5303        }
5304
5305        if (r != null) {
5306            sendPendingThumbnail(r, null, null, null, false);
5307        }
5308
5309        trimApplications();
5310
5311        Binder.restoreCallingIdentity(origId);
5312    }
5313
5314    @Override
5315    public final void activityDestroyed(IBinder token) {
5316        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5317        synchronized (this) {
5318            ActivityStack stack = ActivityRecord.getStackLocked(token);
5319            if (stack != null) {
5320                stack.activityDestroyedLocked(token);
5321            }
5322        }
5323    }
5324
5325    @Override
5326    public String getCallingPackage(IBinder token) {
5327        synchronized (this) {
5328            ActivityRecord r = getCallingRecordLocked(token);
5329            return r != null ? r.info.packageName : null;
5330        }
5331    }
5332
5333    @Override
5334    public ComponentName getCallingActivity(IBinder token) {
5335        synchronized (this) {
5336            ActivityRecord r = getCallingRecordLocked(token);
5337            return r != null ? r.intent.getComponent() : null;
5338        }
5339    }
5340
5341    private ActivityRecord getCallingRecordLocked(IBinder token) {
5342        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5343        if (r == null) {
5344            return null;
5345        }
5346        return r.resultTo;
5347    }
5348
5349    @Override
5350    public ComponentName getActivityClassForToken(IBinder token) {
5351        synchronized(this) {
5352            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5353            if (r == null) {
5354                return null;
5355            }
5356            return r.intent.getComponent();
5357        }
5358    }
5359
5360    @Override
5361    public String getPackageForToken(IBinder token) {
5362        synchronized(this) {
5363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5364            if (r == null) {
5365                return null;
5366            }
5367            return r.packageName;
5368        }
5369    }
5370
5371    @Override
5372    public IIntentSender getIntentSender(int type,
5373            String packageName, IBinder token, String resultWho,
5374            int requestCode, Intent[] intents, String[] resolvedTypes,
5375            int flags, Bundle options, int userId) {
5376        enforceNotIsolatedCaller("getIntentSender");
5377        // Refuse possible leaked file descriptors
5378        if (intents != null) {
5379            if (intents.length < 1) {
5380                throw new IllegalArgumentException("Intents array length must be >= 1");
5381            }
5382            for (int i=0; i<intents.length; i++) {
5383                Intent intent = intents[i];
5384                if (intent != null) {
5385                    if (intent.hasFileDescriptors()) {
5386                        throw new IllegalArgumentException("File descriptors passed in Intent");
5387                    }
5388                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5389                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5390                        throw new IllegalArgumentException(
5391                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5392                    }
5393                    intents[i] = new Intent(intent);
5394                }
5395            }
5396            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5397                throw new IllegalArgumentException(
5398                        "Intent array length does not match resolvedTypes length");
5399            }
5400        }
5401        if (options != null) {
5402            if (options.hasFileDescriptors()) {
5403                throw new IllegalArgumentException("File descriptors passed in options");
5404            }
5405        }
5406
5407        synchronized(this) {
5408            int callingUid = Binder.getCallingUid();
5409            int origUserId = userId;
5410            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5411                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5412                    "getIntentSender", null);
5413            if (origUserId == UserHandle.USER_CURRENT) {
5414                // We don't want to evaluate this until the pending intent is
5415                // actually executed.  However, we do want to always do the
5416                // security checking for it above.
5417                userId = UserHandle.USER_CURRENT;
5418            }
5419            try {
5420                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5421                    int uid = AppGlobals.getPackageManager()
5422                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5423                    if (!UserHandle.isSameApp(callingUid, uid)) {
5424                        String msg = "Permission Denial: getIntentSender() from pid="
5425                            + Binder.getCallingPid()
5426                            + ", uid=" + Binder.getCallingUid()
5427                            + ", (need uid=" + uid + ")"
5428                            + " is not allowed to send as package " + packageName;
5429                        Slog.w(TAG, msg);
5430                        throw new SecurityException(msg);
5431                    }
5432                }
5433
5434                return getIntentSenderLocked(type, packageName, callingUid, userId,
5435                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5436
5437            } catch (RemoteException e) {
5438                throw new SecurityException(e);
5439            }
5440        }
5441    }
5442
5443    IIntentSender getIntentSenderLocked(int type, String packageName,
5444            int callingUid, int userId, IBinder token, String resultWho,
5445            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5446            Bundle options) {
5447        if (DEBUG_MU)
5448            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5449        ActivityRecord activity = null;
5450        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5451            activity = ActivityRecord.isInStackLocked(token);
5452            if (activity == null) {
5453                return null;
5454            }
5455            if (activity.finishing) {
5456                return null;
5457            }
5458        }
5459
5460        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5461        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5462        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5463        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5464                |PendingIntent.FLAG_UPDATE_CURRENT);
5465
5466        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5467                type, packageName, activity, resultWho,
5468                requestCode, intents, resolvedTypes, flags, options, userId);
5469        WeakReference<PendingIntentRecord> ref;
5470        ref = mIntentSenderRecords.get(key);
5471        PendingIntentRecord rec = ref != null ? ref.get() : null;
5472        if (rec != null) {
5473            if (!cancelCurrent) {
5474                if (updateCurrent) {
5475                    if (rec.key.requestIntent != null) {
5476                        rec.key.requestIntent.replaceExtras(intents != null ?
5477                                intents[intents.length - 1] : null);
5478                    }
5479                    if (intents != null) {
5480                        intents[intents.length-1] = rec.key.requestIntent;
5481                        rec.key.allIntents = intents;
5482                        rec.key.allResolvedTypes = resolvedTypes;
5483                    } else {
5484                        rec.key.allIntents = null;
5485                        rec.key.allResolvedTypes = null;
5486                    }
5487                }
5488                return rec;
5489            }
5490            rec.canceled = true;
5491            mIntentSenderRecords.remove(key);
5492        }
5493        if (noCreate) {
5494            return rec;
5495        }
5496        rec = new PendingIntentRecord(this, key, callingUid);
5497        mIntentSenderRecords.put(key, rec.ref);
5498        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5499            if (activity.pendingResults == null) {
5500                activity.pendingResults
5501                        = new HashSet<WeakReference<PendingIntentRecord>>();
5502            }
5503            activity.pendingResults.add(rec.ref);
5504        }
5505        return rec;
5506    }
5507
5508    @Override
5509    public void cancelIntentSender(IIntentSender sender) {
5510        if (!(sender instanceof PendingIntentRecord)) {
5511            return;
5512        }
5513        synchronized(this) {
5514            PendingIntentRecord rec = (PendingIntentRecord)sender;
5515            try {
5516                int uid = AppGlobals.getPackageManager()
5517                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5518                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5519                    String msg = "Permission Denial: cancelIntentSender() from pid="
5520                        + Binder.getCallingPid()
5521                        + ", uid=" + Binder.getCallingUid()
5522                        + " is not allowed to cancel packges "
5523                        + rec.key.packageName;
5524                    Slog.w(TAG, msg);
5525                    throw new SecurityException(msg);
5526                }
5527            } catch (RemoteException e) {
5528                throw new SecurityException(e);
5529            }
5530            cancelIntentSenderLocked(rec, true);
5531        }
5532    }
5533
5534    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5535        rec.canceled = true;
5536        mIntentSenderRecords.remove(rec.key);
5537        if (cleanActivity && rec.key.activity != null) {
5538            rec.key.activity.pendingResults.remove(rec.ref);
5539        }
5540    }
5541
5542    @Override
5543    public String getPackageForIntentSender(IIntentSender pendingResult) {
5544        if (!(pendingResult instanceof PendingIntentRecord)) {
5545            return null;
5546        }
5547        try {
5548            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5549            return res.key.packageName;
5550        } catch (ClassCastException e) {
5551        }
5552        return null;
5553    }
5554
5555    @Override
5556    public int getUidForIntentSender(IIntentSender sender) {
5557        if (sender instanceof PendingIntentRecord) {
5558            try {
5559                PendingIntentRecord res = (PendingIntentRecord)sender;
5560                return res.uid;
5561            } catch (ClassCastException e) {
5562            }
5563        }
5564        return -1;
5565    }
5566
5567    @Override
5568    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5569        if (!(pendingResult instanceof PendingIntentRecord)) {
5570            return false;
5571        }
5572        try {
5573            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5574            if (res.key.allIntents == null) {
5575                return false;
5576            }
5577            for (int i=0; i<res.key.allIntents.length; i++) {
5578                Intent intent = res.key.allIntents[i];
5579                if (intent.getPackage() != null && intent.getComponent() != null) {
5580                    return false;
5581                }
5582            }
5583            return true;
5584        } catch (ClassCastException e) {
5585        }
5586        return false;
5587    }
5588
5589    @Override
5590    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5591        if (!(pendingResult instanceof PendingIntentRecord)) {
5592            return false;
5593        }
5594        try {
5595            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5596            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5597                return true;
5598            }
5599            return false;
5600        } catch (ClassCastException e) {
5601        }
5602        return false;
5603    }
5604
5605    @Override
5606    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5607        if (!(pendingResult instanceof PendingIntentRecord)) {
5608            return null;
5609        }
5610        try {
5611            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5612            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5613        } catch (ClassCastException e) {
5614        }
5615        return null;
5616    }
5617
5618    @Override
5619    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5620        if (!(pendingResult instanceof PendingIntentRecord)) {
5621            return null;
5622        }
5623        try {
5624            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5625            Intent intent = res.key.requestIntent;
5626            if (intent != null) {
5627                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5628                        || res.lastTagPrefix.equals(prefix))) {
5629                    return res.lastTag;
5630                }
5631                res.lastTagPrefix = prefix;
5632                StringBuilder sb = new StringBuilder(128);
5633                if (prefix != null) {
5634                    sb.append(prefix);
5635                }
5636                if (intent.getAction() != null) {
5637                    sb.append(intent.getAction());
5638                } else if (intent.getComponent() != null) {
5639                    intent.getComponent().appendShortString(sb);
5640                } else {
5641                    sb.append("?");
5642                }
5643                return res.lastTag = sb.toString();
5644            }
5645        } catch (ClassCastException e) {
5646        }
5647        return null;
5648    }
5649
5650    @Override
5651    public void setProcessLimit(int max) {
5652        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5653                "setProcessLimit()");
5654        synchronized (this) {
5655            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5656            mProcessLimitOverride = max;
5657        }
5658        trimApplications();
5659    }
5660
5661    @Override
5662    public int getProcessLimit() {
5663        synchronized (this) {
5664            return mProcessLimitOverride;
5665        }
5666    }
5667
5668    void foregroundTokenDied(ForegroundToken token) {
5669        synchronized (ActivityManagerService.this) {
5670            synchronized (mPidsSelfLocked) {
5671                ForegroundToken cur
5672                    = mForegroundProcesses.get(token.pid);
5673                if (cur != token) {
5674                    return;
5675                }
5676                mForegroundProcesses.remove(token.pid);
5677                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5678                if (pr == null) {
5679                    return;
5680                }
5681                pr.forcingToForeground = null;
5682                updateProcessForegroundLocked(pr, false, false);
5683            }
5684            updateOomAdjLocked();
5685        }
5686    }
5687
5688    @Override
5689    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5690        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5691                "setProcessForeground()");
5692        synchronized(this) {
5693            boolean changed = false;
5694
5695            synchronized (mPidsSelfLocked) {
5696                ProcessRecord pr = mPidsSelfLocked.get(pid);
5697                if (pr == null && isForeground) {
5698                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5699                    return;
5700                }
5701                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5702                if (oldToken != null) {
5703                    oldToken.token.unlinkToDeath(oldToken, 0);
5704                    mForegroundProcesses.remove(pid);
5705                    if (pr != null) {
5706                        pr.forcingToForeground = null;
5707                    }
5708                    changed = true;
5709                }
5710                if (isForeground && token != null) {
5711                    ForegroundToken newToken = new ForegroundToken() {
5712                        @Override
5713                        public void binderDied() {
5714                            foregroundTokenDied(this);
5715                        }
5716                    };
5717                    newToken.pid = pid;
5718                    newToken.token = token;
5719                    try {
5720                        token.linkToDeath(newToken, 0);
5721                        mForegroundProcesses.put(pid, newToken);
5722                        pr.forcingToForeground = token;
5723                        changed = true;
5724                    } catch (RemoteException e) {
5725                        // If the process died while doing this, we will later
5726                        // do the cleanup with the process death link.
5727                    }
5728                }
5729            }
5730
5731            if (changed) {
5732                updateOomAdjLocked();
5733            }
5734        }
5735    }
5736
5737    // =========================================================
5738    // PERMISSIONS
5739    // =========================================================
5740
5741    static class PermissionController extends IPermissionController.Stub {
5742        ActivityManagerService mActivityManagerService;
5743        PermissionController(ActivityManagerService activityManagerService) {
5744            mActivityManagerService = activityManagerService;
5745        }
5746
5747        @Override
5748        public boolean checkPermission(String permission, int pid, int uid) {
5749            return mActivityManagerService.checkPermission(permission, pid,
5750                    uid) == PackageManager.PERMISSION_GRANTED;
5751        }
5752    }
5753
5754    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5755        @Override
5756        public int checkComponentPermission(String permission, int pid, int uid,
5757                int owningUid, boolean exported) {
5758            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5759                    owningUid, exported);
5760        }
5761
5762        @Override
5763        public Object getAMSLock() {
5764            return ActivityManagerService.this;
5765        }
5766    }
5767
5768    /**
5769     * This can be called with or without the global lock held.
5770     */
5771    int checkComponentPermission(String permission, int pid, int uid,
5772            int owningUid, boolean exported) {
5773        // We might be performing an operation on behalf of an indirect binder
5774        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5775        // client identity accordingly before proceeding.
5776        Identity tlsIdentity = sCallerIdentity.get();
5777        if (tlsIdentity != null) {
5778            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5779                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5780            uid = tlsIdentity.uid;
5781            pid = tlsIdentity.pid;
5782        }
5783
5784        if (pid == MY_PID) {
5785            return PackageManager.PERMISSION_GRANTED;
5786        }
5787
5788        return ActivityManager.checkComponentPermission(permission, uid,
5789                owningUid, exported);
5790    }
5791
5792    /**
5793     * As the only public entry point for permissions checking, this method
5794     * can enforce the semantic that requesting a check on a null global
5795     * permission is automatically denied.  (Internally a null permission
5796     * string is used when calling {@link #checkComponentPermission} in cases
5797     * when only uid-based security is needed.)
5798     *
5799     * This can be called with or without the global lock held.
5800     */
5801    @Override
5802    public int checkPermission(String permission, int pid, int uid) {
5803        if (permission == null) {
5804            return PackageManager.PERMISSION_DENIED;
5805        }
5806        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5807    }
5808
5809    /**
5810     * Binder IPC calls go through the public entry point.
5811     * This can be called with or without the global lock held.
5812     */
5813    int checkCallingPermission(String permission) {
5814        return checkPermission(permission,
5815                Binder.getCallingPid(),
5816                UserHandle.getAppId(Binder.getCallingUid()));
5817    }
5818
5819    /**
5820     * This can be called with or without the global lock held.
5821     */
5822    void enforceCallingPermission(String permission, String func) {
5823        if (checkCallingPermission(permission)
5824                == PackageManager.PERMISSION_GRANTED) {
5825            return;
5826        }
5827
5828        String msg = "Permission Denial: " + func + " from pid="
5829                + Binder.getCallingPid()
5830                + ", uid=" + Binder.getCallingUid()
5831                + " requires " + permission;
5832        Slog.w(TAG, msg);
5833        throw new SecurityException(msg);
5834    }
5835
5836    /**
5837     * Determine if UID is holding permissions required to access {@link Uri} in
5838     * the given {@link ProviderInfo}. Final permission checking is always done
5839     * in {@link ContentProvider}.
5840     */
5841    private final boolean checkHoldingPermissionsLocked(
5842            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5843        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5844                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5845
5846        if (pi.applicationInfo.uid == uid) {
5847            return true;
5848        } else if (!pi.exported) {
5849            return false;
5850        }
5851
5852        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5853        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5854        try {
5855            // check if target holds top-level <provider> permissions
5856            if (!readMet && pi.readPermission != null
5857                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5858                readMet = true;
5859            }
5860            if (!writeMet && pi.writePermission != null
5861                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5862                writeMet = true;
5863            }
5864
5865            // track if unprotected read/write is allowed; any denied
5866            // <path-permission> below removes this ability
5867            boolean allowDefaultRead = pi.readPermission == null;
5868            boolean allowDefaultWrite = pi.writePermission == null;
5869
5870            // check if target holds any <path-permission> that match uri
5871            final PathPermission[] pps = pi.pathPermissions;
5872            if (pps != null) {
5873                final String path = uri.getPath();
5874                int i = pps.length;
5875                while (i > 0 && (!readMet || !writeMet)) {
5876                    i--;
5877                    PathPermission pp = pps[i];
5878                    if (pp.match(path)) {
5879                        if (!readMet) {
5880                            final String pprperm = pp.getReadPermission();
5881                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5882                                    + pprperm + " for " + pp.getPath()
5883                                    + ": match=" + pp.match(path)
5884                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5885                            if (pprperm != null) {
5886                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5887                                    readMet = true;
5888                                } else {
5889                                    allowDefaultRead = false;
5890                                }
5891                            }
5892                        }
5893                        if (!writeMet) {
5894                            final String ppwperm = pp.getWritePermission();
5895                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5896                                    + ppwperm + " for " + pp.getPath()
5897                                    + ": match=" + pp.match(path)
5898                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5899                            if (ppwperm != null) {
5900                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5901                                    writeMet = true;
5902                                } else {
5903                                    allowDefaultWrite = false;
5904                                }
5905                            }
5906                        }
5907                    }
5908                }
5909            }
5910
5911            // grant unprotected <provider> read/write, if not blocked by
5912            // <path-permission> above
5913            if (allowDefaultRead) readMet = true;
5914            if (allowDefaultWrite) writeMet = true;
5915
5916        } catch (RemoteException e) {
5917            return false;
5918        }
5919
5920        return readMet && writeMet;
5921    }
5922
5923    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5924        ProviderInfo pi = null;
5925        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5926        if (cpr != null) {
5927            pi = cpr.info;
5928        } else {
5929            try {
5930                pi = AppGlobals.getPackageManager().resolveContentProvider(
5931                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5932            } catch (RemoteException ex) {
5933            }
5934        }
5935        return pi;
5936    }
5937
5938    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5939        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5940        if (targetUris != null) {
5941            return targetUris.get(uri);
5942        } else {
5943            return null;
5944        }
5945    }
5946
5947    private UriPermission findOrCreateUriPermissionLocked(
5948            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5949        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5950        if (targetUris == null) {
5951            targetUris = Maps.newArrayMap();
5952            mGrantedUriPermissions.put(targetUid, targetUris);
5953        }
5954
5955        UriPermission perm = targetUris.get(uri);
5956        if (perm == null) {
5957            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5958            targetUris.put(uri, perm);
5959        }
5960
5961        return perm;
5962    }
5963
5964    private final boolean checkUriPermissionLocked(
5965            Uri uri, int uid, int modeFlags, int minStrength) {
5966        // Root gets to do everything.
5967        if (uid == 0) {
5968            return true;
5969        }
5970        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5971        if (perms == null) return false;
5972        UriPermission perm = perms.get(uri);
5973        if (perm == null) return false;
5974        return perm.getStrength(modeFlags) >= minStrength;
5975    }
5976
5977    @Override
5978    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5979        enforceNotIsolatedCaller("checkUriPermission");
5980
5981        // Another redirected-binder-call permissions check as in
5982        // {@link checkComponentPermission}.
5983        Identity tlsIdentity = sCallerIdentity.get();
5984        if (tlsIdentity != null) {
5985            uid = tlsIdentity.uid;
5986            pid = tlsIdentity.pid;
5987        }
5988
5989        // Our own process gets to do everything.
5990        if (pid == MY_PID) {
5991            return PackageManager.PERMISSION_GRANTED;
5992        }
5993        synchronized(this) {
5994            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5995                    ? PackageManager.PERMISSION_GRANTED
5996                    : PackageManager.PERMISSION_DENIED;
5997        }
5998    }
5999
6000    /**
6001     * Check if the targetPkg can be granted permission to access uri by
6002     * the callingUid using the given modeFlags.  Throws a security exception
6003     * if callingUid is not allowed to do this.  Returns the uid of the target
6004     * if the URI permission grant should be performed; returns -1 if it is not
6005     * needed (for example targetPkg already has permission to access the URI).
6006     * If you already know the uid of the target, you can supply it in
6007     * lastTargetUid else set that to -1.
6008     */
6009    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6010            Uri uri, int modeFlags, int lastTargetUid) {
6011        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6012        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6013                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6014        if (modeFlags == 0) {
6015            return -1;
6016        }
6017
6018        if (targetPkg != null) {
6019            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6020                    "Checking grant " + targetPkg + " permission to " + uri);
6021        }
6022
6023        final IPackageManager pm = AppGlobals.getPackageManager();
6024
6025        // If this is not a content: uri, we can't do anything with it.
6026        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6027            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6028                    "Can't grant URI permission for non-content URI: " + uri);
6029            return -1;
6030        }
6031
6032        final String authority = uri.getAuthority();
6033        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6034        if (pi == null) {
6035            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6036            return -1;
6037        }
6038
6039        int targetUid = lastTargetUid;
6040        if (targetUid < 0 && targetPkg != null) {
6041            try {
6042                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6043                if (targetUid < 0) {
6044                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6045                            "Can't grant URI permission no uid for: " + targetPkg);
6046                    return -1;
6047                }
6048            } catch (RemoteException ex) {
6049                return -1;
6050            }
6051        }
6052
6053        if (targetUid >= 0) {
6054            // First...  does the target actually need this permission?
6055            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6056                // No need to grant the target this permission.
6057                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6058                        "Target " + targetPkg + " already has full permission to " + uri);
6059                return -1;
6060            }
6061        } else {
6062            // First...  there is no target package, so can anyone access it?
6063            boolean allowed = pi.exported;
6064            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6065                if (pi.readPermission != null) {
6066                    allowed = false;
6067                }
6068            }
6069            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6070                if (pi.writePermission != null) {
6071                    allowed = false;
6072                }
6073            }
6074            if (allowed) {
6075                return -1;
6076            }
6077        }
6078
6079        // Second...  is the provider allowing granting of URI permissions?
6080        if (!pi.grantUriPermissions) {
6081            throw new SecurityException("Provider " + pi.packageName
6082                    + "/" + pi.name
6083                    + " does not allow granting of Uri permissions (uri "
6084                    + uri + ")");
6085        }
6086        if (pi.uriPermissionPatterns != null) {
6087            final int N = pi.uriPermissionPatterns.length;
6088            boolean allowed = false;
6089            for (int i=0; i<N; i++) {
6090                if (pi.uriPermissionPatterns[i] != null
6091                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6092                    allowed = true;
6093                    break;
6094                }
6095            }
6096            if (!allowed) {
6097                throw new SecurityException("Provider " + pi.packageName
6098                        + "/" + pi.name
6099                        + " does not allow granting of permission to path of Uri "
6100                        + uri);
6101            }
6102        }
6103
6104        // Third...  does the caller itself have permission to access
6105        // this uri?
6106        if (callingUid != Process.myUid()) {
6107            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6108                // Require they hold a strong enough Uri permission
6109                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6110                        : UriPermission.STRENGTH_OWNED;
6111                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6112                    throw new SecurityException("Uid " + callingUid
6113                            + " does not have permission to uri " + uri);
6114                }
6115            }
6116        }
6117
6118        return targetUid;
6119    }
6120
6121    @Override
6122    public int checkGrantUriPermission(int callingUid, String targetPkg,
6123            Uri uri, int modeFlags) {
6124        enforceNotIsolatedCaller("checkGrantUriPermission");
6125        synchronized(this) {
6126            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6127        }
6128    }
6129
6130    void grantUriPermissionUncheckedLocked(
6131            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6132        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6133        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6134                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6135        if (modeFlags == 0) {
6136            return;
6137        }
6138
6139        // So here we are: the caller has the assumed permission
6140        // to the uri, and the target doesn't.  Let's now give this to
6141        // the target.
6142
6143        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6144                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6145
6146        final String authority = uri.getAuthority();
6147        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6148        if (pi == null) {
6149            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6150            return;
6151        }
6152
6153        final UriPermission perm = findOrCreateUriPermissionLocked(
6154                pi.packageName, targetPkg, targetUid, uri);
6155        perm.grantModes(modeFlags, persistable, owner);
6156    }
6157
6158    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6159            int modeFlags, UriPermissionOwner owner) {
6160        if (targetPkg == null) {
6161            throw new NullPointerException("targetPkg");
6162        }
6163
6164        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6165        if (targetUid < 0) {
6166            return;
6167        }
6168
6169        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6170    }
6171
6172    static class NeededUriGrants extends ArrayList<Uri> {
6173        final String targetPkg;
6174        final int targetUid;
6175        final int flags;
6176
6177        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6178            this.targetPkg = targetPkg;
6179            this.targetUid = targetUid;
6180            this.flags = flags;
6181        }
6182    }
6183
6184    /**
6185     * Like checkGrantUriPermissionLocked, but takes an Intent.
6186     */
6187    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6188            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6189        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6190                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6191                + " clip=" + (intent != null ? intent.getClipData() : null)
6192                + " from " + intent + "; flags=0x"
6193                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6194
6195        if (targetPkg == null) {
6196            throw new NullPointerException("targetPkg");
6197        }
6198
6199        if (intent == null) {
6200            return null;
6201        }
6202        Uri data = intent.getData();
6203        ClipData clip = intent.getClipData();
6204        if (data == null && clip == null) {
6205            return null;
6206        }
6207
6208        if (data != null) {
6209            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6210                mode, needed != null ? needed.targetUid : -1);
6211            if (targetUid > 0) {
6212                if (needed == null) {
6213                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6214                }
6215                needed.add(data);
6216            }
6217        }
6218        if (clip != null) {
6219            for (int i=0; i<clip.getItemCount(); i++) {
6220                Uri uri = clip.getItemAt(i).getUri();
6221                if (uri != null) {
6222                    int targetUid = -1;
6223                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6224                            mode, needed != null ? needed.targetUid : -1);
6225                    if (targetUid > 0) {
6226                        if (needed == null) {
6227                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6228                        }
6229                        needed.add(uri);
6230                    }
6231                } else {
6232                    Intent clipIntent = clip.getItemAt(i).getIntent();
6233                    if (clipIntent != null) {
6234                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6235                                callingUid, targetPkg, clipIntent, mode, needed);
6236                        if (newNeeded != null) {
6237                            needed = newNeeded;
6238                        }
6239                    }
6240                }
6241            }
6242        }
6243
6244        return needed;
6245    }
6246
6247    /**
6248     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6249     */
6250    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6251            UriPermissionOwner owner) {
6252        if (needed != null) {
6253            for (int i=0; i<needed.size(); i++) {
6254                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6255                        needed.get(i), needed.flags, owner);
6256            }
6257        }
6258    }
6259
6260    void grantUriPermissionFromIntentLocked(int callingUid,
6261            String targetPkg, Intent intent, UriPermissionOwner owner) {
6262        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6263                intent, intent != null ? intent.getFlags() : 0, null);
6264        if (needed == null) {
6265            return;
6266        }
6267
6268        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6269    }
6270
6271    @Override
6272    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6273            Uri uri, int modeFlags) {
6274        enforceNotIsolatedCaller("grantUriPermission");
6275        synchronized(this) {
6276            final ProcessRecord r = getRecordForAppLocked(caller);
6277            if (r == null) {
6278                throw new SecurityException("Unable to find app for caller "
6279                        + caller
6280                        + " when granting permission to uri " + uri);
6281            }
6282            if (targetPkg == null) {
6283                throw new IllegalArgumentException("null target");
6284            }
6285            if (uri == null) {
6286                throw new IllegalArgumentException("null uri");
6287            }
6288
6289            // Persistable only supported through Intents
6290            Preconditions.checkFlagsArgument(modeFlags,
6291                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6292
6293            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6294                    null);
6295        }
6296    }
6297
6298    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6299        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6300                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6301            ArrayMap<Uri, UriPermission> perms
6302                    = mGrantedUriPermissions.get(perm.targetUid);
6303            if (perms != null) {
6304                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6305                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6306                perms.remove(perm.uri);
6307                if (perms.size() == 0) {
6308                    mGrantedUriPermissions.remove(perm.targetUid);
6309                }
6310            }
6311        }
6312    }
6313
6314    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6315        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6316
6317        final IPackageManager pm = AppGlobals.getPackageManager();
6318        final String authority = uri.getAuthority();
6319        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6320        if (pi == null) {
6321            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6322            return;
6323        }
6324
6325        // Does the caller have this permission on the URI?
6326        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6327            // Right now, if you are not the original owner of the permission,
6328            // you are not allowed to revoke it.
6329            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6330                throw new SecurityException("Uid " + callingUid
6331                        + " does not have permission to uri " + uri);
6332            //}
6333        }
6334
6335        boolean persistChanged = false;
6336
6337        // Go through all of the permissions and remove any that match.
6338        final List<String> SEGMENTS = uri.getPathSegments();
6339        if (SEGMENTS != null) {
6340            final int NS = SEGMENTS.size();
6341            int N = mGrantedUriPermissions.size();
6342            for (int i=0; i<N; i++) {
6343                ArrayMap<Uri, UriPermission> perms
6344                        = mGrantedUriPermissions.valueAt(i);
6345                Iterator<UriPermission> it = perms.values().iterator();
6346            toploop:
6347                while (it.hasNext()) {
6348                    UriPermission perm = it.next();
6349                    Uri targetUri = perm.uri;
6350                    if (!authority.equals(targetUri.getAuthority())) {
6351                        continue;
6352                    }
6353                    List<String> targetSegments = targetUri.getPathSegments();
6354                    if (targetSegments == null) {
6355                        continue;
6356                    }
6357                    if (targetSegments.size() < NS) {
6358                        continue;
6359                    }
6360                    for (int j=0; j<NS; j++) {
6361                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6362                            continue toploop;
6363                        }
6364                    }
6365                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6366                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6367                    persistChanged |= perm.clearModes(modeFlags, true);
6368                    if (perm.modeFlags == 0) {
6369                        it.remove();
6370                    }
6371                }
6372                if (perms.size() == 0) {
6373                    mGrantedUriPermissions.remove(
6374                            mGrantedUriPermissions.keyAt(i));
6375                    N--;
6376                    i--;
6377                }
6378            }
6379        }
6380
6381        if (persistChanged) {
6382            schedulePersistUriGrants();
6383        }
6384    }
6385
6386    @Override
6387    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6388            int modeFlags) {
6389        enforceNotIsolatedCaller("revokeUriPermission");
6390        synchronized(this) {
6391            final ProcessRecord r = getRecordForAppLocked(caller);
6392            if (r == null) {
6393                throw new SecurityException("Unable to find app for caller "
6394                        + caller
6395                        + " when revoking permission to uri " + uri);
6396            }
6397            if (uri == null) {
6398                Slog.w(TAG, "revokeUriPermission: null uri");
6399                return;
6400            }
6401
6402            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6403                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6404            if (modeFlags == 0) {
6405                return;
6406            }
6407
6408            final IPackageManager pm = AppGlobals.getPackageManager();
6409            final String authority = uri.getAuthority();
6410            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6411            if (pi == null) {
6412                Slog.w(TAG, "No content provider found for permission revoke: "
6413                        + uri.toSafeString());
6414                return;
6415            }
6416
6417            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6418        }
6419    }
6420
6421    /**
6422     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6423     * given package.
6424     *
6425     * @param packageName Package name to match, or {@code null} to apply to all
6426     *            packages.
6427     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6428     *            to all users.
6429     * @param persistable If persistable grants should be removed.
6430     */
6431    private void removeUriPermissionsForPackageLocked(
6432            String packageName, int userHandle, boolean persistable) {
6433        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6434            throw new IllegalArgumentException("Must narrow by either package or user");
6435        }
6436
6437        boolean persistChanged = false;
6438
6439        final int size = mGrantedUriPermissions.size();
6440        for (int i = 0; i < size; i++) {
6441            // Only inspect grants matching user
6442            if (userHandle == UserHandle.USER_ALL
6443                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6444                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6445                        .values().iterator();
6446                while (it.hasNext()) {
6447                    final UriPermission perm = it.next();
6448
6449                    // Only inspect grants matching package
6450                    if (packageName == null || perm.sourcePkg.equals(packageName)
6451                            || perm.targetPkg.equals(packageName)) {
6452                        persistChanged |= perm.clearModes(~0, persistable);
6453
6454                        // Only remove when no modes remain; any persisted grants
6455                        // will keep this alive.
6456                        if (perm.modeFlags == 0) {
6457                            it.remove();
6458                        }
6459                    }
6460                }
6461            }
6462        }
6463
6464        if (persistChanged) {
6465            schedulePersistUriGrants();
6466        }
6467    }
6468
6469    @Override
6470    public IBinder newUriPermissionOwner(String name) {
6471        enforceNotIsolatedCaller("newUriPermissionOwner");
6472        synchronized(this) {
6473            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6474            return owner.getExternalTokenLocked();
6475        }
6476    }
6477
6478    @Override
6479    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6480            Uri uri, int modeFlags) {
6481        synchronized(this) {
6482            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6483            if (owner == null) {
6484                throw new IllegalArgumentException("Unknown owner: " + token);
6485            }
6486            if (fromUid != Binder.getCallingUid()) {
6487                if (Binder.getCallingUid() != Process.myUid()) {
6488                    // Only system code can grant URI permissions on behalf
6489                    // of other users.
6490                    throw new SecurityException("nice try");
6491                }
6492            }
6493            if (targetPkg == null) {
6494                throw new IllegalArgumentException("null target");
6495            }
6496            if (uri == null) {
6497                throw new IllegalArgumentException("null uri");
6498            }
6499
6500            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6501        }
6502    }
6503
6504    @Override
6505    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6506        synchronized(this) {
6507            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6508            if (owner == null) {
6509                throw new IllegalArgumentException("Unknown owner: " + token);
6510            }
6511
6512            if (uri == null) {
6513                owner.removeUriPermissionsLocked(mode);
6514            } else {
6515                owner.removeUriPermissionLocked(uri, mode);
6516            }
6517        }
6518    }
6519
6520    private void schedulePersistUriGrants() {
6521        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6522            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6523                    10 * DateUtils.SECOND_IN_MILLIS);
6524        }
6525    }
6526
6527    private void writeGrantedUriPermissions() {
6528        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6529
6530        // Snapshot permissions so we can persist without lock
6531        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6532        synchronized (this) {
6533            final int size = mGrantedUriPermissions.size();
6534            for (int i = 0 ; i < size; i++) {
6535                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6536                    if (perm.persistedModeFlags != 0) {
6537                        persist.add(perm.snapshot());
6538                    }
6539                }
6540            }
6541        }
6542
6543        FileOutputStream fos = null;
6544        try {
6545            fos = mGrantFile.startWrite();
6546
6547            XmlSerializer out = new FastXmlSerializer();
6548            out.setOutput(fos, "utf-8");
6549            out.startDocument(null, true);
6550            out.startTag(null, TAG_URI_GRANTS);
6551            for (UriPermission.Snapshot perm : persist) {
6552                out.startTag(null, TAG_URI_GRANT);
6553                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6554                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6555                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6556                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6557                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6558                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6559                out.endTag(null, TAG_URI_GRANT);
6560            }
6561            out.endTag(null, TAG_URI_GRANTS);
6562            out.endDocument();
6563
6564            mGrantFile.finishWrite(fos);
6565        } catch (IOException e) {
6566            if (fos != null) {
6567                mGrantFile.failWrite(fos);
6568            }
6569        }
6570    }
6571
6572    private void readGrantedUriPermissionsLocked() {
6573        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6574
6575        final long now = System.currentTimeMillis();
6576
6577        FileInputStream fis = null;
6578        try {
6579            fis = mGrantFile.openRead();
6580            final XmlPullParser in = Xml.newPullParser();
6581            in.setInput(fis, null);
6582
6583            int type;
6584            while ((type = in.next()) != END_DOCUMENT) {
6585                final String tag = in.getName();
6586                if (type == START_TAG) {
6587                    if (TAG_URI_GRANT.equals(tag)) {
6588                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6589                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6590                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6591                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6592                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6593                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6594
6595                        // Sanity check that provider still belongs to source package
6596                        final ProviderInfo pi = getProviderInfoLocked(
6597                                uri.getAuthority(), userHandle);
6598                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6599                            int targetUid = -1;
6600                            try {
6601                                targetUid = AppGlobals.getPackageManager()
6602                                        .getPackageUid(targetPkg, userHandle);
6603                            } catch (RemoteException e) {
6604                            }
6605                            if (targetUid != -1) {
6606                                final UriPermission perm = findOrCreateUriPermissionLocked(
6607                                        sourcePkg, targetPkg, targetUid, uri);
6608                                perm.initPersistedModes(modeFlags, createdTime);
6609                            }
6610                        } else {
6611                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6612                                    + " but instead found " + pi);
6613                        }
6614                    }
6615                }
6616            }
6617        } catch (FileNotFoundException e) {
6618            // Missing grants is okay
6619        } catch (IOException e) {
6620            Log.wtf(TAG, "Failed reading Uri grants", e);
6621        } catch (XmlPullParserException e) {
6622            Log.wtf(TAG, "Failed reading Uri grants", e);
6623        } finally {
6624            IoUtils.closeQuietly(fis);
6625        }
6626    }
6627
6628    @Override
6629    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6630        enforceNotIsolatedCaller("takePersistableUriPermission");
6631
6632        Preconditions.checkFlagsArgument(modeFlags,
6633                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6634
6635        synchronized (this) {
6636            final int callingUid = Binder.getCallingUid();
6637            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6638            if (perm == null) {
6639                throw new SecurityException("No permission grant found for UID " + callingUid
6640                        + " and Uri " + uri.toSafeString());
6641            }
6642
6643            boolean persistChanged = perm.takePersistableModes(modeFlags);
6644            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6645
6646            if (persistChanged) {
6647                schedulePersistUriGrants();
6648            }
6649        }
6650    }
6651
6652    @Override
6653    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6654        enforceNotIsolatedCaller("releasePersistableUriPermission");
6655
6656        Preconditions.checkFlagsArgument(modeFlags,
6657                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6658
6659        synchronized (this) {
6660            final int callingUid = Binder.getCallingUid();
6661
6662            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6663            if (perm == null) {
6664                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6665                        + uri.toSafeString());
6666                return;
6667            }
6668
6669            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6670            removeUriPermissionIfNeededLocked(perm);
6671            if (persistChanged) {
6672                schedulePersistUriGrants();
6673            }
6674        }
6675    }
6676
6677    /**
6678     * Prune any older {@link UriPermission} for the given UID until outstanding
6679     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6680     *
6681     * @return if any mutations occured that require persisting.
6682     */
6683    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6684        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6685        if (perms == null) return false;
6686        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6687
6688        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6689        for (UriPermission perm : perms.values()) {
6690            if (perm.persistedModeFlags != 0) {
6691                persisted.add(perm);
6692            }
6693        }
6694
6695        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6696        if (trimCount <= 0) return false;
6697
6698        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6699        for (int i = 0; i < trimCount; i++) {
6700            final UriPermission perm = persisted.get(i);
6701
6702            if (DEBUG_URI_PERMISSION) {
6703                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6704            }
6705
6706            perm.releasePersistableModes(~0);
6707            removeUriPermissionIfNeededLocked(perm);
6708        }
6709
6710        return true;
6711    }
6712
6713    @Override
6714    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6715            String packageName, boolean incoming) {
6716        enforceNotIsolatedCaller("getPersistedUriPermissions");
6717        Preconditions.checkNotNull(packageName, "packageName");
6718
6719        final int callingUid = Binder.getCallingUid();
6720        final IPackageManager pm = AppGlobals.getPackageManager();
6721        try {
6722            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6723            if (packageUid != callingUid) {
6724                throw new SecurityException(
6725                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6726            }
6727        } catch (RemoteException e) {
6728            throw new SecurityException("Failed to verify package name ownership");
6729        }
6730
6731        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6732        synchronized (this) {
6733            if (incoming) {
6734                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6735                if (perms == null) {
6736                    Slog.w(TAG, "No permission grants found for " + packageName);
6737                } else {
6738                    final int size = perms.size();
6739                    for (int i = 0; i < size; i++) {
6740                        final UriPermission perm = perms.valueAt(i);
6741                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6742                            result.add(perm.buildPersistedPublicApiObject());
6743                        }
6744                    }
6745                }
6746            } else {
6747                final int size = mGrantedUriPermissions.size();
6748                for (int i = 0; i < size; i++) {
6749                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6750                    final int permsSize = perms.size();
6751                    for (int j = 0; j < permsSize; j++) {
6752                        final UriPermission perm = perms.valueAt(j);
6753                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6754                            result.add(perm.buildPersistedPublicApiObject());
6755                        }
6756                    }
6757                }
6758            }
6759        }
6760        return new ParceledListSlice<android.content.UriPermission>(result);
6761    }
6762
6763    @Override
6764    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6765        synchronized (this) {
6766            ProcessRecord app =
6767                who != null ? getRecordForAppLocked(who) : null;
6768            if (app == null) return;
6769
6770            Message msg = Message.obtain();
6771            msg.what = WAIT_FOR_DEBUGGER_MSG;
6772            msg.obj = app;
6773            msg.arg1 = waiting ? 1 : 0;
6774            mHandler.sendMessage(msg);
6775        }
6776    }
6777
6778    @Override
6779    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6780        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6781        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6782        outInfo.availMem = Process.getFreeMemory();
6783        outInfo.totalMem = Process.getTotalMemory();
6784        outInfo.threshold = homeAppMem;
6785        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6786        outInfo.hiddenAppThreshold = cachedAppMem;
6787        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6788                ProcessList.SERVICE_ADJ);
6789        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6790                ProcessList.VISIBLE_APP_ADJ);
6791        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6792                ProcessList.FOREGROUND_APP_ADJ);
6793    }
6794
6795    // =========================================================
6796    // TASK MANAGEMENT
6797    // =========================================================
6798
6799    @Override
6800    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6801                         IThumbnailReceiver receiver) {
6802        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6803
6804        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6805        ActivityRecord topRecord = null;
6806
6807        synchronized(this) {
6808            if (localLOGV) Slog.v(
6809                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6810                + ", receiver=" + receiver);
6811
6812            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6813                    != PackageManager.PERMISSION_GRANTED) {
6814                if (receiver != null) {
6815                    // If the caller wants to wait for pending thumbnails,
6816                    // it ain't gonna get them.
6817                    try {
6818                        receiver.finished();
6819                    } catch (RemoteException ex) {
6820                    }
6821                }
6822                String msg = "Permission Denial: getTasks() from pid="
6823                        + Binder.getCallingPid()
6824                        + ", uid=" + Binder.getCallingUid()
6825                        + " requires " + android.Manifest.permission.GET_TASKS;
6826                Slog.w(TAG, msg);
6827                throw new SecurityException(msg);
6828            }
6829
6830            // TODO: Improve with MRU list from all ActivityStacks.
6831            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6832
6833            if (!pending.pendingRecords.isEmpty()) {
6834                mPendingThumbnails.add(pending);
6835            }
6836        }
6837
6838        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6839
6840        if (topRecord != null) {
6841            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6842            try {
6843                IApplicationThread topThumbnail = topRecord.app.thread;
6844                topThumbnail.requestThumbnail(topRecord.appToken);
6845            } catch (Exception e) {
6846                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6847                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6848            }
6849        }
6850
6851        if (pending.pendingRecords.isEmpty() && receiver != null) {
6852            // In this case all thumbnails were available and the client
6853            // is being asked to be told when the remaining ones come in...
6854            // which is unusually, since the top-most currently running
6855            // activity should never have a canned thumbnail!  Oh well.
6856            try {
6857                receiver.finished();
6858            } catch (RemoteException ex) {
6859            }
6860        }
6861
6862        return list;
6863    }
6864
6865    TaskRecord getMostRecentTask() {
6866        return mRecentTasks.get(0);
6867    }
6868
6869    @Override
6870    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6871            int flags, int userId) {
6872        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6873                false, true, "getRecentTasks", null);
6874
6875        synchronized (this) {
6876            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6877                    "getRecentTasks()");
6878            final boolean detailed = checkCallingPermission(
6879                    android.Manifest.permission.GET_DETAILED_TASKS)
6880                    == PackageManager.PERMISSION_GRANTED;
6881
6882            IPackageManager pm = AppGlobals.getPackageManager();
6883
6884            final int N = mRecentTasks.size();
6885            ArrayList<ActivityManager.RecentTaskInfo> res
6886                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6887                            maxNum < N ? maxNum : N);
6888
6889            final Set<Integer> includedUsers;
6890            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
6891                includedUsers = getProfileIdsLocked(userId);
6892            } else {
6893                includedUsers = new HashSet<Integer>();
6894            }
6895            includedUsers.add(Integer.valueOf(userId));
6896            for (int i=0; i<N && maxNum > 0; i++) {
6897                TaskRecord tr = mRecentTasks.get(i);
6898                // Only add calling user or related users recent tasks
6899                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
6900
6901                // Return the entry if desired by the caller.  We always return
6902                // the first entry, because callers always expect this to be the
6903                // foreground app.  We may filter others if the caller has
6904                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6905                // we should exclude the entry.
6906
6907                if (i == 0
6908                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6909                        || (tr.intent == null)
6910                        || ((tr.intent.getFlags()
6911                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6912                    ActivityManager.RecentTaskInfo rti
6913                            = new ActivityManager.RecentTaskInfo();
6914                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6915                    rti.persistentId = tr.taskId;
6916                    rti.baseIntent = new Intent(
6917                            tr.intent != null ? tr.intent : tr.affinityIntent);
6918                    if (!detailed) {
6919                        rti.baseIntent.replaceExtras((Bundle)null);
6920                    }
6921                    rti.origActivity = tr.origActivity;
6922                    rti.description = tr.lastDescription;
6923                    rti.stackId = tr.stack.mStackId;
6924                    rti.userId = tr.userId;
6925
6926                    // Traverse upwards looking for any break between main task activities and
6927                    // utility activities.
6928                    final ArrayList<ActivityRecord> activities = tr.mActivities;
6929                    int activityNdx;
6930                    final int numActivities = activities.size();
6931                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
6932                            ++activityNdx) {
6933                        final ActivityRecord r = activities.get(activityNdx);
6934                        if (r.intent != null &&
6935                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
6936                                        != 0) {
6937                            break;
6938                        }
6939                    }
6940                    // Traverse downwards starting below break looking for set label and icon.
6941                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
6942                        final ActivityRecord r = activities.get(activityNdx);
6943                        if (r.activityLabel != null || r.activityIcon != null) {
6944                            rti.activityLabel = r.activityLabel;
6945                            rti.activityIcon = r.activityIcon;
6946                            break;
6947                        }
6948                    }
6949
6950                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6951                        // Check whether this activity is currently available.
6952                        try {
6953                            if (rti.origActivity != null) {
6954                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6955                                        == null) {
6956                                    continue;
6957                                }
6958                            } else if (rti.baseIntent != null) {
6959                                if (pm.queryIntentActivities(rti.baseIntent,
6960                                        null, 0, userId) == null) {
6961                                    continue;
6962                                }
6963                            }
6964                        } catch (RemoteException e) {
6965                            // Will never happen.
6966                        }
6967                    }
6968
6969                    res.add(rti);
6970                    maxNum--;
6971                }
6972            }
6973            return res;
6974        }
6975    }
6976
6977    private TaskRecord recentTaskForIdLocked(int id) {
6978        final int N = mRecentTasks.size();
6979            for (int i=0; i<N; i++) {
6980                TaskRecord tr = mRecentTasks.get(i);
6981                if (tr.taskId == id) {
6982                    return tr;
6983                }
6984            }
6985            return null;
6986    }
6987
6988    @Override
6989    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6990        synchronized (this) {
6991            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6992                    "getTaskThumbnails()");
6993            TaskRecord tr = recentTaskForIdLocked(id);
6994            if (tr != null) {
6995                return tr.getTaskThumbnailsLocked();
6996            }
6997        }
6998        return null;
6999    }
7000
7001    @Override
7002    public Bitmap getTaskTopThumbnail(int id) {
7003        synchronized (this) {
7004            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7005                    "getTaskTopThumbnail()");
7006            TaskRecord tr = recentTaskForIdLocked(id);
7007            if (tr != null) {
7008                return tr.getTaskTopThumbnailLocked();
7009            }
7010        }
7011        return null;
7012    }
7013
7014    @Override
7015    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
7016            Bitmap activityIcon) {
7017        synchronized (this) {
7018            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7019            if (r != null) {
7020                r.activityLabel = activityLabel.toString();
7021                r.activityIcon = activityIcon;
7022            }
7023        }
7024    }
7025
7026    @Override
7027    public boolean removeSubTask(int taskId, int subTaskIndex) {
7028        synchronized (this) {
7029            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7030                    "removeSubTask()");
7031            long ident = Binder.clearCallingIdentity();
7032            try {
7033                TaskRecord tr = recentTaskForIdLocked(taskId);
7034                if (tr != null) {
7035                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7036                }
7037                return false;
7038            } finally {
7039                Binder.restoreCallingIdentity(ident);
7040            }
7041        }
7042    }
7043
7044    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7045        if (!pr.killedByAm) {
7046            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7047            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7048                    pr.processName, pr.setAdj, reason);
7049            pr.killedByAm = true;
7050            Process.killProcessQuiet(pr.pid);
7051        }
7052    }
7053
7054    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7055        tr.disposeThumbnail();
7056        mRecentTasks.remove(tr);
7057        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7058        Intent baseIntent = new Intent(
7059                tr.intent != null ? tr.intent : tr.affinityIntent);
7060        ComponentName component = baseIntent.getComponent();
7061        if (component == null) {
7062            Slog.w(TAG, "Now component for base intent of task: " + tr);
7063            return;
7064        }
7065
7066        // Find any running services associated with this app.
7067        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7068
7069        if (killProcesses) {
7070            // Find any running processes associated with this app.
7071            final String pkg = component.getPackageName();
7072            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7073            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7074            for (int i=0; i<pmap.size(); i++) {
7075                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7076                for (int j=0; j<uids.size(); j++) {
7077                    ProcessRecord proc = uids.valueAt(j);
7078                    if (proc.userId != tr.userId) {
7079                        continue;
7080                    }
7081                    if (!proc.pkgList.containsKey(pkg)) {
7082                        continue;
7083                    }
7084                    procs.add(proc);
7085                }
7086            }
7087
7088            // Kill the running processes.
7089            for (int i=0; i<procs.size(); i++) {
7090                ProcessRecord pr = procs.get(i);
7091                if (pr == mHomeProcess) {
7092                    // Don't kill the home process along with tasks from the same package.
7093                    continue;
7094                }
7095                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7096                    killUnneededProcessLocked(pr, "remove task");
7097                } else {
7098                    pr.waitingToKill = "remove task";
7099                }
7100            }
7101        }
7102    }
7103
7104    /**
7105     * Removes the task with the specified task id.
7106     *
7107     * @param taskId Identifier of the task to be removed.
7108     * @param flags Additional operational flags.  May be 0 or
7109     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7110     * @return Returns true if the given task was found and removed.
7111     */
7112    private boolean removeTaskByIdLocked(int taskId, int flags) {
7113        TaskRecord tr = recentTaskForIdLocked(taskId);
7114        if (tr != null) {
7115            tr.removeTaskActivitiesLocked(-1, false);
7116            cleanUpRemovedTaskLocked(tr, flags);
7117            return true;
7118        }
7119        return false;
7120    }
7121
7122    @Override
7123    public boolean removeTask(int taskId, int flags) {
7124        synchronized (this) {
7125            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7126                    "removeTask()");
7127            long ident = Binder.clearCallingIdentity();
7128            try {
7129                return removeTaskByIdLocked(taskId, flags);
7130            } finally {
7131                Binder.restoreCallingIdentity(ident);
7132            }
7133        }
7134    }
7135
7136    /**
7137     * TODO: Add mController hook
7138     */
7139    @Override
7140    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7141        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7142                "moveTaskToFront()");
7143
7144        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7145        synchronized(this) {
7146            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7147                    Binder.getCallingUid(), "Task to front")) {
7148                ActivityOptions.abort(options);
7149                return;
7150            }
7151            final long origId = Binder.clearCallingIdentity();
7152            try {
7153                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7154                if (task == null) {
7155                    return;
7156                }
7157                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7158                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7159                    return;
7160                }
7161                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7162            } finally {
7163                Binder.restoreCallingIdentity(origId);
7164            }
7165            ActivityOptions.abort(options);
7166        }
7167    }
7168
7169    @Override
7170    public void moveTaskToBack(int taskId) {
7171        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7172                "moveTaskToBack()");
7173
7174        synchronized(this) {
7175            TaskRecord tr = recentTaskForIdLocked(taskId);
7176            if (tr != null) {
7177                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7178                ActivityStack stack = tr.stack;
7179                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7180                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7181                            Binder.getCallingUid(), "Task to back")) {
7182                        return;
7183                    }
7184                }
7185                final long origId = Binder.clearCallingIdentity();
7186                try {
7187                    stack.moveTaskToBackLocked(taskId, null);
7188                } finally {
7189                    Binder.restoreCallingIdentity(origId);
7190                }
7191            }
7192        }
7193    }
7194
7195    /**
7196     * Moves an activity, and all of the other activities within the same task, to the bottom
7197     * of the history stack.  The activity's order within the task is unchanged.
7198     *
7199     * @param token A reference to the activity we wish to move
7200     * @param nonRoot If false then this only works if the activity is the root
7201     *                of a task; if true it will work for any activity in a task.
7202     * @return Returns true if the move completed, false if not.
7203     */
7204    @Override
7205    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7206        enforceNotIsolatedCaller("moveActivityTaskToBack");
7207        synchronized(this) {
7208            final long origId = Binder.clearCallingIdentity();
7209            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7210            if (taskId >= 0) {
7211                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7212            }
7213            Binder.restoreCallingIdentity(origId);
7214        }
7215        return false;
7216    }
7217
7218    @Override
7219    public void moveTaskBackwards(int task) {
7220        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7221                "moveTaskBackwards()");
7222
7223        synchronized(this) {
7224            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7225                    Binder.getCallingUid(), "Task backwards")) {
7226                return;
7227            }
7228            final long origId = Binder.clearCallingIdentity();
7229            moveTaskBackwardsLocked(task);
7230            Binder.restoreCallingIdentity(origId);
7231        }
7232    }
7233
7234    private final void moveTaskBackwardsLocked(int task) {
7235        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7236    }
7237
7238    @Override
7239    public IBinder getHomeActivityToken() throws RemoteException {
7240        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7241                "getHomeActivityToken()");
7242        synchronized (this) {
7243            return mStackSupervisor.getHomeActivityToken();
7244        }
7245    }
7246
7247    @Override
7248    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7249            IActivityContainerCallback callback) throws RemoteException {
7250        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7251                "createActivityContainer()");
7252        synchronized (this) {
7253            if (parentActivityToken == null) {
7254                throw new IllegalArgumentException("parent token must not be null");
7255            }
7256            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7257            if (r == null) {
7258                return null;
7259            }
7260            if (callback == null) {
7261                throw new IllegalArgumentException("callback must not be null");
7262            }
7263            return mStackSupervisor.createActivityContainer(r, callback);
7264        }
7265    }
7266
7267    @Override
7268    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7269        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7270                "deleteActivityContainer()");
7271        synchronized (this) {
7272            mStackSupervisor.deleteActivityContainer(container);
7273        }
7274    }
7275
7276    @Override
7277    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7278            throws RemoteException {
7279        synchronized (this) {
7280            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7281            if (stack != null) {
7282                return stack.mActivityContainer;
7283            }
7284            return null;
7285        }
7286    }
7287
7288    @Override
7289    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7290        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7291                "moveTaskToStack()");
7292        if (stackId == HOME_STACK_ID) {
7293            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7294                    new RuntimeException("here").fillInStackTrace());
7295        }
7296        synchronized (this) {
7297            long ident = Binder.clearCallingIdentity();
7298            try {
7299                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7300                        + stackId + " toTop=" + toTop);
7301                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7302            } finally {
7303                Binder.restoreCallingIdentity(ident);
7304            }
7305        }
7306    }
7307
7308    @Override
7309    public void resizeStack(int stackBoxId, Rect bounds) {
7310        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7311                "resizeStackBox()");
7312        long ident = Binder.clearCallingIdentity();
7313        try {
7314            mWindowManager.resizeStack(stackBoxId, bounds);
7315        } finally {
7316            Binder.restoreCallingIdentity(ident);
7317        }
7318    }
7319
7320    @Override
7321    public List<StackInfo> getAllStackInfos() {
7322        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7323                "getAllStackInfos()");
7324        long ident = Binder.clearCallingIdentity();
7325        try {
7326            synchronized (this) {
7327                return mStackSupervisor.getAllStackInfosLocked();
7328            }
7329        } finally {
7330            Binder.restoreCallingIdentity(ident);
7331        }
7332    }
7333
7334    @Override
7335    public StackInfo getStackInfo(int stackId) {
7336        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7337                "getStackInfo()");
7338        long ident = Binder.clearCallingIdentity();
7339        try {
7340            synchronized (this) {
7341                return mStackSupervisor.getStackInfoLocked(stackId);
7342            }
7343        } finally {
7344            Binder.restoreCallingIdentity(ident);
7345        }
7346    }
7347
7348    @Override
7349    public boolean isInHomeStack(int taskId) {
7350        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7351                "getStackInfo()");
7352        long ident = Binder.clearCallingIdentity();
7353        try {
7354            synchronized (this) {
7355                TaskRecord tr = recentTaskForIdLocked(taskId);
7356                if (tr != null) {
7357                    return tr.stack.isHomeStack();
7358                }
7359            }
7360        } finally {
7361            Binder.restoreCallingIdentity(ident);
7362        }
7363        return false;
7364    }
7365
7366    @Override
7367    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7368        synchronized(this) {
7369            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7370        }
7371    }
7372
7373    private boolean isLockTaskAuthorized(ComponentName name) {
7374//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7375//                "startLockTaskMode()");
7376//        DevicePolicyManager dpm = (DevicePolicyManager)
7377//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7378//        return dpm != null && dpm.isLockTaskPermitted(name);
7379        return true;
7380    }
7381
7382    private void startLockTaskMode(TaskRecord task) {
7383        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7384            return;
7385        }
7386        long ident = Binder.clearCallingIdentity();
7387        try {
7388            synchronized (this) {
7389                // Since we lost lock on task, make sure it is still there.
7390                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7391                if (task != null) {
7392                    mStackSupervisor.setLockTaskModeLocked(task);
7393                }
7394            }
7395        } finally {
7396            Binder.restoreCallingIdentity(ident);
7397        }
7398    }
7399
7400    @Override
7401    public void startLockTaskMode(int taskId) {
7402        long ident = Binder.clearCallingIdentity();
7403        try {
7404            final TaskRecord task;
7405            synchronized (this) {
7406                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7407            }
7408            if (task != null) {
7409                startLockTaskMode(task);
7410            }
7411        } finally {
7412            Binder.restoreCallingIdentity(ident);
7413        }
7414    }
7415
7416    @Override
7417    public void startLockTaskMode(IBinder token) {
7418        long ident = Binder.clearCallingIdentity();
7419        try {
7420            final TaskRecord task;
7421            synchronized (this) {
7422                final ActivityRecord r = ActivityRecord.forToken(token);
7423                if (r == null) {
7424                    return;
7425                }
7426                task = r.task;
7427            }
7428            if (task != null) {
7429                startLockTaskMode(task);
7430            }
7431        } finally {
7432            Binder.restoreCallingIdentity(ident);
7433        }
7434    }
7435
7436    @Override
7437    public void stopLockTaskMode() {
7438//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7439//                "stopLockTaskMode()");
7440        synchronized (this) {
7441            mStackSupervisor.setLockTaskModeLocked(null);
7442        }
7443    }
7444
7445    @Override
7446    public boolean isInLockTaskMode() {
7447        synchronized (this) {
7448            return mStackSupervisor.isInLockTaskMode();
7449        }
7450    }
7451
7452    // =========================================================
7453    // THUMBNAILS
7454    // =========================================================
7455
7456    public void reportThumbnail(IBinder token,
7457            Bitmap thumbnail, CharSequence description) {
7458        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7459        final long origId = Binder.clearCallingIdentity();
7460        sendPendingThumbnail(null, token, thumbnail, description, true);
7461        Binder.restoreCallingIdentity(origId);
7462    }
7463
7464    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7465            Bitmap thumbnail, CharSequence description, boolean always) {
7466        TaskRecord task;
7467        ArrayList<PendingThumbnailsRecord> receivers = null;
7468
7469        //System.out.println("Send pending thumbnail: " + r);
7470
7471        synchronized(this) {
7472            if (r == null) {
7473                r = ActivityRecord.isInStackLocked(token);
7474                if (r == null) {
7475                    return;
7476                }
7477            }
7478            if (thumbnail == null && r.thumbHolder != null) {
7479                thumbnail = r.thumbHolder.lastThumbnail;
7480                description = r.thumbHolder.lastDescription;
7481            }
7482            if (thumbnail == null && !always) {
7483                // If there is no thumbnail, and this entry is not actually
7484                // going away, then abort for now and pick up the next
7485                // thumbnail we get.
7486                return;
7487            }
7488            task = r.task;
7489
7490            int N = mPendingThumbnails.size();
7491            int i=0;
7492            while (i<N) {
7493                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7494                //System.out.println("Looking in " + pr.pendingRecords);
7495                if (pr.pendingRecords.remove(r)) {
7496                    if (receivers == null) {
7497                        receivers = new ArrayList<PendingThumbnailsRecord>();
7498                    }
7499                    receivers.add(pr);
7500                    if (pr.pendingRecords.size() == 0) {
7501                        pr.finished = true;
7502                        mPendingThumbnails.remove(i);
7503                        N--;
7504                        continue;
7505                    }
7506                }
7507                i++;
7508            }
7509        }
7510
7511        if (receivers != null) {
7512            final int N = receivers.size();
7513            for (int i=0; i<N; i++) {
7514                try {
7515                    PendingThumbnailsRecord pr = receivers.get(i);
7516                    pr.receiver.newThumbnail(
7517                        task != null ? task.taskId : -1, thumbnail, description);
7518                    if (pr.finished) {
7519                        pr.receiver.finished();
7520                    }
7521                } catch (Exception e) {
7522                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7523                }
7524            }
7525        }
7526    }
7527
7528    // =========================================================
7529    // CONTENT PROVIDERS
7530    // =========================================================
7531
7532    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7533        List<ProviderInfo> providers = null;
7534        try {
7535            providers = AppGlobals.getPackageManager().
7536                queryContentProviders(app.processName, app.uid,
7537                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7538        } catch (RemoteException ex) {
7539        }
7540        if (DEBUG_MU)
7541            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7542        int userId = app.userId;
7543        if (providers != null) {
7544            int N = providers.size();
7545            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7546            for (int i=0; i<N; i++) {
7547                ProviderInfo cpi =
7548                    (ProviderInfo)providers.get(i);
7549                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7550                        cpi.name, cpi.flags);
7551                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7552                    // This is a singleton provider, but a user besides the
7553                    // default user is asking to initialize a process it runs
7554                    // in...  well, no, it doesn't actually run in this process,
7555                    // it runs in the process of the default user.  Get rid of it.
7556                    providers.remove(i);
7557                    N--;
7558                    i--;
7559                    continue;
7560                }
7561
7562                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7563                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7564                if (cpr == null) {
7565                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7566                    mProviderMap.putProviderByClass(comp, cpr);
7567                }
7568                if (DEBUG_MU)
7569                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7570                app.pubProviders.put(cpi.name, cpr);
7571                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7572                    // Don't add this if it is a platform component that is marked
7573                    // to run in multiple processes, because this is actually
7574                    // part of the framework so doesn't make sense to track as a
7575                    // separate apk in the process.
7576                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7577                }
7578                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7579            }
7580        }
7581        return providers;
7582    }
7583
7584    /**
7585     * Check if {@link ProcessRecord} has a possible chance at accessing the
7586     * given {@link ProviderInfo}. Final permission checking is always done
7587     * in {@link ContentProvider}.
7588     */
7589    private final String checkContentProviderPermissionLocked(
7590            ProviderInfo cpi, ProcessRecord r) {
7591        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7592        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7593        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7594                cpi.applicationInfo.uid, cpi.exported)
7595                == PackageManager.PERMISSION_GRANTED) {
7596            return null;
7597        }
7598        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7599                cpi.applicationInfo.uid, cpi.exported)
7600                == PackageManager.PERMISSION_GRANTED) {
7601            return null;
7602        }
7603
7604        PathPermission[] pps = cpi.pathPermissions;
7605        if (pps != null) {
7606            int i = pps.length;
7607            while (i > 0) {
7608                i--;
7609                PathPermission pp = pps[i];
7610                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7611                        cpi.applicationInfo.uid, cpi.exported)
7612                        == PackageManager.PERMISSION_GRANTED) {
7613                    return null;
7614                }
7615                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7616                        cpi.applicationInfo.uid, cpi.exported)
7617                        == PackageManager.PERMISSION_GRANTED) {
7618                    return null;
7619                }
7620            }
7621        }
7622
7623        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7624        if (perms != null) {
7625            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7626                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7627                    return null;
7628                }
7629            }
7630        }
7631
7632        String msg;
7633        if (!cpi.exported) {
7634            msg = "Permission Denial: opening provider " + cpi.name
7635                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7636                    + ", uid=" + callingUid + ") that is not exported from uid "
7637                    + cpi.applicationInfo.uid;
7638        } else {
7639            msg = "Permission Denial: opening provider " + cpi.name
7640                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7641                    + ", uid=" + callingUid + ") requires "
7642                    + cpi.readPermission + " or " + cpi.writePermission;
7643        }
7644        Slog.w(TAG, msg);
7645        return msg;
7646    }
7647
7648    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7649            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7650        if (r != null) {
7651            for (int i=0; i<r.conProviders.size(); i++) {
7652                ContentProviderConnection conn = r.conProviders.get(i);
7653                if (conn.provider == cpr) {
7654                    if (DEBUG_PROVIDER) Slog.v(TAG,
7655                            "Adding provider requested by "
7656                            + r.processName + " from process "
7657                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7658                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7659                    if (stable) {
7660                        conn.stableCount++;
7661                        conn.numStableIncs++;
7662                    } else {
7663                        conn.unstableCount++;
7664                        conn.numUnstableIncs++;
7665                    }
7666                    return conn;
7667                }
7668            }
7669            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7670            if (stable) {
7671                conn.stableCount = 1;
7672                conn.numStableIncs = 1;
7673            } else {
7674                conn.unstableCount = 1;
7675                conn.numUnstableIncs = 1;
7676            }
7677            cpr.connections.add(conn);
7678            r.conProviders.add(conn);
7679            return conn;
7680        }
7681        cpr.addExternalProcessHandleLocked(externalProcessToken);
7682        return null;
7683    }
7684
7685    boolean decProviderCountLocked(ContentProviderConnection conn,
7686            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7687        if (conn != null) {
7688            cpr = conn.provider;
7689            if (DEBUG_PROVIDER) Slog.v(TAG,
7690                    "Removing provider requested by "
7691                    + conn.client.processName + " from process "
7692                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7693                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7694            if (stable) {
7695                conn.stableCount--;
7696            } else {
7697                conn.unstableCount--;
7698            }
7699            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7700                cpr.connections.remove(conn);
7701                conn.client.conProviders.remove(conn);
7702                return true;
7703            }
7704            return false;
7705        }
7706        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7707        return false;
7708    }
7709
7710    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7711            String name, IBinder token, boolean stable, int userId) {
7712        ContentProviderRecord cpr;
7713        ContentProviderConnection conn = null;
7714        ProviderInfo cpi = null;
7715
7716        synchronized(this) {
7717            ProcessRecord r = null;
7718            if (caller != null) {
7719                r = getRecordForAppLocked(caller);
7720                if (r == null) {
7721                    throw new SecurityException(
7722                            "Unable to find app for caller " + caller
7723                          + " (pid=" + Binder.getCallingPid()
7724                          + ") when getting content provider " + name);
7725                }
7726            }
7727
7728            // First check if this content provider has been published...
7729            cpr = mProviderMap.getProviderByName(name, userId);
7730            boolean providerRunning = cpr != null;
7731            if (providerRunning) {
7732                cpi = cpr.info;
7733                String msg;
7734                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7735                    throw new SecurityException(msg);
7736                }
7737
7738                if (r != null && cpr.canRunHere(r)) {
7739                    // This provider has been published or is in the process
7740                    // of being published...  but it is also allowed to run
7741                    // in the caller's process, so don't make a connection
7742                    // and just let the caller instantiate its own instance.
7743                    ContentProviderHolder holder = cpr.newHolder(null);
7744                    // don't give caller the provider object, it needs
7745                    // to make its own.
7746                    holder.provider = null;
7747                    return holder;
7748                }
7749
7750                final long origId = Binder.clearCallingIdentity();
7751
7752                // In this case the provider instance already exists, so we can
7753                // return it right away.
7754                conn = incProviderCountLocked(r, cpr, token, stable);
7755                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7756                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7757                        // If this is a perceptible app accessing the provider,
7758                        // make sure to count it as being accessed and thus
7759                        // back up on the LRU list.  This is good because
7760                        // content providers are often expensive to start.
7761                        updateLruProcessLocked(cpr.proc, false, null);
7762                    }
7763                }
7764
7765                if (cpr.proc != null) {
7766                    if (false) {
7767                        if (cpr.name.flattenToShortString().equals(
7768                                "com.android.providers.calendar/.CalendarProvider2")) {
7769                            Slog.v(TAG, "****************** KILLING "
7770                                + cpr.name.flattenToShortString());
7771                            Process.killProcess(cpr.proc.pid);
7772                        }
7773                    }
7774                    boolean success = updateOomAdjLocked(cpr.proc);
7775                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7776                    // NOTE: there is still a race here where a signal could be
7777                    // pending on the process even though we managed to update its
7778                    // adj level.  Not sure what to do about this, but at least
7779                    // the race is now smaller.
7780                    if (!success) {
7781                        // Uh oh...  it looks like the provider's process
7782                        // has been killed on us.  We need to wait for a new
7783                        // process to be started, and make sure its death
7784                        // doesn't kill our process.
7785                        Slog.i(TAG,
7786                                "Existing provider " + cpr.name.flattenToShortString()
7787                                + " is crashing; detaching " + r);
7788                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7789                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7790                        if (!lastRef) {
7791                            // This wasn't the last ref our process had on
7792                            // the provider...  we have now been killed, bail.
7793                            return null;
7794                        }
7795                        providerRunning = false;
7796                        conn = null;
7797                    }
7798                }
7799
7800                Binder.restoreCallingIdentity(origId);
7801            }
7802
7803            boolean singleton;
7804            if (!providerRunning) {
7805                try {
7806                    cpi = AppGlobals.getPackageManager().
7807                        resolveContentProvider(name,
7808                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7809                } catch (RemoteException ex) {
7810                }
7811                if (cpi == null) {
7812                    return null;
7813                }
7814                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7815                        cpi.name, cpi.flags);
7816                if (singleton) {
7817                    userId = 0;
7818                }
7819                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7820
7821                String msg;
7822                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7823                    throw new SecurityException(msg);
7824                }
7825
7826                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7827                        && !cpi.processName.equals("system")) {
7828                    // If this content provider does not run in the system
7829                    // process, and the system is not yet ready to run other
7830                    // processes, then fail fast instead of hanging.
7831                    throw new IllegalArgumentException(
7832                            "Attempt to launch content provider before system ready");
7833                }
7834
7835                // Make sure that the user who owns this provider is started.  If not,
7836                // we don't want to allow it to run.
7837                if (mStartedUsers.get(userId) == null) {
7838                    Slog.w(TAG, "Unable to launch app "
7839                            + cpi.applicationInfo.packageName + "/"
7840                            + cpi.applicationInfo.uid + " for provider "
7841                            + name + ": user " + userId + " is stopped");
7842                    return null;
7843                }
7844
7845                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7846                cpr = mProviderMap.getProviderByClass(comp, userId);
7847                final boolean firstClass = cpr == null;
7848                if (firstClass) {
7849                    try {
7850                        ApplicationInfo ai =
7851                            AppGlobals.getPackageManager().
7852                                getApplicationInfo(
7853                                        cpi.applicationInfo.packageName,
7854                                        STOCK_PM_FLAGS, userId);
7855                        if (ai == null) {
7856                            Slog.w(TAG, "No package info for content provider "
7857                                    + cpi.name);
7858                            return null;
7859                        }
7860                        ai = getAppInfoForUser(ai, userId);
7861                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7862                    } catch (RemoteException ex) {
7863                        // pm is in same process, this will never happen.
7864                    }
7865                }
7866
7867                if (r != null && cpr.canRunHere(r)) {
7868                    // If this is a multiprocess provider, then just return its
7869                    // info and allow the caller to instantiate it.  Only do
7870                    // this if the provider is the same user as the caller's
7871                    // process, or can run as root (so can be in any process).
7872                    return cpr.newHolder(null);
7873                }
7874
7875                if (DEBUG_PROVIDER) {
7876                    RuntimeException e = new RuntimeException("here");
7877                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7878                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7879                }
7880
7881                // This is single process, and our app is now connecting to it.
7882                // See if we are already in the process of launching this
7883                // provider.
7884                final int N = mLaunchingProviders.size();
7885                int i;
7886                for (i=0; i<N; i++) {
7887                    if (mLaunchingProviders.get(i) == cpr) {
7888                        break;
7889                    }
7890                }
7891
7892                // If the provider is not already being launched, then get it
7893                // started.
7894                if (i >= N) {
7895                    final long origId = Binder.clearCallingIdentity();
7896
7897                    try {
7898                        // Content provider is now in use, its package can't be stopped.
7899                        try {
7900                            AppGlobals.getPackageManager().setPackageStoppedState(
7901                                    cpr.appInfo.packageName, false, userId);
7902                        } catch (RemoteException e) {
7903                        } catch (IllegalArgumentException e) {
7904                            Slog.w(TAG, "Failed trying to unstop package "
7905                                    + cpr.appInfo.packageName + ": " + e);
7906                        }
7907
7908                        // Use existing process if already started
7909                        ProcessRecord proc = getProcessRecordLocked(
7910                                cpi.processName, cpr.appInfo.uid, false);
7911                        if (proc != null && proc.thread != null) {
7912                            if (DEBUG_PROVIDER) {
7913                                Slog.d(TAG, "Installing in existing process " + proc);
7914                            }
7915                            proc.pubProviders.put(cpi.name, cpr);
7916                            try {
7917                                proc.thread.scheduleInstallProvider(cpi);
7918                            } catch (RemoteException e) {
7919                            }
7920                        } else {
7921                            proc = startProcessLocked(cpi.processName,
7922                                    cpr.appInfo, false, 0, "content provider",
7923                                    new ComponentName(cpi.applicationInfo.packageName,
7924                                            cpi.name), false, false, false);
7925                            if (proc == null) {
7926                                Slog.w(TAG, "Unable to launch app "
7927                                        + cpi.applicationInfo.packageName + "/"
7928                                        + cpi.applicationInfo.uid + " for provider "
7929                                        + name + ": process is bad");
7930                                return null;
7931                            }
7932                        }
7933                        cpr.launchingApp = proc;
7934                        mLaunchingProviders.add(cpr);
7935                    } finally {
7936                        Binder.restoreCallingIdentity(origId);
7937                    }
7938                }
7939
7940                // Make sure the provider is published (the same provider class
7941                // may be published under multiple names).
7942                if (firstClass) {
7943                    mProviderMap.putProviderByClass(comp, cpr);
7944                }
7945
7946                mProviderMap.putProviderByName(name, cpr);
7947                conn = incProviderCountLocked(r, cpr, token, stable);
7948                if (conn != null) {
7949                    conn.waiting = true;
7950                }
7951            }
7952        }
7953
7954        // Wait for the provider to be published...
7955        synchronized (cpr) {
7956            while (cpr.provider == null) {
7957                if (cpr.launchingApp == null) {
7958                    Slog.w(TAG, "Unable to launch app "
7959                            + cpi.applicationInfo.packageName + "/"
7960                            + cpi.applicationInfo.uid + " for provider "
7961                            + name + ": launching app became null");
7962                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7963                            UserHandle.getUserId(cpi.applicationInfo.uid),
7964                            cpi.applicationInfo.packageName,
7965                            cpi.applicationInfo.uid, name);
7966                    return null;
7967                }
7968                try {
7969                    if (DEBUG_MU) {
7970                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7971                                + cpr.launchingApp);
7972                    }
7973                    if (conn != null) {
7974                        conn.waiting = true;
7975                    }
7976                    cpr.wait();
7977                } catch (InterruptedException ex) {
7978                } finally {
7979                    if (conn != null) {
7980                        conn.waiting = false;
7981                    }
7982                }
7983            }
7984        }
7985        return cpr != null ? cpr.newHolder(conn) : null;
7986    }
7987
7988    public final ContentProviderHolder getContentProvider(
7989            IApplicationThread caller, String name, int userId, boolean stable) {
7990        enforceNotIsolatedCaller("getContentProvider");
7991        if (caller == null) {
7992            String msg = "null IApplicationThread when getting content provider "
7993                    + name;
7994            Slog.w(TAG, msg);
7995            throw new SecurityException(msg);
7996        }
7997
7998        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7999                false, true, "getContentProvider", null);
8000        return getContentProviderImpl(caller, name, null, stable, userId);
8001    }
8002
8003    public ContentProviderHolder getContentProviderExternal(
8004            String name, int userId, IBinder token) {
8005        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8006            "Do not have permission in call getContentProviderExternal()");
8007        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8008                false, true, "getContentProvider", null);
8009        return getContentProviderExternalUnchecked(name, token, userId);
8010    }
8011
8012    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8013            IBinder token, int userId) {
8014        return getContentProviderImpl(null, name, token, true, userId);
8015    }
8016
8017    /**
8018     * Drop a content provider from a ProcessRecord's bookkeeping
8019     */
8020    public void removeContentProvider(IBinder connection, boolean stable) {
8021        enforceNotIsolatedCaller("removeContentProvider");
8022        long ident = Binder.clearCallingIdentity();
8023        try {
8024            synchronized (this) {
8025                ContentProviderConnection conn;
8026                try {
8027                    conn = (ContentProviderConnection)connection;
8028                } catch (ClassCastException e) {
8029                    String msg ="removeContentProvider: " + connection
8030                            + " not a ContentProviderConnection";
8031                    Slog.w(TAG, msg);
8032                    throw new IllegalArgumentException(msg);
8033                }
8034                if (conn == null) {
8035                    throw new NullPointerException("connection is null");
8036                }
8037                if (decProviderCountLocked(conn, null, null, stable)) {
8038                    updateOomAdjLocked();
8039                }
8040            }
8041        } finally {
8042            Binder.restoreCallingIdentity(ident);
8043        }
8044    }
8045
8046    public void removeContentProviderExternal(String name, IBinder token) {
8047        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8048            "Do not have permission in call removeContentProviderExternal()");
8049        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8050    }
8051
8052    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8053        synchronized (this) {
8054            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8055            if(cpr == null) {
8056                //remove from mProvidersByClass
8057                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8058                return;
8059            }
8060
8061            //update content provider record entry info
8062            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8063            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8064            if (localCpr.hasExternalProcessHandles()) {
8065                if (localCpr.removeExternalProcessHandleLocked(token)) {
8066                    updateOomAdjLocked();
8067                } else {
8068                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8069                            + " with no external reference for token: "
8070                            + token + ".");
8071                }
8072            } else {
8073                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8074                        + " with no external references.");
8075            }
8076        }
8077    }
8078
8079    public final void publishContentProviders(IApplicationThread caller,
8080            List<ContentProviderHolder> providers) {
8081        if (providers == null) {
8082            return;
8083        }
8084
8085        enforceNotIsolatedCaller("publishContentProviders");
8086        synchronized (this) {
8087            final ProcessRecord r = getRecordForAppLocked(caller);
8088            if (DEBUG_MU)
8089                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8090            if (r == null) {
8091                throw new SecurityException(
8092                        "Unable to find app for caller " + caller
8093                      + " (pid=" + Binder.getCallingPid()
8094                      + ") when publishing content providers");
8095            }
8096
8097            final long origId = Binder.clearCallingIdentity();
8098
8099            final int N = providers.size();
8100            for (int i=0; i<N; i++) {
8101                ContentProviderHolder src = providers.get(i);
8102                if (src == null || src.info == null || src.provider == null) {
8103                    continue;
8104                }
8105                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8106                if (DEBUG_MU)
8107                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8108                if (dst != null) {
8109                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8110                    mProviderMap.putProviderByClass(comp, dst);
8111                    String names[] = dst.info.authority.split(";");
8112                    for (int j = 0; j < names.length; j++) {
8113                        mProviderMap.putProviderByName(names[j], dst);
8114                    }
8115
8116                    int NL = mLaunchingProviders.size();
8117                    int j;
8118                    for (j=0; j<NL; j++) {
8119                        if (mLaunchingProviders.get(j) == dst) {
8120                            mLaunchingProviders.remove(j);
8121                            j--;
8122                            NL--;
8123                        }
8124                    }
8125                    synchronized (dst) {
8126                        dst.provider = src.provider;
8127                        dst.proc = r;
8128                        dst.notifyAll();
8129                    }
8130                    updateOomAdjLocked(r);
8131                }
8132            }
8133
8134            Binder.restoreCallingIdentity(origId);
8135        }
8136    }
8137
8138    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8139        ContentProviderConnection conn;
8140        try {
8141            conn = (ContentProviderConnection)connection;
8142        } catch (ClassCastException e) {
8143            String msg ="refContentProvider: " + connection
8144                    + " not a ContentProviderConnection";
8145            Slog.w(TAG, msg);
8146            throw new IllegalArgumentException(msg);
8147        }
8148        if (conn == null) {
8149            throw new NullPointerException("connection is null");
8150        }
8151
8152        synchronized (this) {
8153            if (stable > 0) {
8154                conn.numStableIncs += stable;
8155            }
8156            stable = conn.stableCount + stable;
8157            if (stable < 0) {
8158                throw new IllegalStateException("stableCount < 0: " + stable);
8159            }
8160
8161            if (unstable > 0) {
8162                conn.numUnstableIncs += unstable;
8163            }
8164            unstable = conn.unstableCount + unstable;
8165            if (unstable < 0) {
8166                throw new IllegalStateException("unstableCount < 0: " + unstable);
8167            }
8168
8169            if ((stable+unstable) <= 0) {
8170                throw new IllegalStateException("ref counts can't go to zero here: stable="
8171                        + stable + " unstable=" + unstable);
8172            }
8173            conn.stableCount = stable;
8174            conn.unstableCount = unstable;
8175            return !conn.dead;
8176        }
8177    }
8178
8179    public void unstableProviderDied(IBinder connection) {
8180        ContentProviderConnection conn;
8181        try {
8182            conn = (ContentProviderConnection)connection;
8183        } catch (ClassCastException e) {
8184            String msg ="refContentProvider: " + connection
8185                    + " not a ContentProviderConnection";
8186            Slog.w(TAG, msg);
8187            throw new IllegalArgumentException(msg);
8188        }
8189        if (conn == null) {
8190            throw new NullPointerException("connection is null");
8191        }
8192
8193        // Safely retrieve the content provider associated with the connection.
8194        IContentProvider provider;
8195        synchronized (this) {
8196            provider = conn.provider.provider;
8197        }
8198
8199        if (provider == null) {
8200            // Um, yeah, we're way ahead of you.
8201            return;
8202        }
8203
8204        // Make sure the caller is being honest with us.
8205        if (provider.asBinder().pingBinder()) {
8206            // Er, no, still looks good to us.
8207            synchronized (this) {
8208                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8209                        + " says " + conn + " died, but we don't agree");
8210                return;
8211            }
8212        }
8213
8214        // Well look at that!  It's dead!
8215        synchronized (this) {
8216            if (conn.provider.provider != provider) {
8217                // But something changed...  good enough.
8218                return;
8219            }
8220
8221            ProcessRecord proc = conn.provider.proc;
8222            if (proc == null || proc.thread == null) {
8223                // Seems like the process is already cleaned up.
8224                return;
8225            }
8226
8227            // As far as we're concerned, this is just like receiving a
8228            // death notification...  just a bit prematurely.
8229            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8230                    + ") early provider death");
8231            final long ident = Binder.clearCallingIdentity();
8232            try {
8233                appDiedLocked(proc, proc.pid, proc.thread);
8234            } finally {
8235                Binder.restoreCallingIdentity(ident);
8236            }
8237        }
8238    }
8239
8240    @Override
8241    public void appNotRespondingViaProvider(IBinder connection) {
8242        enforceCallingPermission(
8243                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8244
8245        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8246        if (conn == null) {
8247            Slog.w(TAG, "ContentProviderConnection is null");
8248            return;
8249        }
8250
8251        final ProcessRecord host = conn.provider.proc;
8252        if (host == null) {
8253            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8254            return;
8255        }
8256
8257        final long token = Binder.clearCallingIdentity();
8258        try {
8259            appNotResponding(host, null, null, false, "ContentProvider not responding");
8260        } finally {
8261            Binder.restoreCallingIdentity(token);
8262        }
8263    }
8264
8265    public final void installSystemProviders() {
8266        List<ProviderInfo> providers;
8267        synchronized (this) {
8268            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8269            providers = generateApplicationProvidersLocked(app);
8270            if (providers != null) {
8271                for (int i=providers.size()-1; i>=0; i--) {
8272                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8273                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8274                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8275                                + ": not system .apk");
8276                        providers.remove(i);
8277                    }
8278                }
8279            }
8280        }
8281        if (providers != null) {
8282            mSystemThread.installSystemProviders(providers);
8283        }
8284
8285        mCoreSettingsObserver = new CoreSettingsObserver(this);
8286
8287        mUsageStatsService.monitorPackages();
8288    }
8289
8290    /**
8291     * Allows app to retrieve the MIME type of a URI without having permission
8292     * to access its content provider.
8293     *
8294     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8295     *
8296     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8297     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8298     */
8299    public String getProviderMimeType(Uri uri, int userId) {
8300        enforceNotIsolatedCaller("getProviderMimeType");
8301        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8302                userId, false, true, "getProviderMimeType", null);
8303        final String name = uri.getAuthority();
8304        final long ident = Binder.clearCallingIdentity();
8305        ContentProviderHolder holder = null;
8306
8307        try {
8308            holder = getContentProviderExternalUnchecked(name, null, userId);
8309            if (holder != null) {
8310                return holder.provider.getType(uri);
8311            }
8312        } catch (RemoteException e) {
8313            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8314            return null;
8315        } finally {
8316            if (holder != null) {
8317                removeContentProviderExternalUnchecked(name, null, userId);
8318            }
8319            Binder.restoreCallingIdentity(ident);
8320        }
8321
8322        return null;
8323    }
8324
8325    // =========================================================
8326    // GLOBAL MANAGEMENT
8327    // =========================================================
8328
8329    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8330            boolean isolated) {
8331        String proc = customProcess != null ? customProcess : info.processName;
8332        BatteryStatsImpl.Uid.Proc ps = null;
8333        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8334        int uid = info.uid;
8335        if (isolated) {
8336            int userId = UserHandle.getUserId(uid);
8337            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8338            while (true) {
8339                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8340                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8341                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8342                }
8343                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8344                mNextIsolatedProcessUid++;
8345                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8346                    // No process for this uid, use it.
8347                    break;
8348                }
8349                stepsLeft--;
8350                if (stepsLeft <= 0) {
8351                    return null;
8352                }
8353            }
8354        }
8355        return new ProcessRecord(stats, info, proc, uid);
8356    }
8357
8358    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8359        ProcessRecord app;
8360        if (!isolated) {
8361            app = getProcessRecordLocked(info.processName, info.uid, true);
8362        } else {
8363            app = null;
8364        }
8365
8366        if (app == null) {
8367            app = newProcessRecordLocked(info, null, isolated);
8368            mProcessNames.put(info.processName, app.uid, app);
8369            if (isolated) {
8370                mIsolatedProcesses.put(app.uid, app);
8371            }
8372            updateLruProcessLocked(app, false, null);
8373            updateOomAdjLocked();
8374        }
8375
8376        // This package really, really can not be stopped.
8377        try {
8378            AppGlobals.getPackageManager().setPackageStoppedState(
8379                    info.packageName, false, UserHandle.getUserId(app.uid));
8380        } catch (RemoteException e) {
8381        } catch (IllegalArgumentException e) {
8382            Slog.w(TAG, "Failed trying to unstop package "
8383                    + info.packageName + ": " + e);
8384        }
8385
8386        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8387                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8388            app.persistent = true;
8389            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8390        }
8391        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8392            mPersistentStartingProcesses.add(app);
8393            startProcessLocked(app, "added application", app.processName);
8394        }
8395
8396        return app;
8397    }
8398
8399    public void unhandledBack() {
8400        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8401                "unhandledBack()");
8402
8403        synchronized(this) {
8404            final long origId = Binder.clearCallingIdentity();
8405            try {
8406                getFocusedStack().unhandledBackLocked();
8407            } finally {
8408                Binder.restoreCallingIdentity(origId);
8409            }
8410        }
8411    }
8412
8413    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8414        enforceNotIsolatedCaller("openContentUri");
8415        final int userId = UserHandle.getCallingUserId();
8416        String name = uri.getAuthority();
8417        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8418        ParcelFileDescriptor pfd = null;
8419        if (cph != null) {
8420            // We record the binder invoker's uid in thread-local storage before
8421            // going to the content provider to open the file.  Later, in the code
8422            // that handles all permissions checks, we look for this uid and use
8423            // that rather than the Activity Manager's own uid.  The effect is that
8424            // we do the check against the caller's permissions even though it looks
8425            // to the content provider like the Activity Manager itself is making
8426            // the request.
8427            sCallerIdentity.set(new Identity(
8428                    Binder.getCallingPid(), Binder.getCallingUid()));
8429            try {
8430                pfd = cph.provider.openFile(null, uri, "r", null);
8431            } catch (FileNotFoundException e) {
8432                // do nothing; pfd will be returned null
8433            } finally {
8434                // Ensure that whatever happens, we clean up the identity state
8435                sCallerIdentity.remove();
8436            }
8437
8438            // We've got the fd now, so we're done with the provider.
8439            removeContentProviderExternalUnchecked(name, null, userId);
8440        } else {
8441            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8442        }
8443        return pfd;
8444    }
8445
8446    // Actually is sleeping or shutting down or whatever else in the future
8447    // is an inactive state.
8448    public boolean isSleepingOrShuttingDown() {
8449        return mSleeping || mShuttingDown;
8450    }
8451
8452    void goingToSleep() {
8453        synchronized(this) {
8454            mWentToSleep = true;
8455            updateEventDispatchingLocked();
8456
8457            if (!mSleeping) {
8458                mSleeping = true;
8459                mStackSupervisor.goingToSleepLocked();
8460
8461                // Initialize the wake times of all processes.
8462                checkExcessivePowerUsageLocked(false);
8463                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8464                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8465                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8466            }
8467        }
8468    }
8469
8470    @Override
8471    public boolean shutdown(int timeout) {
8472        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8473                != PackageManager.PERMISSION_GRANTED) {
8474            throw new SecurityException("Requires permission "
8475                    + android.Manifest.permission.SHUTDOWN);
8476        }
8477
8478        boolean timedout = false;
8479
8480        synchronized(this) {
8481            mShuttingDown = true;
8482            updateEventDispatchingLocked();
8483            timedout = mStackSupervisor.shutdownLocked(timeout);
8484        }
8485
8486        mAppOpsService.shutdown();
8487        mUsageStatsService.shutdown();
8488        mBatteryStatsService.shutdown();
8489        synchronized (this) {
8490            mProcessStats.shutdownLocked();
8491        }
8492
8493        return timedout;
8494    }
8495
8496    public final void activitySlept(IBinder token) {
8497        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8498
8499        final long origId = Binder.clearCallingIdentity();
8500
8501        synchronized (this) {
8502            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8503            if (r != null) {
8504                mStackSupervisor.activitySleptLocked(r);
8505            }
8506        }
8507
8508        Binder.restoreCallingIdentity(origId);
8509    }
8510
8511    void logLockScreen(String msg) {
8512        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8513                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8514                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8515                mStackSupervisor.mDismissKeyguardOnNextActivity);
8516    }
8517
8518    private void comeOutOfSleepIfNeededLocked() {
8519        if (!mWentToSleep && !mLockScreenShown) {
8520            if (mSleeping) {
8521                mSleeping = false;
8522                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8523            }
8524        }
8525    }
8526
8527    void wakingUp() {
8528        synchronized(this) {
8529            mWentToSleep = false;
8530            updateEventDispatchingLocked();
8531            comeOutOfSleepIfNeededLocked();
8532        }
8533    }
8534
8535    private void updateEventDispatchingLocked() {
8536        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8537    }
8538
8539    public void setLockScreenShown(boolean shown) {
8540        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8541                != PackageManager.PERMISSION_GRANTED) {
8542            throw new SecurityException("Requires permission "
8543                    + android.Manifest.permission.DEVICE_POWER);
8544        }
8545
8546        synchronized(this) {
8547            long ident = Binder.clearCallingIdentity();
8548            try {
8549                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8550                mLockScreenShown = shown;
8551                comeOutOfSleepIfNeededLocked();
8552            } finally {
8553                Binder.restoreCallingIdentity(ident);
8554            }
8555        }
8556    }
8557
8558    public void stopAppSwitches() {
8559        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8560                != PackageManager.PERMISSION_GRANTED) {
8561            throw new SecurityException("Requires permission "
8562                    + android.Manifest.permission.STOP_APP_SWITCHES);
8563        }
8564
8565        synchronized(this) {
8566            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8567                    + APP_SWITCH_DELAY_TIME;
8568            mDidAppSwitch = false;
8569            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8570            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8571            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8572        }
8573    }
8574
8575    public void resumeAppSwitches() {
8576        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8577                != PackageManager.PERMISSION_GRANTED) {
8578            throw new SecurityException("Requires permission "
8579                    + android.Manifest.permission.STOP_APP_SWITCHES);
8580        }
8581
8582        synchronized(this) {
8583            // Note that we don't execute any pending app switches... we will
8584            // let those wait until either the timeout, or the next start
8585            // activity request.
8586            mAppSwitchesAllowedTime = 0;
8587        }
8588    }
8589
8590    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8591            String name) {
8592        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8593            return true;
8594        }
8595
8596        final int perm = checkComponentPermission(
8597                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8598                callingUid, -1, true);
8599        if (perm == PackageManager.PERMISSION_GRANTED) {
8600            return true;
8601        }
8602
8603        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8604        return false;
8605    }
8606
8607    public void setDebugApp(String packageName, boolean waitForDebugger,
8608            boolean persistent) {
8609        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8610                "setDebugApp()");
8611
8612        long ident = Binder.clearCallingIdentity();
8613        try {
8614            // Note that this is not really thread safe if there are multiple
8615            // callers into it at the same time, but that's not a situation we
8616            // care about.
8617            if (persistent) {
8618                final ContentResolver resolver = mContext.getContentResolver();
8619                Settings.Global.putString(
8620                    resolver, Settings.Global.DEBUG_APP,
8621                    packageName);
8622                Settings.Global.putInt(
8623                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8624                    waitForDebugger ? 1 : 0);
8625            }
8626
8627            synchronized (this) {
8628                if (!persistent) {
8629                    mOrigDebugApp = mDebugApp;
8630                    mOrigWaitForDebugger = mWaitForDebugger;
8631                }
8632                mDebugApp = packageName;
8633                mWaitForDebugger = waitForDebugger;
8634                mDebugTransient = !persistent;
8635                if (packageName != null) {
8636                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8637                            false, UserHandle.USER_ALL, "set debug app");
8638                }
8639            }
8640        } finally {
8641            Binder.restoreCallingIdentity(ident);
8642        }
8643    }
8644
8645    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8646        synchronized (this) {
8647            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8648            if (!isDebuggable) {
8649                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8650                    throw new SecurityException("Process not debuggable: " + app.packageName);
8651                }
8652            }
8653
8654            mOpenGlTraceApp = processName;
8655        }
8656    }
8657
8658    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8659            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8660        synchronized (this) {
8661            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8662            if (!isDebuggable) {
8663                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8664                    throw new SecurityException("Process not debuggable: " + app.packageName);
8665                }
8666            }
8667            mProfileApp = processName;
8668            mProfileFile = profileFile;
8669            if (mProfileFd != null) {
8670                try {
8671                    mProfileFd.close();
8672                } catch (IOException e) {
8673                }
8674                mProfileFd = null;
8675            }
8676            mProfileFd = profileFd;
8677            mProfileType = 0;
8678            mAutoStopProfiler = autoStopProfiler;
8679        }
8680    }
8681
8682    @Override
8683    public void setAlwaysFinish(boolean enabled) {
8684        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8685                "setAlwaysFinish()");
8686
8687        Settings.Global.putInt(
8688                mContext.getContentResolver(),
8689                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8690
8691        synchronized (this) {
8692            mAlwaysFinishActivities = enabled;
8693        }
8694    }
8695
8696    @Override
8697    public void setActivityController(IActivityController controller) {
8698        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8699                "setActivityController()");
8700        synchronized (this) {
8701            mController = controller;
8702            Watchdog.getInstance().setActivityController(controller);
8703        }
8704    }
8705
8706    @Override
8707    public void setUserIsMonkey(boolean userIsMonkey) {
8708        synchronized (this) {
8709            synchronized (mPidsSelfLocked) {
8710                final int callingPid = Binder.getCallingPid();
8711                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8712                if (precessRecord == null) {
8713                    throw new SecurityException("Unknown process: " + callingPid);
8714                }
8715                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8716                    throw new SecurityException("Only an instrumentation process "
8717                            + "with a UiAutomation can call setUserIsMonkey");
8718                }
8719            }
8720            mUserIsMonkey = userIsMonkey;
8721        }
8722    }
8723
8724    @Override
8725    public boolean isUserAMonkey() {
8726        synchronized (this) {
8727            // If there is a controller also implies the user is a monkey.
8728            return (mUserIsMonkey || mController != null);
8729        }
8730    }
8731
8732    public void requestBugReport() {
8733        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8734        SystemProperties.set("ctl.start", "bugreport");
8735    }
8736
8737    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8738        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8739    }
8740
8741    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8742        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8743            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8744        }
8745        return KEY_DISPATCHING_TIMEOUT;
8746    }
8747
8748    @Override
8749    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8750        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8751                != PackageManager.PERMISSION_GRANTED) {
8752            throw new SecurityException("Requires permission "
8753                    + android.Manifest.permission.FILTER_EVENTS);
8754        }
8755        ProcessRecord proc;
8756        long timeout;
8757        synchronized (this) {
8758            synchronized (mPidsSelfLocked) {
8759                proc = mPidsSelfLocked.get(pid);
8760            }
8761            timeout = getInputDispatchingTimeoutLocked(proc);
8762        }
8763
8764        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8765            return -1;
8766        }
8767
8768        return timeout;
8769    }
8770
8771    /**
8772     * Handle input dispatching timeouts.
8773     * Returns whether input dispatching should be aborted or not.
8774     */
8775    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8776            final ActivityRecord activity, final ActivityRecord parent,
8777            final boolean aboveSystem, String reason) {
8778        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8779                != PackageManager.PERMISSION_GRANTED) {
8780            throw new SecurityException("Requires permission "
8781                    + android.Manifest.permission.FILTER_EVENTS);
8782        }
8783
8784        final String annotation;
8785        if (reason == null) {
8786            annotation = "Input dispatching timed out";
8787        } else {
8788            annotation = "Input dispatching timed out (" + reason + ")";
8789        }
8790
8791        if (proc != null) {
8792            synchronized (this) {
8793                if (proc.debugging) {
8794                    return false;
8795                }
8796
8797                if (mDidDexOpt) {
8798                    // Give more time since we were dexopting.
8799                    mDidDexOpt = false;
8800                    return false;
8801                }
8802
8803                if (proc.instrumentationClass != null) {
8804                    Bundle info = new Bundle();
8805                    info.putString("shortMsg", "keyDispatchingTimedOut");
8806                    info.putString("longMsg", annotation);
8807                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8808                    return true;
8809                }
8810            }
8811            mHandler.post(new Runnable() {
8812                @Override
8813                public void run() {
8814                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8815                }
8816            });
8817        }
8818
8819        return true;
8820    }
8821
8822    public Bundle getAssistContextExtras(int requestType) {
8823        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8824                "getAssistContextExtras()");
8825        PendingAssistExtras pae;
8826        Bundle extras = new Bundle();
8827        synchronized (this) {
8828            ActivityRecord activity = getFocusedStack().mResumedActivity;
8829            if (activity == null) {
8830                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8831                return null;
8832            }
8833            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8834            if (activity.app == null || activity.app.thread == null) {
8835                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8836                return extras;
8837            }
8838            if (activity.app.pid == Binder.getCallingPid()) {
8839                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8840                return extras;
8841            }
8842            pae = new PendingAssistExtras(activity);
8843            try {
8844                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8845                        requestType);
8846                mPendingAssistExtras.add(pae);
8847                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8848            } catch (RemoteException e) {
8849                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8850                return extras;
8851            }
8852        }
8853        synchronized (pae) {
8854            while (!pae.haveResult) {
8855                try {
8856                    pae.wait();
8857                } catch (InterruptedException e) {
8858                }
8859            }
8860            if (pae.result != null) {
8861                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8862            }
8863        }
8864        synchronized (this) {
8865            mPendingAssistExtras.remove(pae);
8866            mHandler.removeCallbacks(pae);
8867        }
8868        return extras;
8869    }
8870
8871    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8872        PendingAssistExtras pae = (PendingAssistExtras)token;
8873        synchronized (pae) {
8874            pae.result = extras;
8875            pae.haveResult = true;
8876            pae.notifyAll();
8877        }
8878    }
8879
8880    public void registerProcessObserver(IProcessObserver observer) {
8881        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8882                "registerProcessObserver()");
8883        synchronized (this) {
8884            mProcessObservers.register(observer);
8885        }
8886    }
8887
8888    @Override
8889    public void unregisterProcessObserver(IProcessObserver observer) {
8890        synchronized (this) {
8891            mProcessObservers.unregister(observer);
8892        }
8893    }
8894
8895    @Override
8896    public boolean convertFromTranslucent(IBinder token) {
8897        final long origId = Binder.clearCallingIdentity();
8898        try {
8899            synchronized (this) {
8900                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8901                if (r == null) {
8902                    return false;
8903                }
8904                if (r.changeWindowTranslucency(true)) {
8905                    mWindowManager.setAppFullscreen(token, true);
8906                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8907                    return true;
8908                }
8909                return false;
8910            }
8911        } finally {
8912            Binder.restoreCallingIdentity(origId);
8913        }
8914    }
8915
8916    @Override
8917    public boolean convertToTranslucent(IBinder token) {
8918        final long origId = Binder.clearCallingIdentity();
8919        try {
8920            synchronized (this) {
8921                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8922                if (r == null) {
8923                    return false;
8924                }
8925                if (r.changeWindowTranslucency(false)) {
8926                    r.task.stack.convertToTranslucent(r);
8927                    mWindowManager.setAppFullscreen(token, false);
8928                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8929                    return true;
8930                }
8931                return false;
8932            }
8933        } finally {
8934            Binder.restoreCallingIdentity(origId);
8935        }
8936    }
8937
8938    @Override
8939    public void setImmersive(IBinder token, boolean immersive) {
8940        synchronized(this) {
8941            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8942            if (r == null) {
8943                throw new IllegalArgumentException();
8944            }
8945            r.immersive = immersive;
8946
8947            // update associated state if we're frontmost
8948            if (r == mFocusedActivity) {
8949                if (DEBUG_IMMERSIVE) {
8950                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8951                }
8952                applyUpdateLockStateLocked(r);
8953            }
8954        }
8955    }
8956
8957    @Override
8958    public boolean isImmersive(IBinder token) {
8959        synchronized (this) {
8960            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8961            if (r == null) {
8962                throw new IllegalArgumentException();
8963            }
8964            return r.immersive;
8965        }
8966    }
8967
8968    public boolean isTopActivityImmersive() {
8969        enforceNotIsolatedCaller("startActivity");
8970        synchronized (this) {
8971            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8972            return (r != null) ? r.immersive : false;
8973        }
8974    }
8975
8976    public final void enterSafeMode() {
8977        synchronized(this) {
8978            // It only makes sense to do this before the system is ready
8979            // and started launching other packages.
8980            if (!mSystemReady) {
8981                try {
8982                    AppGlobals.getPackageManager().enterSafeMode();
8983                } catch (RemoteException e) {
8984                }
8985            }
8986
8987            mSafeMode = true;
8988        }
8989    }
8990
8991    public final void showSafeModeOverlay() {
8992        View v = LayoutInflater.from(mContext).inflate(
8993                com.android.internal.R.layout.safe_mode, null);
8994        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8995        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8996        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8997        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8998        lp.gravity = Gravity.BOTTOM | Gravity.START;
8999        lp.format = v.getBackground().getOpacity();
9000        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9001                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9002        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9003        ((WindowManager)mContext.getSystemService(
9004                Context.WINDOW_SERVICE)).addView(v, lp);
9005    }
9006
9007    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9008        if (!(sender instanceof PendingIntentRecord)) {
9009            return;
9010        }
9011        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9012        synchronized (stats) {
9013            if (mBatteryStatsService.isOnBattery()) {
9014                mBatteryStatsService.enforceCallingPermission();
9015                PendingIntentRecord rec = (PendingIntentRecord)sender;
9016                int MY_UID = Binder.getCallingUid();
9017                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9018                BatteryStatsImpl.Uid.Pkg pkg =
9019                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9020                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9021                pkg.incWakeupsLocked();
9022            }
9023        }
9024    }
9025
9026    public boolean killPids(int[] pids, String pReason, boolean secure) {
9027        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9028            throw new SecurityException("killPids only available to the system");
9029        }
9030        String reason = (pReason == null) ? "Unknown" : pReason;
9031        // XXX Note: don't acquire main activity lock here, because the window
9032        // manager calls in with its locks held.
9033
9034        boolean killed = false;
9035        synchronized (mPidsSelfLocked) {
9036            int[] types = new int[pids.length];
9037            int worstType = 0;
9038            for (int i=0; i<pids.length; i++) {
9039                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9040                if (proc != null) {
9041                    int type = proc.setAdj;
9042                    types[i] = type;
9043                    if (type > worstType) {
9044                        worstType = type;
9045                    }
9046                }
9047            }
9048
9049            // If the worst oom_adj is somewhere in the cached proc LRU range,
9050            // then constrain it so we will kill all cached procs.
9051            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9052                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9053                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9054            }
9055
9056            // If this is not a secure call, don't let it kill processes that
9057            // are important.
9058            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9059                worstType = ProcessList.SERVICE_ADJ;
9060            }
9061
9062            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9063            for (int i=0; i<pids.length; i++) {
9064                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9065                if (proc == null) {
9066                    continue;
9067                }
9068                int adj = proc.setAdj;
9069                if (adj >= worstType && !proc.killedByAm) {
9070                    killUnneededProcessLocked(proc, reason);
9071                    killed = true;
9072                }
9073            }
9074        }
9075        return killed;
9076    }
9077
9078    @Override
9079    public void killUid(int uid, String reason) {
9080        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9081            throw new SecurityException("killUid only available to the system");
9082        }
9083        synchronized (this) {
9084            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9085                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9086                    reason != null ? reason : "kill uid");
9087        }
9088    }
9089
9090    @Override
9091    public boolean killProcessesBelowForeground(String reason) {
9092        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9093            throw new SecurityException("killProcessesBelowForeground() only available to system");
9094        }
9095
9096        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9097    }
9098
9099    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9100        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9101            throw new SecurityException("killProcessesBelowAdj() only available to system");
9102        }
9103
9104        boolean killed = false;
9105        synchronized (mPidsSelfLocked) {
9106            final int size = mPidsSelfLocked.size();
9107            for (int i = 0; i < size; i++) {
9108                final int pid = mPidsSelfLocked.keyAt(i);
9109                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9110                if (proc == null) continue;
9111
9112                final int adj = proc.setAdj;
9113                if (adj > belowAdj && !proc.killedByAm) {
9114                    killUnneededProcessLocked(proc, reason);
9115                    killed = true;
9116                }
9117            }
9118        }
9119        return killed;
9120    }
9121
9122    @Override
9123    public void hang(final IBinder who, boolean allowRestart) {
9124        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9125                != PackageManager.PERMISSION_GRANTED) {
9126            throw new SecurityException("Requires permission "
9127                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9128        }
9129
9130        final IBinder.DeathRecipient death = new DeathRecipient() {
9131            @Override
9132            public void binderDied() {
9133                synchronized (this) {
9134                    notifyAll();
9135                }
9136            }
9137        };
9138
9139        try {
9140            who.linkToDeath(death, 0);
9141        } catch (RemoteException e) {
9142            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9143            return;
9144        }
9145
9146        synchronized (this) {
9147            Watchdog.getInstance().setAllowRestart(allowRestart);
9148            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9149            synchronized (death) {
9150                while (who.isBinderAlive()) {
9151                    try {
9152                        death.wait();
9153                    } catch (InterruptedException e) {
9154                    }
9155                }
9156            }
9157            Watchdog.getInstance().setAllowRestart(true);
9158        }
9159    }
9160
9161    @Override
9162    public void restart() {
9163        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9164                != PackageManager.PERMISSION_GRANTED) {
9165            throw new SecurityException("Requires permission "
9166                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9167        }
9168
9169        Log.i(TAG, "Sending shutdown broadcast...");
9170
9171        BroadcastReceiver br = new BroadcastReceiver() {
9172            @Override public void onReceive(Context context, Intent intent) {
9173                // Now the broadcast is done, finish up the low-level shutdown.
9174                Log.i(TAG, "Shutting down activity manager...");
9175                shutdown(10000);
9176                Log.i(TAG, "Shutdown complete, restarting!");
9177                Process.killProcess(Process.myPid());
9178                System.exit(10);
9179            }
9180        };
9181
9182        // First send the high-level shut down broadcast.
9183        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9184        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9185        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9186        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9187        mContext.sendOrderedBroadcastAsUser(intent,
9188                UserHandle.ALL, null, br, mHandler, 0, null, null);
9189        */
9190        br.onReceive(mContext, intent);
9191    }
9192
9193    private long getLowRamTimeSinceIdle(long now) {
9194        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9195    }
9196
9197    @Override
9198    public void performIdleMaintenance() {
9199        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9200                != PackageManager.PERMISSION_GRANTED) {
9201            throw new SecurityException("Requires permission "
9202                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9203        }
9204
9205        synchronized (this) {
9206            final long now = SystemClock.uptimeMillis();
9207            final long timeSinceLastIdle = now - mLastIdleTime;
9208            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9209            mLastIdleTime = now;
9210            mLowRamTimeSinceLastIdle = 0;
9211            if (mLowRamStartTime != 0) {
9212                mLowRamStartTime = now;
9213            }
9214
9215            StringBuilder sb = new StringBuilder(128);
9216            sb.append("Idle maintenance over ");
9217            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9218            sb.append(" low RAM for ");
9219            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9220            Slog.i(TAG, sb.toString());
9221
9222            // If at least 1/3 of our time since the last idle period has been spent
9223            // with RAM low, then we want to kill processes.
9224            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9225
9226            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9227                ProcessRecord proc = mLruProcesses.get(i);
9228                if (proc.notCachedSinceIdle) {
9229                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9230                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9231                        if (doKilling && proc.initialIdlePss != 0
9232                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9233                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9234                                    + " from " + proc.initialIdlePss + ")");
9235                        }
9236                    }
9237                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9238                    proc.notCachedSinceIdle = true;
9239                    proc.initialIdlePss = 0;
9240                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9241                            mSleeping, now);
9242                }
9243            }
9244
9245            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9246            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9247        }
9248    }
9249
9250    private void retrieveSettings() {
9251        final ContentResolver resolver = mContext.getContentResolver();
9252        String debugApp = Settings.Global.getString(
9253            resolver, Settings.Global.DEBUG_APP);
9254        boolean waitForDebugger = Settings.Global.getInt(
9255            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9256        boolean alwaysFinishActivities = Settings.Global.getInt(
9257            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9258        boolean forceRtl = Settings.Global.getInt(
9259                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9260        // Transfer any global setting for forcing RTL layout, into a System Property
9261        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9262
9263        Configuration configuration = new Configuration();
9264        Settings.System.getConfiguration(resolver, configuration);
9265        if (forceRtl) {
9266            // This will take care of setting the correct layout direction flags
9267            configuration.setLayoutDirection(configuration.locale);
9268        }
9269
9270        synchronized (this) {
9271            mDebugApp = mOrigDebugApp = debugApp;
9272            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9273            mAlwaysFinishActivities = alwaysFinishActivities;
9274            // This happens before any activities are started, so we can
9275            // change mConfiguration in-place.
9276            updateConfigurationLocked(configuration, null, false, true);
9277            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9278        }
9279    }
9280
9281    public boolean testIsSystemReady() {
9282        // no need to synchronize(this) just to read & return the value
9283        return mSystemReady;
9284    }
9285
9286    private static File getCalledPreBootReceiversFile() {
9287        File dataDir = Environment.getDataDirectory();
9288        File systemDir = new File(dataDir, "system");
9289        File fname = new File(systemDir, "called_pre_boots.dat");
9290        return fname;
9291    }
9292
9293    static final int LAST_DONE_VERSION = 10000;
9294
9295    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9296        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9297        File file = getCalledPreBootReceiversFile();
9298        FileInputStream fis = null;
9299        try {
9300            fis = new FileInputStream(file);
9301            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9302            int fvers = dis.readInt();
9303            if (fvers == LAST_DONE_VERSION) {
9304                String vers = dis.readUTF();
9305                String codename = dis.readUTF();
9306                String build = dis.readUTF();
9307                if (android.os.Build.VERSION.RELEASE.equals(vers)
9308                        && android.os.Build.VERSION.CODENAME.equals(codename)
9309                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9310                    int num = dis.readInt();
9311                    while (num > 0) {
9312                        num--;
9313                        String pkg = dis.readUTF();
9314                        String cls = dis.readUTF();
9315                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9316                    }
9317                }
9318            }
9319        } catch (FileNotFoundException e) {
9320        } catch (IOException e) {
9321            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9322        } finally {
9323            if (fis != null) {
9324                try {
9325                    fis.close();
9326                } catch (IOException e) {
9327                }
9328            }
9329        }
9330        return lastDoneReceivers;
9331    }
9332
9333    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9334        File file = getCalledPreBootReceiversFile();
9335        FileOutputStream fos = null;
9336        DataOutputStream dos = null;
9337        try {
9338            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9339            fos = new FileOutputStream(file);
9340            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9341            dos.writeInt(LAST_DONE_VERSION);
9342            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9343            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9344            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9345            dos.writeInt(list.size());
9346            for (int i=0; i<list.size(); i++) {
9347                dos.writeUTF(list.get(i).getPackageName());
9348                dos.writeUTF(list.get(i).getClassName());
9349            }
9350        } catch (IOException e) {
9351            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9352            file.delete();
9353        } finally {
9354            FileUtils.sync(fos);
9355            if (dos != null) {
9356                try {
9357                    dos.close();
9358                } catch (IOException e) {
9359                    // TODO Auto-generated catch block
9360                    e.printStackTrace();
9361                }
9362            }
9363        }
9364    }
9365
9366    public void systemReady(final Runnable goingCallback) {
9367        synchronized(this) {
9368            if (mSystemReady) {
9369                if (goingCallback != null) goingCallback.run();
9370                return;
9371            }
9372
9373            // Check to see if there are any update receivers to run.
9374            if (!mDidUpdate) {
9375                if (mWaitingUpdate) {
9376                    return;
9377                }
9378                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9379                List<ResolveInfo> ris = null;
9380                try {
9381                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9382                            intent, null, 0, 0);
9383                } catch (RemoteException e) {
9384                }
9385                if (ris != null) {
9386                    for (int i=ris.size()-1; i>=0; i--) {
9387                        if ((ris.get(i).activityInfo.applicationInfo.flags
9388                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9389                            ris.remove(i);
9390                        }
9391                    }
9392                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9393
9394                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9395
9396                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9397                    for (int i=0; i<ris.size(); i++) {
9398                        ActivityInfo ai = ris.get(i).activityInfo;
9399                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9400                        if (lastDoneReceivers.contains(comp)) {
9401                            // We already did the pre boot receiver for this app with the current
9402                            // platform version, so don't do it again...
9403                            ris.remove(i);
9404                            i--;
9405                            // ...however, do keep it as one that has been done, so we don't
9406                            // forget about it when rewriting the file of last done receivers.
9407                            doneReceivers.add(comp);
9408                        }
9409                    }
9410
9411                    final int[] users = getUsersLocked();
9412                    for (int i=0; i<ris.size(); i++) {
9413                        ActivityInfo ai = ris.get(i).activityInfo;
9414                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9415                        doneReceivers.add(comp);
9416                        intent.setComponent(comp);
9417                        for (int j=0; j<users.length; j++) {
9418                            IIntentReceiver finisher = null;
9419                            if (i == ris.size()-1 && j == users.length-1) {
9420                                finisher = new IIntentReceiver.Stub() {
9421                                    public void performReceive(Intent intent, int resultCode,
9422                                            String data, Bundle extras, boolean ordered,
9423                                            boolean sticky, int sendingUser) {
9424                                        // The raw IIntentReceiver interface is called
9425                                        // with the AM lock held, so redispatch to
9426                                        // execute our code without the lock.
9427                                        mHandler.post(new Runnable() {
9428                                            public void run() {
9429                                                synchronized (ActivityManagerService.this) {
9430                                                    mDidUpdate = true;
9431                                                }
9432                                                writeLastDonePreBootReceivers(doneReceivers);
9433                                                showBootMessage(mContext.getText(
9434                                                        R.string.android_upgrading_complete),
9435                                                        false);
9436                                                systemReady(goingCallback);
9437                                            }
9438                                        });
9439                                    }
9440                                };
9441                            }
9442                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9443                                    + " for user " + users[j]);
9444                            broadcastIntentLocked(null, null, intent, null, finisher,
9445                                    0, null, null, null, AppOpsManager.OP_NONE,
9446                                    true, false, MY_PID, Process.SYSTEM_UID,
9447                                    users[j]);
9448                            if (finisher != null) {
9449                                mWaitingUpdate = true;
9450                            }
9451                        }
9452                    }
9453                }
9454                if (mWaitingUpdate) {
9455                    return;
9456                }
9457                mDidUpdate = true;
9458            }
9459
9460            mAppOpsService.systemReady();
9461            mSystemReady = true;
9462        }
9463
9464        ArrayList<ProcessRecord> procsToKill = null;
9465        synchronized(mPidsSelfLocked) {
9466            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9467                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9468                if (!isAllowedWhileBooting(proc.info)){
9469                    if (procsToKill == null) {
9470                        procsToKill = new ArrayList<ProcessRecord>();
9471                    }
9472                    procsToKill.add(proc);
9473                }
9474            }
9475        }
9476
9477        synchronized(this) {
9478            if (procsToKill != null) {
9479                for (int i=procsToKill.size()-1; i>=0; i--) {
9480                    ProcessRecord proc = procsToKill.get(i);
9481                    Slog.i(TAG, "Removing system update proc: " + proc);
9482                    removeProcessLocked(proc, true, false, "system update done");
9483                }
9484            }
9485
9486            // Now that we have cleaned up any update processes, we
9487            // are ready to start launching real processes and know that
9488            // we won't trample on them any more.
9489            mProcessesReady = true;
9490        }
9491
9492        Slog.i(TAG, "System now ready");
9493        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9494            SystemClock.uptimeMillis());
9495
9496        synchronized(this) {
9497            // Make sure we have no pre-ready processes sitting around.
9498
9499            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9500                ResolveInfo ri = mContext.getPackageManager()
9501                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9502                                STOCK_PM_FLAGS);
9503                CharSequence errorMsg = null;
9504                if (ri != null) {
9505                    ActivityInfo ai = ri.activityInfo;
9506                    ApplicationInfo app = ai.applicationInfo;
9507                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9508                        mTopAction = Intent.ACTION_FACTORY_TEST;
9509                        mTopData = null;
9510                        mTopComponent = new ComponentName(app.packageName,
9511                                ai.name);
9512                    } else {
9513                        errorMsg = mContext.getResources().getText(
9514                                com.android.internal.R.string.factorytest_not_system);
9515                    }
9516                } else {
9517                    errorMsg = mContext.getResources().getText(
9518                            com.android.internal.R.string.factorytest_no_action);
9519                }
9520                if (errorMsg != null) {
9521                    mTopAction = null;
9522                    mTopData = null;
9523                    mTopComponent = null;
9524                    Message msg = Message.obtain();
9525                    msg.what = SHOW_FACTORY_ERROR_MSG;
9526                    msg.getData().putCharSequence("msg", errorMsg);
9527                    mHandler.sendMessage(msg);
9528                }
9529            }
9530        }
9531
9532        retrieveSettings();
9533
9534        synchronized (this) {
9535            readGrantedUriPermissionsLocked();
9536        }
9537
9538        if (goingCallback != null) goingCallback.run();
9539
9540        synchronized (this) {
9541            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9542                try {
9543                    List apps = AppGlobals.getPackageManager().
9544                        getPersistentApplications(STOCK_PM_FLAGS);
9545                    if (apps != null) {
9546                        int N = apps.size();
9547                        int i;
9548                        for (i=0; i<N; i++) {
9549                            ApplicationInfo info
9550                                = (ApplicationInfo)apps.get(i);
9551                            if (info != null &&
9552                                    !info.packageName.equals("android")) {
9553                                addAppLocked(info, false);
9554                            }
9555                        }
9556                    }
9557                } catch (RemoteException ex) {
9558                    // pm is in same process, this will never happen.
9559                }
9560            }
9561
9562            // Start up initial activity.
9563            mBooting = true;
9564
9565            try {
9566                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9567                    Message msg = Message.obtain();
9568                    msg.what = SHOW_UID_ERROR_MSG;
9569                    mHandler.sendMessage(msg);
9570                }
9571            } catch (RemoteException e) {
9572            }
9573
9574            long ident = Binder.clearCallingIdentity();
9575            try {
9576                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9577                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9578                        | Intent.FLAG_RECEIVER_FOREGROUND);
9579                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9580                broadcastIntentLocked(null, null, intent,
9581                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9582                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9583                intent = new Intent(Intent.ACTION_USER_STARTING);
9584                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9585                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9586                broadcastIntentLocked(null, null, intent,
9587                        null, new IIntentReceiver.Stub() {
9588                            @Override
9589                            public void performReceive(Intent intent, int resultCode, String data,
9590                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9591                                    throws RemoteException {
9592                            }
9593                        }, 0, null, null,
9594                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9595                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9596            } finally {
9597                Binder.restoreCallingIdentity(ident);
9598            }
9599            mStackSupervisor.resumeTopActivitiesLocked();
9600            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9601        }
9602    }
9603
9604    private boolean makeAppCrashingLocked(ProcessRecord app,
9605            String shortMsg, String longMsg, String stackTrace) {
9606        app.crashing = true;
9607        app.crashingReport = generateProcessError(app,
9608                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9609        startAppProblemLocked(app);
9610        app.stopFreezingAllLocked();
9611        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9612    }
9613
9614    private void makeAppNotRespondingLocked(ProcessRecord app,
9615            String activity, String shortMsg, String longMsg) {
9616        app.notResponding = true;
9617        app.notRespondingReport = generateProcessError(app,
9618                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9619                activity, shortMsg, longMsg, null);
9620        startAppProblemLocked(app);
9621        app.stopFreezingAllLocked();
9622    }
9623
9624    /**
9625     * Generate a process error record, suitable for attachment to a ProcessRecord.
9626     *
9627     * @param app The ProcessRecord in which the error occurred.
9628     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9629     *                      ActivityManager.AppErrorStateInfo
9630     * @param activity The activity associated with the crash, if known.
9631     * @param shortMsg Short message describing the crash.
9632     * @param longMsg Long message describing the crash.
9633     * @param stackTrace Full crash stack trace, may be null.
9634     *
9635     * @return Returns a fully-formed AppErrorStateInfo record.
9636     */
9637    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9638            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9639        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9640
9641        report.condition = condition;
9642        report.processName = app.processName;
9643        report.pid = app.pid;
9644        report.uid = app.info.uid;
9645        report.tag = activity;
9646        report.shortMsg = shortMsg;
9647        report.longMsg = longMsg;
9648        report.stackTrace = stackTrace;
9649
9650        return report;
9651    }
9652
9653    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9654        synchronized (this) {
9655            app.crashing = false;
9656            app.crashingReport = null;
9657            app.notResponding = false;
9658            app.notRespondingReport = null;
9659            if (app.anrDialog == fromDialog) {
9660                app.anrDialog = null;
9661            }
9662            if (app.waitDialog == fromDialog) {
9663                app.waitDialog = null;
9664            }
9665            if (app.pid > 0 && app.pid != MY_PID) {
9666                handleAppCrashLocked(app, null, null, null);
9667                killUnneededProcessLocked(app, "user request after error");
9668            }
9669        }
9670    }
9671
9672    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9673            String stackTrace) {
9674        long now = SystemClock.uptimeMillis();
9675
9676        Long crashTime;
9677        if (!app.isolated) {
9678            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9679        } else {
9680            crashTime = null;
9681        }
9682        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9683            // This process loses!
9684            Slog.w(TAG, "Process " + app.info.processName
9685                    + " has crashed too many times: killing!");
9686            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9687                    app.userId, app.info.processName, app.uid);
9688            mStackSupervisor.handleAppCrashLocked(app);
9689            if (!app.persistent) {
9690                // We don't want to start this process again until the user
9691                // explicitly does so...  but for persistent process, we really
9692                // need to keep it running.  If a persistent process is actually
9693                // repeatedly crashing, then badness for everyone.
9694                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9695                        app.info.processName);
9696                if (!app.isolated) {
9697                    // XXX We don't have a way to mark isolated processes
9698                    // as bad, since they don't have a peristent identity.
9699                    mBadProcesses.put(app.info.processName, app.uid,
9700                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9701                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9702                }
9703                app.bad = true;
9704                app.removed = true;
9705                // Don't let services in this process be restarted and potentially
9706                // annoy the user repeatedly.  Unless it is persistent, since those
9707                // processes run critical code.
9708                removeProcessLocked(app, false, false, "crash");
9709                mStackSupervisor.resumeTopActivitiesLocked();
9710                return false;
9711            }
9712            mStackSupervisor.resumeTopActivitiesLocked();
9713        } else {
9714            mStackSupervisor.finishTopRunningActivityLocked(app);
9715        }
9716
9717        // Bump up the crash count of any services currently running in the proc.
9718        for (int i=app.services.size()-1; i>=0; i--) {
9719            // Any services running in the application need to be placed
9720            // back in the pending list.
9721            ServiceRecord sr = app.services.valueAt(i);
9722            sr.crashCount++;
9723        }
9724
9725        // If the crashing process is what we consider to be the "home process" and it has been
9726        // replaced by a third-party app, clear the package preferred activities from packages
9727        // with a home activity running in the process to prevent a repeatedly crashing app
9728        // from blocking the user to manually clear the list.
9729        final ArrayList<ActivityRecord> activities = app.activities;
9730        if (app == mHomeProcess && activities.size() > 0
9731                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9732            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9733                final ActivityRecord r = activities.get(activityNdx);
9734                if (r.isHomeActivity()) {
9735                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9736                    try {
9737                        ActivityThread.getPackageManager()
9738                                .clearPackagePreferredActivities(r.packageName);
9739                    } catch (RemoteException c) {
9740                        // pm is in same process, this will never happen.
9741                    }
9742                }
9743            }
9744        }
9745
9746        if (!app.isolated) {
9747            // XXX Can't keep track of crash times for isolated processes,
9748            // because they don't have a perisistent identity.
9749            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9750        }
9751
9752        return true;
9753    }
9754
9755    void startAppProblemLocked(ProcessRecord app) {
9756        if (app.userId == mCurrentUserId) {
9757            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9758                    mContext, app.info.packageName, app.info.flags);
9759        } else {
9760            // If this app is not running under the current user, then we
9761            // can't give it a report button because that would require
9762            // launching the report UI under a different user.
9763            app.errorReportReceiver = null;
9764        }
9765        skipCurrentReceiverLocked(app);
9766    }
9767
9768    void skipCurrentReceiverLocked(ProcessRecord app) {
9769        for (BroadcastQueue queue : mBroadcastQueues) {
9770            queue.skipCurrentReceiverLocked(app);
9771        }
9772    }
9773
9774    /**
9775     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9776     * The application process will exit immediately after this call returns.
9777     * @param app object of the crashing app, null for the system server
9778     * @param crashInfo describing the exception
9779     */
9780    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9781        ProcessRecord r = findAppProcess(app, "Crash");
9782        final String processName = app == null ? "system_server"
9783                : (r == null ? "unknown" : r.processName);
9784
9785        handleApplicationCrashInner("crash", r, processName, crashInfo);
9786    }
9787
9788    /* Native crash reporting uses this inner version because it needs to be somewhat
9789     * decoupled from the AM-managed cleanup lifecycle
9790     */
9791    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9792            ApplicationErrorReport.CrashInfo crashInfo) {
9793        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9794                UserHandle.getUserId(Binder.getCallingUid()), processName,
9795                r == null ? -1 : r.info.flags,
9796                crashInfo.exceptionClassName,
9797                crashInfo.exceptionMessage,
9798                crashInfo.throwFileName,
9799                crashInfo.throwLineNumber);
9800
9801        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9802
9803        crashApplication(r, crashInfo);
9804    }
9805
9806    public void handleApplicationStrictModeViolation(
9807            IBinder app,
9808            int violationMask,
9809            StrictMode.ViolationInfo info) {
9810        ProcessRecord r = findAppProcess(app, "StrictMode");
9811        if (r == null) {
9812            return;
9813        }
9814
9815        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9816            Integer stackFingerprint = info.hashCode();
9817            boolean logIt = true;
9818            synchronized (mAlreadyLoggedViolatedStacks) {
9819                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9820                    logIt = false;
9821                    // TODO: sub-sample into EventLog for these, with
9822                    // the info.durationMillis?  Then we'd get
9823                    // the relative pain numbers, without logging all
9824                    // the stack traces repeatedly.  We'd want to do
9825                    // likewise in the client code, which also does
9826                    // dup suppression, before the Binder call.
9827                } else {
9828                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9829                        mAlreadyLoggedViolatedStacks.clear();
9830                    }
9831                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9832                }
9833            }
9834            if (logIt) {
9835                logStrictModeViolationToDropBox(r, info);
9836            }
9837        }
9838
9839        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9840            AppErrorResult result = new AppErrorResult();
9841            synchronized (this) {
9842                final long origId = Binder.clearCallingIdentity();
9843
9844                Message msg = Message.obtain();
9845                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9846                HashMap<String, Object> data = new HashMap<String, Object>();
9847                data.put("result", result);
9848                data.put("app", r);
9849                data.put("violationMask", violationMask);
9850                data.put("info", info);
9851                msg.obj = data;
9852                mHandler.sendMessage(msg);
9853
9854                Binder.restoreCallingIdentity(origId);
9855            }
9856            int res = result.get();
9857            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9858        }
9859    }
9860
9861    // Depending on the policy in effect, there could be a bunch of
9862    // these in quick succession so we try to batch these together to
9863    // minimize disk writes, number of dropbox entries, and maximize
9864    // compression, by having more fewer, larger records.
9865    private void logStrictModeViolationToDropBox(
9866            ProcessRecord process,
9867            StrictMode.ViolationInfo info) {
9868        if (info == null) {
9869            return;
9870        }
9871        final boolean isSystemApp = process == null ||
9872                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9873                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9874        final String processName = process == null ? "unknown" : process.processName;
9875        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9876        final DropBoxManager dbox = (DropBoxManager)
9877                mContext.getSystemService(Context.DROPBOX_SERVICE);
9878
9879        // Exit early if the dropbox isn't configured to accept this report type.
9880        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9881
9882        boolean bufferWasEmpty;
9883        boolean needsFlush;
9884        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9885        synchronized (sb) {
9886            bufferWasEmpty = sb.length() == 0;
9887            appendDropBoxProcessHeaders(process, processName, sb);
9888            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9889            sb.append("System-App: ").append(isSystemApp).append("\n");
9890            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9891            if (info.violationNumThisLoop != 0) {
9892                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9893            }
9894            if (info.numAnimationsRunning != 0) {
9895                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9896            }
9897            if (info.broadcastIntentAction != null) {
9898                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9899            }
9900            if (info.durationMillis != -1) {
9901                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9902            }
9903            if (info.numInstances != -1) {
9904                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9905            }
9906            if (info.tags != null) {
9907                for (String tag : info.tags) {
9908                    sb.append("Span-Tag: ").append(tag).append("\n");
9909                }
9910            }
9911            sb.append("\n");
9912            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9913                sb.append(info.crashInfo.stackTrace);
9914            }
9915            sb.append("\n");
9916
9917            // Only buffer up to ~64k.  Various logging bits truncate
9918            // things at 128k.
9919            needsFlush = (sb.length() > 64 * 1024);
9920        }
9921
9922        // Flush immediately if the buffer's grown too large, or this
9923        // is a non-system app.  Non-system apps are isolated with a
9924        // different tag & policy and not batched.
9925        //
9926        // Batching is useful during internal testing with
9927        // StrictMode settings turned up high.  Without batching,
9928        // thousands of separate files could be created on boot.
9929        if (!isSystemApp || needsFlush) {
9930            new Thread("Error dump: " + dropboxTag) {
9931                @Override
9932                public void run() {
9933                    String report;
9934                    synchronized (sb) {
9935                        report = sb.toString();
9936                        sb.delete(0, sb.length());
9937                        sb.trimToSize();
9938                    }
9939                    if (report.length() != 0) {
9940                        dbox.addText(dropboxTag, report);
9941                    }
9942                }
9943            }.start();
9944            return;
9945        }
9946
9947        // System app batching:
9948        if (!bufferWasEmpty) {
9949            // An existing dropbox-writing thread is outstanding, so
9950            // we don't need to start it up.  The existing thread will
9951            // catch the buffer appends we just did.
9952            return;
9953        }
9954
9955        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9956        // (After this point, we shouldn't access AMS internal data structures.)
9957        new Thread("Error dump: " + dropboxTag) {
9958            @Override
9959            public void run() {
9960                // 5 second sleep to let stacks arrive and be batched together
9961                try {
9962                    Thread.sleep(5000);  // 5 seconds
9963                } catch (InterruptedException e) {}
9964
9965                String errorReport;
9966                synchronized (mStrictModeBuffer) {
9967                    errorReport = mStrictModeBuffer.toString();
9968                    if (errorReport.length() == 0) {
9969                        return;
9970                    }
9971                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9972                    mStrictModeBuffer.trimToSize();
9973                }
9974                dbox.addText(dropboxTag, errorReport);
9975            }
9976        }.start();
9977    }
9978
9979    /**
9980     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9981     * @param app object of the crashing app, null for the system server
9982     * @param tag reported by the caller
9983     * @param crashInfo describing the context of the error
9984     * @return true if the process should exit immediately (WTF is fatal)
9985     */
9986    public boolean handleApplicationWtf(IBinder app, String tag,
9987            ApplicationErrorReport.CrashInfo crashInfo) {
9988        ProcessRecord r = findAppProcess(app, "WTF");
9989        final String processName = app == null ? "system_server"
9990                : (r == null ? "unknown" : r.processName);
9991
9992        EventLog.writeEvent(EventLogTags.AM_WTF,
9993                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9994                processName,
9995                r == null ? -1 : r.info.flags,
9996                tag, crashInfo.exceptionMessage);
9997
9998        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9999
10000        if (r != null && r.pid != Process.myPid() &&
10001                Settings.Global.getInt(mContext.getContentResolver(),
10002                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10003            crashApplication(r, crashInfo);
10004            return true;
10005        } else {
10006            return false;
10007        }
10008    }
10009
10010    /**
10011     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10012     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10013     */
10014    private ProcessRecord findAppProcess(IBinder app, String reason) {
10015        if (app == null) {
10016            return null;
10017        }
10018
10019        synchronized (this) {
10020            final int NP = mProcessNames.getMap().size();
10021            for (int ip=0; ip<NP; ip++) {
10022                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10023                final int NA = apps.size();
10024                for (int ia=0; ia<NA; ia++) {
10025                    ProcessRecord p = apps.valueAt(ia);
10026                    if (p.thread != null && p.thread.asBinder() == app) {
10027                        return p;
10028                    }
10029                }
10030            }
10031
10032            Slog.w(TAG, "Can't find mystery application for " + reason
10033                    + " from pid=" + Binder.getCallingPid()
10034                    + " uid=" + Binder.getCallingUid() + ": " + app);
10035            return null;
10036        }
10037    }
10038
10039    /**
10040     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10041     * to append various headers to the dropbox log text.
10042     */
10043    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10044            StringBuilder sb) {
10045        // Watchdog thread ends up invoking this function (with
10046        // a null ProcessRecord) to add the stack file to dropbox.
10047        // Do not acquire a lock on this (am) in such cases, as it
10048        // could cause a potential deadlock, if and when watchdog
10049        // is invoked due to unavailability of lock on am and it
10050        // would prevent watchdog from killing system_server.
10051        if (process == null) {
10052            sb.append("Process: ").append(processName).append("\n");
10053            return;
10054        }
10055        // Note: ProcessRecord 'process' is guarded by the service
10056        // instance.  (notably process.pkgList, which could otherwise change
10057        // concurrently during execution of this method)
10058        synchronized (this) {
10059            sb.append("Process: ").append(processName).append("\n");
10060            int flags = process.info.flags;
10061            IPackageManager pm = AppGlobals.getPackageManager();
10062            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10063            for (int ip=0; ip<process.pkgList.size(); ip++) {
10064                String pkg = process.pkgList.keyAt(ip);
10065                sb.append("Package: ").append(pkg);
10066                try {
10067                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10068                    if (pi != null) {
10069                        sb.append(" v").append(pi.versionCode);
10070                        if (pi.versionName != null) {
10071                            sb.append(" (").append(pi.versionName).append(")");
10072                        }
10073                    }
10074                } catch (RemoteException e) {
10075                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10076                }
10077                sb.append("\n");
10078            }
10079        }
10080    }
10081
10082    private static String processClass(ProcessRecord process) {
10083        if (process == null || process.pid == MY_PID) {
10084            return "system_server";
10085        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10086            return "system_app";
10087        } else {
10088            return "data_app";
10089        }
10090    }
10091
10092    /**
10093     * Write a description of an error (crash, WTF, ANR) to the drop box.
10094     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10095     * @param process which caused the error, null means the system server
10096     * @param activity which triggered the error, null if unknown
10097     * @param parent activity related to the error, null if unknown
10098     * @param subject line related to the error, null if absent
10099     * @param report in long form describing the error, null if absent
10100     * @param logFile to include in the report, null if none
10101     * @param crashInfo giving an application stack trace, null if absent
10102     */
10103    public void addErrorToDropBox(String eventType,
10104            ProcessRecord process, String processName, ActivityRecord activity,
10105            ActivityRecord parent, String subject,
10106            final String report, final File logFile,
10107            final ApplicationErrorReport.CrashInfo crashInfo) {
10108        // NOTE -- this must never acquire the ActivityManagerService lock,
10109        // otherwise the watchdog may be prevented from resetting the system.
10110
10111        final String dropboxTag = processClass(process) + "_" + eventType;
10112        final DropBoxManager dbox = (DropBoxManager)
10113                mContext.getSystemService(Context.DROPBOX_SERVICE);
10114
10115        // Exit early if the dropbox isn't configured to accept this report type.
10116        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10117
10118        final StringBuilder sb = new StringBuilder(1024);
10119        appendDropBoxProcessHeaders(process, processName, sb);
10120        if (activity != null) {
10121            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10122        }
10123        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10124            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10125        }
10126        if (parent != null && parent != activity) {
10127            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10128        }
10129        if (subject != null) {
10130            sb.append("Subject: ").append(subject).append("\n");
10131        }
10132        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10133        if (Debug.isDebuggerConnected()) {
10134            sb.append("Debugger: Connected\n");
10135        }
10136        sb.append("\n");
10137
10138        // Do the rest in a worker thread to avoid blocking the caller on I/O
10139        // (After this point, we shouldn't access AMS internal data structures.)
10140        Thread worker = new Thread("Error dump: " + dropboxTag) {
10141            @Override
10142            public void run() {
10143                if (report != null) {
10144                    sb.append(report);
10145                }
10146                if (logFile != null) {
10147                    try {
10148                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10149                                    "\n\n[[TRUNCATED]]"));
10150                    } catch (IOException e) {
10151                        Slog.e(TAG, "Error reading " + logFile, e);
10152                    }
10153                }
10154                if (crashInfo != null && crashInfo.stackTrace != null) {
10155                    sb.append(crashInfo.stackTrace);
10156                }
10157
10158                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10159                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10160                if (lines > 0) {
10161                    sb.append("\n");
10162
10163                    // Merge several logcat streams, and take the last N lines
10164                    InputStreamReader input = null;
10165                    try {
10166                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10167                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10168                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10169
10170                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10171                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10172                        input = new InputStreamReader(logcat.getInputStream());
10173
10174                        int num;
10175                        char[] buf = new char[8192];
10176                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10177                    } catch (IOException e) {
10178                        Slog.e(TAG, "Error running logcat", e);
10179                    } finally {
10180                        if (input != null) try { input.close(); } catch (IOException e) {}
10181                    }
10182                }
10183
10184                dbox.addText(dropboxTag, sb.toString());
10185            }
10186        };
10187
10188        if (process == null) {
10189            // If process is null, we are being called from some internal code
10190            // and may be about to die -- run this synchronously.
10191            worker.run();
10192        } else {
10193            worker.start();
10194        }
10195    }
10196
10197    /**
10198     * Bring up the "unexpected error" dialog box for a crashing app.
10199     * Deal with edge cases (intercepts from instrumented applications,
10200     * ActivityController, error intent receivers, that sort of thing).
10201     * @param r the application crashing
10202     * @param crashInfo describing the failure
10203     */
10204    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10205        long timeMillis = System.currentTimeMillis();
10206        String shortMsg = crashInfo.exceptionClassName;
10207        String longMsg = crashInfo.exceptionMessage;
10208        String stackTrace = crashInfo.stackTrace;
10209        if (shortMsg != null && longMsg != null) {
10210            longMsg = shortMsg + ": " + longMsg;
10211        } else if (shortMsg != null) {
10212            longMsg = shortMsg;
10213        }
10214
10215        AppErrorResult result = new AppErrorResult();
10216        synchronized (this) {
10217            if (mController != null) {
10218                try {
10219                    String name = r != null ? r.processName : null;
10220                    int pid = r != null ? r.pid : Binder.getCallingPid();
10221                    if (!mController.appCrashed(name, pid,
10222                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10223                        Slog.w(TAG, "Force-killing crashed app " + name
10224                                + " at watcher's request");
10225                        Process.killProcess(pid);
10226                        return;
10227                    }
10228                } catch (RemoteException e) {
10229                    mController = null;
10230                    Watchdog.getInstance().setActivityController(null);
10231                }
10232            }
10233
10234            final long origId = Binder.clearCallingIdentity();
10235
10236            // If this process is running instrumentation, finish it.
10237            if (r != null && r.instrumentationClass != null) {
10238                Slog.w(TAG, "Error in app " + r.processName
10239                      + " running instrumentation " + r.instrumentationClass + ":");
10240                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10241                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10242                Bundle info = new Bundle();
10243                info.putString("shortMsg", shortMsg);
10244                info.putString("longMsg", longMsg);
10245                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10246                Binder.restoreCallingIdentity(origId);
10247                return;
10248            }
10249
10250            // If we can't identify the process or it's already exceeded its crash quota,
10251            // quit right away without showing a crash dialog.
10252            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10253                Binder.restoreCallingIdentity(origId);
10254                return;
10255            }
10256
10257            Message msg = Message.obtain();
10258            msg.what = SHOW_ERROR_MSG;
10259            HashMap data = new HashMap();
10260            data.put("result", result);
10261            data.put("app", r);
10262            msg.obj = data;
10263            mHandler.sendMessage(msg);
10264
10265            Binder.restoreCallingIdentity(origId);
10266        }
10267
10268        int res = result.get();
10269
10270        Intent appErrorIntent = null;
10271        synchronized (this) {
10272            if (r != null && !r.isolated) {
10273                // XXX Can't keep track of crash time for isolated processes,
10274                // since they don't have a persistent identity.
10275                mProcessCrashTimes.put(r.info.processName, r.uid,
10276                        SystemClock.uptimeMillis());
10277            }
10278            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10279                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10280            }
10281        }
10282
10283        if (appErrorIntent != null) {
10284            try {
10285                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10286            } catch (ActivityNotFoundException e) {
10287                Slog.w(TAG, "bug report receiver dissappeared", e);
10288            }
10289        }
10290    }
10291
10292    Intent createAppErrorIntentLocked(ProcessRecord r,
10293            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10294        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10295        if (report == null) {
10296            return null;
10297        }
10298        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10299        result.setComponent(r.errorReportReceiver);
10300        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10301        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10302        return result;
10303    }
10304
10305    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10306            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10307        if (r.errorReportReceiver == null) {
10308            return null;
10309        }
10310
10311        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10312            return null;
10313        }
10314
10315        ApplicationErrorReport report = new ApplicationErrorReport();
10316        report.packageName = r.info.packageName;
10317        report.installerPackageName = r.errorReportReceiver.getPackageName();
10318        report.processName = r.processName;
10319        report.time = timeMillis;
10320        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10321
10322        if (r.crashing || r.forceCrashReport) {
10323            report.type = ApplicationErrorReport.TYPE_CRASH;
10324            report.crashInfo = crashInfo;
10325        } else if (r.notResponding) {
10326            report.type = ApplicationErrorReport.TYPE_ANR;
10327            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10328
10329            report.anrInfo.activity = r.notRespondingReport.tag;
10330            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10331            report.anrInfo.info = r.notRespondingReport.longMsg;
10332        }
10333
10334        return report;
10335    }
10336
10337    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10338        enforceNotIsolatedCaller("getProcessesInErrorState");
10339        // assume our apps are happy - lazy create the list
10340        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10341
10342        final boolean allUsers = ActivityManager.checkUidPermission(
10343                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10344                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10345        int userId = UserHandle.getUserId(Binder.getCallingUid());
10346
10347        synchronized (this) {
10348
10349            // iterate across all processes
10350            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10351                ProcessRecord app = mLruProcesses.get(i);
10352                if (!allUsers && app.userId != userId) {
10353                    continue;
10354                }
10355                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10356                    // This one's in trouble, so we'll generate a report for it
10357                    // crashes are higher priority (in case there's a crash *and* an anr)
10358                    ActivityManager.ProcessErrorStateInfo report = null;
10359                    if (app.crashing) {
10360                        report = app.crashingReport;
10361                    } else if (app.notResponding) {
10362                        report = app.notRespondingReport;
10363                    }
10364
10365                    if (report != null) {
10366                        if (errList == null) {
10367                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10368                        }
10369                        errList.add(report);
10370                    } else {
10371                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10372                                " crashing = " + app.crashing +
10373                                " notResponding = " + app.notResponding);
10374                    }
10375                }
10376            }
10377        }
10378
10379        return errList;
10380    }
10381
10382    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10383        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10384            if (currApp != null) {
10385                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10386            }
10387            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10388        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10389            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10390        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10391            if (currApp != null) {
10392                currApp.lru = 0;
10393            }
10394            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10395        } else if (adj >= ProcessList.SERVICE_ADJ) {
10396            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10397        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10398            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10399        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10400            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10401        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10402            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10403        } else {
10404            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10405        }
10406    }
10407
10408    private void fillInProcMemInfo(ProcessRecord app,
10409            ActivityManager.RunningAppProcessInfo outInfo) {
10410        outInfo.pid = app.pid;
10411        outInfo.uid = app.info.uid;
10412        if (mHeavyWeightProcess == app) {
10413            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10414        }
10415        if (app.persistent) {
10416            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10417        }
10418        if (app.activities.size() > 0) {
10419            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10420        }
10421        outInfo.lastTrimLevel = app.trimMemoryLevel;
10422        int adj = app.curAdj;
10423        outInfo.importance = oomAdjToImportance(adj, outInfo);
10424        outInfo.importanceReasonCode = app.adjTypeCode;
10425    }
10426
10427    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10428        enforceNotIsolatedCaller("getRunningAppProcesses");
10429        // Lazy instantiation of list
10430        List<ActivityManager.RunningAppProcessInfo> runList = null;
10431        final boolean allUsers = ActivityManager.checkUidPermission(
10432                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10433                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10434        int userId = UserHandle.getUserId(Binder.getCallingUid());
10435        synchronized (this) {
10436            // Iterate across all processes
10437            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10438                ProcessRecord app = mLruProcesses.get(i);
10439                if (!allUsers && app.userId != userId) {
10440                    continue;
10441                }
10442                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10443                    // Generate process state info for running application
10444                    ActivityManager.RunningAppProcessInfo currApp =
10445                        new ActivityManager.RunningAppProcessInfo(app.processName,
10446                                app.pid, app.getPackageList());
10447                    fillInProcMemInfo(app, currApp);
10448                    if (app.adjSource instanceof ProcessRecord) {
10449                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10450                        currApp.importanceReasonImportance = oomAdjToImportance(
10451                                app.adjSourceOom, null);
10452                    } else if (app.adjSource instanceof ActivityRecord) {
10453                        ActivityRecord r = (ActivityRecord)app.adjSource;
10454                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10455                    }
10456                    if (app.adjTarget instanceof ComponentName) {
10457                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10458                    }
10459                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10460                    //        + " lru=" + currApp.lru);
10461                    if (runList == null) {
10462                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10463                    }
10464                    runList.add(currApp);
10465                }
10466            }
10467        }
10468        return runList;
10469    }
10470
10471    public List<ApplicationInfo> getRunningExternalApplications() {
10472        enforceNotIsolatedCaller("getRunningExternalApplications");
10473        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10474        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10475        if (runningApps != null && runningApps.size() > 0) {
10476            Set<String> extList = new HashSet<String>();
10477            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10478                if (app.pkgList != null) {
10479                    for (String pkg : app.pkgList) {
10480                        extList.add(pkg);
10481                    }
10482                }
10483            }
10484            IPackageManager pm = AppGlobals.getPackageManager();
10485            for (String pkg : extList) {
10486                try {
10487                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10488                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10489                        retList.add(info);
10490                    }
10491                } catch (RemoteException e) {
10492                }
10493            }
10494        }
10495        return retList;
10496    }
10497
10498    @Override
10499    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10500        enforceNotIsolatedCaller("getMyMemoryState");
10501        synchronized (this) {
10502            ProcessRecord proc;
10503            synchronized (mPidsSelfLocked) {
10504                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10505            }
10506            fillInProcMemInfo(proc, outInfo);
10507        }
10508    }
10509
10510    @Override
10511    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10512        if (checkCallingPermission(android.Manifest.permission.DUMP)
10513                != PackageManager.PERMISSION_GRANTED) {
10514            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10515                    + Binder.getCallingPid()
10516                    + ", uid=" + Binder.getCallingUid()
10517                    + " without permission "
10518                    + android.Manifest.permission.DUMP);
10519            return;
10520        }
10521
10522        boolean dumpAll = false;
10523        boolean dumpClient = false;
10524        String dumpPackage = null;
10525
10526        int opti = 0;
10527        while (opti < args.length) {
10528            String opt = args[opti];
10529            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10530                break;
10531            }
10532            opti++;
10533            if ("-a".equals(opt)) {
10534                dumpAll = true;
10535            } else if ("-c".equals(opt)) {
10536                dumpClient = true;
10537            } else if ("-h".equals(opt)) {
10538                pw.println("Activity manager dump options:");
10539                pw.println("  [-a] [-c] [-h] [cmd] ...");
10540                pw.println("  cmd may be one of:");
10541                pw.println("    a[ctivities]: activity stack state");
10542                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10543                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10544                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10545                pw.println("    o[om]: out of memory management");
10546                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10547                pw.println("    provider [COMP_SPEC]: provider client-side state");
10548                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10549                pw.println("    service [COMP_SPEC]: service client-side state");
10550                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10551                pw.println("    all: dump all activities");
10552                pw.println("    top: dump the top activity");
10553                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10554                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10555                pw.println("    a partial substring in a component name, a");
10556                pw.println("    hex object identifier.");
10557                pw.println("  -a: include all available server state.");
10558                pw.println("  -c: include client state.");
10559                return;
10560            } else {
10561                pw.println("Unknown argument: " + opt + "; use -h for help");
10562            }
10563        }
10564
10565        long origId = Binder.clearCallingIdentity();
10566        boolean more = false;
10567        // Is the caller requesting to dump a particular piece of data?
10568        if (opti < args.length) {
10569            String cmd = args[opti];
10570            opti++;
10571            if ("activities".equals(cmd) || "a".equals(cmd)) {
10572                synchronized (this) {
10573                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10574                }
10575            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10576                String[] newArgs;
10577                String name;
10578                if (opti >= args.length) {
10579                    name = null;
10580                    newArgs = EMPTY_STRING_ARRAY;
10581                } else {
10582                    name = args[opti];
10583                    opti++;
10584                    newArgs = new String[args.length - opti];
10585                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10586                            args.length - opti);
10587                }
10588                synchronized (this) {
10589                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10590                }
10591            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10592                String[] newArgs;
10593                String name;
10594                if (opti >= args.length) {
10595                    name = null;
10596                    newArgs = EMPTY_STRING_ARRAY;
10597                } else {
10598                    name = args[opti];
10599                    opti++;
10600                    newArgs = new String[args.length - opti];
10601                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10602                            args.length - opti);
10603                }
10604                synchronized (this) {
10605                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10606                }
10607            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10608                String[] newArgs;
10609                String name;
10610                if (opti >= args.length) {
10611                    name = null;
10612                    newArgs = EMPTY_STRING_ARRAY;
10613                } else {
10614                    name = args[opti];
10615                    opti++;
10616                    newArgs = new String[args.length - opti];
10617                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10618                            args.length - opti);
10619                }
10620                synchronized (this) {
10621                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10622                }
10623            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10624                synchronized (this) {
10625                    dumpOomLocked(fd, pw, args, opti, true);
10626                }
10627            } else if ("provider".equals(cmd)) {
10628                String[] newArgs;
10629                String name;
10630                if (opti >= args.length) {
10631                    name = null;
10632                    newArgs = EMPTY_STRING_ARRAY;
10633                } else {
10634                    name = args[opti];
10635                    opti++;
10636                    newArgs = new String[args.length - opti];
10637                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10638                }
10639                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10640                    pw.println("No providers match: " + name);
10641                    pw.println("Use -h for help.");
10642                }
10643            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10644                synchronized (this) {
10645                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10646                }
10647            } else if ("service".equals(cmd)) {
10648                String[] newArgs;
10649                String name;
10650                if (opti >= args.length) {
10651                    name = null;
10652                    newArgs = EMPTY_STRING_ARRAY;
10653                } else {
10654                    name = args[opti];
10655                    opti++;
10656                    newArgs = new String[args.length - opti];
10657                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10658                            args.length - opti);
10659                }
10660                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10661                    pw.println("No services match: " + name);
10662                    pw.println("Use -h for help.");
10663                }
10664            } else if ("package".equals(cmd)) {
10665                String[] newArgs;
10666                if (opti >= args.length) {
10667                    pw.println("package: no package name specified");
10668                    pw.println("Use -h for help.");
10669                } else {
10670                    dumpPackage = args[opti];
10671                    opti++;
10672                    newArgs = new String[args.length - opti];
10673                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10674                            args.length - opti);
10675                    args = newArgs;
10676                    opti = 0;
10677                    more = true;
10678                }
10679            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10680                synchronized (this) {
10681                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10682                }
10683            } else {
10684                // Dumping a single activity?
10685                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10686                    pw.println("Bad activity command, or no activities match: " + cmd);
10687                    pw.println("Use -h for help.");
10688                }
10689            }
10690            if (!more) {
10691                Binder.restoreCallingIdentity(origId);
10692                return;
10693            }
10694        }
10695
10696        // No piece of data specified, dump everything.
10697        synchronized (this) {
10698            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10699            pw.println();
10700            if (dumpAll) {
10701                pw.println("-------------------------------------------------------------------------------");
10702            }
10703            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10704            pw.println();
10705            if (dumpAll) {
10706                pw.println("-------------------------------------------------------------------------------");
10707            }
10708            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10709            pw.println();
10710            if (dumpAll) {
10711                pw.println("-------------------------------------------------------------------------------");
10712            }
10713            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10714            pw.println();
10715            if (dumpAll) {
10716                pw.println("-------------------------------------------------------------------------------");
10717            }
10718            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10719            pw.println();
10720            if (dumpAll) {
10721                pw.println("-------------------------------------------------------------------------------");
10722            }
10723            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10724        }
10725        Binder.restoreCallingIdentity(origId);
10726    }
10727
10728    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10729            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10730        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10731
10732        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10733                dumpPackage);
10734        boolean needSep = printedAnything;
10735
10736        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10737                dumpPackage, needSep, "  mFocusedActivity: ");
10738        if (printed) {
10739            printedAnything = true;
10740            needSep = false;
10741        }
10742
10743        if (dumpPackage == null) {
10744            if (needSep) {
10745                pw.println();
10746            }
10747            needSep = true;
10748            printedAnything = true;
10749            mStackSupervisor.dump(pw, "  ");
10750        }
10751
10752        if (mRecentTasks.size() > 0) {
10753            boolean printedHeader = false;
10754
10755            final int N = mRecentTasks.size();
10756            for (int i=0; i<N; i++) {
10757                TaskRecord tr = mRecentTasks.get(i);
10758                if (dumpPackage != null) {
10759                    if (tr.realActivity == null ||
10760                            !dumpPackage.equals(tr.realActivity)) {
10761                        continue;
10762                    }
10763                }
10764                if (!printedHeader) {
10765                    if (needSep) {
10766                        pw.println();
10767                    }
10768                    pw.println("  Recent tasks:");
10769                    printedHeader = true;
10770                    printedAnything = true;
10771                }
10772                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10773                        pw.println(tr);
10774                if (dumpAll) {
10775                    mRecentTasks.get(i).dump(pw, "    ");
10776                }
10777            }
10778        }
10779
10780        if (!printedAnything) {
10781            pw.println("  (nothing)");
10782        }
10783    }
10784
10785    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10786            int opti, boolean dumpAll, String dumpPackage) {
10787        boolean needSep = false;
10788        boolean printedAnything = false;
10789        int numPers = 0;
10790
10791        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10792
10793        if (dumpAll) {
10794            final int NP = mProcessNames.getMap().size();
10795            for (int ip=0; ip<NP; ip++) {
10796                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10797                final int NA = procs.size();
10798                for (int ia=0; ia<NA; ia++) {
10799                    ProcessRecord r = procs.valueAt(ia);
10800                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10801                        continue;
10802                    }
10803                    if (!needSep) {
10804                        pw.println("  All known processes:");
10805                        needSep = true;
10806                        printedAnything = true;
10807                    }
10808                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10809                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10810                        pw.print(" "); pw.println(r);
10811                    r.dump(pw, "    ");
10812                    if (r.persistent) {
10813                        numPers++;
10814                    }
10815                }
10816            }
10817        }
10818
10819        if (mIsolatedProcesses.size() > 0) {
10820            boolean printed = false;
10821            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10822                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10823                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10824                    continue;
10825                }
10826                if (!printed) {
10827                    if (needSep) {
10828                        pw.println();
10829                    }
10830                    pw.println("  Isolated process list (sorted by uid):");
10831                    printedAnything = true;
10832                    printed = true;
10833                    needSep = true;
10834                }
10835                pw.println(String.format("%sIsolated #%2d: %s",
10836                        "    ", i, r.toString()));
10837            }
10838        }
10839
10840        if (mLruProcesses.size() > 0) {
10841            if (needSep) {
10842                pw.println();
10843            }
10844            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10845                    pw.print(" total, non-act at ");
10846                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10847                    pw.print(", non-svc at ");
10848                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10849                    pw.println("):");
10850            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10851            needSep = true;
10852            printedAnything = true;
10853        }
10854
10855        if (dumpAll || dumpPackage != null) {
10856            synchronized (mPidsSelfLocked) {
10857                boolean printed = false;
10858                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10859                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10860                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10861                        continue;
10862                    }
10863                    if (!printed) {
10864                        if (needSep) pw.println();
10865                        needSep = true;
10866                        pw.println("  PID mappings:");
10867                        printed = true;
10868                        printedAnything = true;
10869                    }
10870                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10871                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10872                }
10873            }
10874        }
10875
10876        if (mForegroundProcesses.size() > 0) {
10877            synchronized (mPidsSelfLocked) {
10878                boolean printed = false;
10879                for (int i=0; i<mForegroundProcesses.size(); i++) {
10880                    ProcessRecord r = mPidsSelfLocked.get(
10881                            mForegroundProcesses.valueAt(i).pid);
10882                    if (dumpPackage != null && (r == null
10883                            || !r.pkgList.containsKey(dumpPackage))) {
10884                        continue;
10885                    }
10886                    if (!printed) {
10887                        if (needSep) pw.println();
10888                        needSep = true;
10889                        pw.println("  Foreground Processes:");
10890                        printed = true;
10891                        printedAnything = true;
10892                    }
10893                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10894                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10895                }
10896            }
10897        }
10898
10899        if (mPersistentStartingProcesses.size() > 0) {
10900            if (needSep) pw.println();
10901            needSep = true;
10902            printedAnything = true;
10903            pw.println("  Persisent processes that are starting:");
10904            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10905                    "Starting Norm", "Restarting PERS", dumpPackage);
10906        }
10907
10908        if (mRemovedProcesses.size() > 0) {
10909            if (needSep) pw.println();
10910            needSep = true;
10911            printedAnything = true;
10912            pw.println("  Processes that are being removed:");
10913            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10914                    "Removed Norm", "Removed PERS", dumpPackage);
10915        }
10916
10917        if (mProcessesOnHold.size() > 0) {
10918            if (needSep) pw.println();
10919            needSep = true;
10920            printedAnything = true;
10921            pw.println("  Processes that are on old until the system is ready:");
10922            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10923                    "OnHold Norm", "OnHold PERS", dumpPackage);
10924        }
10925
10926        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10927
10928        if (mProcessCrashTimes.getMap().size() > 0) {
10929            boolean printed = false;
10930            long now = SystemClock.uptimeMillis();
10931            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10932            final int NP = pmap.size();
10933            for (int ip=0; ip<NP; ip++) {
10934                String pname = pmap.keyAt(ip);
10935                SparseArray<Long> uids = pmap.valueAt(ip);
10936                final int N = uids.size();
10937                for (int i=0; i<N; i++) {
10938                    int puid = uids.keyAt(i);
10939                    ProcessRecord r = mProcessNames.get(pname, puid);
10940                    if (dumpPackage != null && (r == null
10941                            || !r.pkgList.containsKey(dumpPackage))) {
10942                        continue;
10943                    }
10944                    if (!printed) {
10945                        if (needSep) pw.println();
10946                        needSep = true;
10947                        pw.println("  Time since processes crashed:");
10948                        printed = true;
10949                        printedAnything = true;
10950                    }
10951                    pw.print("    Process "); pw.print(pname);
10952                            pw.print(" uid "); pw.print(puid);
10953                            pw.print(": last crashed ");
10954                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10955                            pw.println(" ago");
10956                }
10957            }
10958        }
10959
10960        if (mBadProcesses.getMap().size() > 0) {
10961            boolean printed = false;
10962            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10963            final int NP = pmap.size();
10964            for (int ip=0; ip<NP; ip++) {
10965                String pname = pmap.keyAt(ip);
10966                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10967                final int N = uids.size();
10968                for (int i=0; i<N; i++) {
10969                    int puid = uids.keyAt(i);
10970                    ProcessRecord r = mProcessNames.get(pname, puid);
10971                    if (dumpPackage != null && (r == null
10972                            || !r.pkgList.containsKey(dumpPackage))) {
10973                        continue;
10974                    }
10975                    if (!printed) {
10976                        if (needSep) pw.println();
10977                        needSep = true;
10978                        pw.println("  Bad processes:");
10979                        printedAnything = true;
10980                    }
10981                    BadProcessInfo info = uids.valueAt(i);
10982                    pw.print("    Bad process "); pw.print(pname);
10983                            pw.print(" uid "); pw.print(puid);
10984                            pw.print(": crashed at time "); pw.println(info.time);
10985                    if (info.shortMsg != null) {
10986                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10987                    }
10988                    if (info.longMsg != null) {
10989                        pw.print("      Long msg: "); pw.println(info.longMsg);
10990                    }
10991                    if (info.stack != null) {
10992                        pw.println("      Stack:");
10993                        int lastPos = 0;
10994                        for (int pos=0; pos<info.stack.length(); pos++) {
10995                            if (info.stack.charAt(pos) == '\n') {
10996                                pw.print("        ");
10997                                pw.write(info.stack, lastPos, pos-lastPos);
10998                                pw.println();
10999                                lastPos = pos+1;
11000                            }
11001                        }
11002                        if (lastPos < info.stack.length()) {
11003                            pw.print("        ");
11004                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11005                            pw.println();
11006                        }
11007                    }
11008                }
11009            }
11010        }
11011
11012        if (dumpPackage == null) {
11013            pw.println();
11014            needSep = false;
11015            pw.println("  mStartedUsers:");
11016            for (int i=0; i<mStartedUsers.size(); i++) {
11017                UserStartedState uss = mStartedUsers.valueAt(i);
11018                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11019                        pw.print(": "); uss.dump("", pw);
11020            }
11021            pw.print("  mStartedUserArray: [");
11022            for (int i=0; i<mStartedUserArray.length; i++) {
11023                if (i > 0) pw.print(", ");
11024                pw.print(mStartedUserArray[i]);
11025            }
11026            pw.println("]");
11027            pw.print("  mUserLru: [");
11028            for (int i=0; i<mUserLru.size(); i++) {
11029                if (i > 0) pw.print(", ");
11030                pw.print(mUserLru.get(i));
11031            }
11032            pw.println("]");
11033            if (dumpAll) {
11034                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11035            }
11036        }
11037        if (mHomeProcess != null && (dumpPackage == null
11038                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11039            if (needSep) {
11040                pw.println();
11041                needSep = false;
11042            }
11043            pw.println("  mHomeProcess: " + mHomeProcess);
11044        }
11045        if (mPreviousProcess != null && (dumpPackage == null
11046                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11047            if (needSep) {
11048                pw.println();
11049                needSep = false;
11050            }
11051            pw.println("  mPreviousProcess: " + mPreviousProcess);
11052        }
11053        if (dumpAll) {
11054            StringBuilder sb = new StringBuilder(128);
11055            sb.append("  mPreviousProcessVisibleTime: ");
11056            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11057            pw.println(sb);
11058        }
11059        if (mHeavyWeightProcess != null && (dumpPackage == null
11060                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11061            if (needSep) {
11062                pw.println();
11063                needSep = false;
11064            }
11065            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11066        }
11067        if (dumpPackage == null) {
11068            pw.println("  mConfiguration: " + mConfiguration);
11069        }
11070        if (dumpAll) {
11071            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11072            if (mCompatModePackages.getPackages().size() > 0) {
11073                boolean printed = false;
11074                for (Map.Entry<String, Integer> entry
11075                        : mCompatModePackages.getPackages().entrySet()) {
11076                    String pkg = entry.getKey();
11077                    int mode = entry.getValue();
11078                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11079                        continue;
11080                    }
11081                    if (!printed) {
11082                        pw.println("  mScreenCompatPackages:");
11083                        printed = true;
11084                    }
11085                    pw.print("    "); pw.print(pkg); pw.print(": ");
11086                            pw.print(mode); pw.println();
11087                }
11088            }
11089        }
11090        if (dumpPackage == null) {
11091            if (mSleeping || mWentToSleep || mLockScreenShown) {
11092                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11093                        + " mLockScreenShown " + mLockScreenShown);
11094            }
11095            if (mShuttingDown) {
11096                pw.println("  mShuttingDown=" + mShuttingDown);
11097            }
11098        }
11099        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11100                || mOrigWaitForDebugger) {
11101            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11102                    || dumpPackage.equals(mOrigDebugApp)) {
11103                if (needSep) {
11104                    pw.println();
11105                    needSep = false;
11106                }
11107                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11108                        + " mDebugTransient=" + mDebugTransient
11109                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11110            }
11111        }
11112        if (mOpenGlTraceApp != null) {
11113            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11114                if (needSep) {
11115                    pw.println();
11116                    needSep = false;
11117                }
11118                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11119            }
11120        }
11121        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11122                || mProfileFd != null) {
11123            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11124                if (needSep) {
11125                    pw.println();
11126                    needSep = false;
11127                }
11128                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11129                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11130                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11131                        + mAutoStopProfiler);
11132            }
11133        }
11134        if (dumpPackage == null) {
11135            if (mAlwaysFinishActivities || mController != null) {
11136                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11137                        + " mController=" + mController);
11138            }
11139            if (dumpAll) {
11140                pw.println("  Total persistent processes: " + numPers);
11141                pw.println("  mProcessesReady=" + mProcessesReady
11142                        + " mSystemReady=" + mSystemReady);
11143                pw.println("  mBooting=" + mBooting
11144                        + " mBooted=" + mBooted
11145                        + " mFactoryTest=" + mFactoryTest);
11146                pw.print("  mLastPowerCheckRealtime=");
11147                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11148                        pw.println("");
11149                pw.print("  mLastPowerCheckUptime=");
11150                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11151                        pw.println("");
11152                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11153                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11154                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11155                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11156                        + " (" + mLruProcesses.size() + " total)"
11157                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11158                        + " mNumServiceProcs=" + mNumServiceProcs
11159                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11160                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11161                        + " mLastMemoryLevel" + mLastMemoryLevel
11162                        + " mLastNumProcesses" + mLastNumProcesses);
11163                long now = SystemClock.uptimeMillis();
11164                pw.print("  mLastIdleTime=");
11165                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11166                        pw.print(" mLowRamSinceLastIdle=");
11167                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11168                        pw.println();
11169            }
11170        }
11171
11172        if (!printedAnything) {
11173            pw.println("  (nothing)");
11174        }
11175    }
11176
11177    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11178            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11179        if (mProcessesToGc.size() > 0) {
11180            boolean printed = false;
11181            long now = SystemClock.uptimeMillis();
11182            for (int i=0; i<mProcessesToGc.size(); i++) {
11183                ProcessRecord proc = mProcessesToGc.get(i);
11184                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11185                    continue;
11186                }
11187                if (!printed) {
11188                    if (needSep) pw.println();
11189                    needSep = true;
11190                    pw.println("  Processes that are waiting to GC:");
11191                    printed = true;
11192                }
11193                pw.print("    Process "); pw.println(proc);
11194                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11195                        pw.print(", last gced=");
11196                        pw.print(now-proc.lastRequestedGc);
11197                        pw.print(" ms ago, last lowMem=");
11198                        pw.print(now-proc.lastLowMemory);
11199                        pw.println(" ms ago");
11200
11201            }
11202        }
11203        return needSep;
11204    }
11205
11206    void printOomLevel(PrintWriter pw, String name, int adj) {
11207        pw.print("    ");
11208        if (adj >= 0) {
11209            pw.print(' ');
11210            if (adj < 10) pw.print(' ');
11211        } else {
11212            if (adj > -10) pw.print(' ');
11213        }
11214        pw.print(adj);
11215        pw.print(": ");
11216        pw.print(name);
11217        pw.print(" (");
11218        pw.print(mProcessList.getMemLevel(adj)/1024);
11219        pw.println(" kB)");
11220    }
11221
11222    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11223            int opti, boolean dumpAll) {
11224        boolean needSep = false;
11225
11226        if (mLruProcesses.size() > 0) {
11227            if (needSep) pw.println();
11228            needSep = true;
11229            pw.println("  OOM levels:");
11230            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11231            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11232            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11233            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11234            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11235            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11236            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11237            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11238            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11239            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11240            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11241            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11242            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11243
11244            if (needSep) pw.println();
11245            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11246                    pw.print(" total, non-act at ");
11247                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11248                    pw.print(", non-svc at ");
11249                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11250                    pw.println("):");
11251            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11252            needSep = true;
11253        }
11254
11255        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11256
11257        pw.println();
11258        pw.println("  mHomeProcess: " + mHomeProcess);
11259        pw.println("  mPreviousProcess: " + mPreviousProcess);
11260        if (mHeavyWeightProcess != null) {
11261            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11262        }
11263
11264        return true;
11265    }
11266
11267    /**
11268     * There are three ways to call this:
11269     *  - no provider specified: dump all the providers
11270     *  - a flattened component name that matched an existing provider was specified as the
11271     *    first arg: dump that one provider
11272     *  - the first arg isn't the flattened component name of an existing provider:
11273     *    dump all providers whose component contains the first arg as a substring
11274     */
11275    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11276            int opti, boolean dumpAll) {
11277        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11278    }
11279
11280    static class ItemMatcher {
11281        ArrayList<ComponentName> components;
11282        ArrayList<String> strings;
11283        ArrayList<Integer> objects;
11284        boolean all;
11285
11286        ItemMatcher() {
11287            all = true;
11288        }
11289
11290        void build(String name) {
11291            ComponentName componentName = ComponentName.unflattenFromString(name);
11292            if (componentName != null) {
11293                if (components == null) {
11294                    components = new ArrayList<ComponentName>();
11295                }
11296                components.add(componentName);
11297                all = false;
11298            } else {
11299                int objectId = 0;
11300                // Not a '/' separated full component name; maybe an object ID?
11301                try {
11302                    objectId = Integer.parseInt(name, 16);
11303                    if (objects == null) {
11304                        objects = new ArrayList<Integer>();
11305                    }
11306                    objects.add(objectId);
11307                    all = false;
11308                } catch (RuntimeException e) {
11309                    // Not an integer; just do string match.
11310                    if (strings == null) {
11311                        strings = new ArrayList<String>();
11312                    }
11313                    strings.add(name);
11314                    all = false;
11315                }
11316            }
11317        }
11318
11319        int build(String[] args, int opti) {
11320            for (; opti<args.length; opti++) {
11321                String name = args[opti];
11322                if ("--".equals(name)) {
11323                    return opti+1;
11324                }
11325                build(name);
11326            }
11327            return opti;
11328        }
11329
11330        boolean match(Object object, ComponentName comp) {
11331            if (all) {
11332                return true;
11333            }
11334            if (components != null) {
11335                for (int i=0; i<components.size(); i++) {
11336                    if (components.get(i).equals(comp)) {
11337                        return true;
11338                    }
11339                }
11340            }
11341            if (objects != null) {
11342                for (int i=0; i<objects.size(); i++) {
11343                    if (System.identityHashCode(object) == objects.get(i)) {
11344                        return true;
11345                    }
11346                }
11347            }
11348            if (strings != null) {
11349                String flat = comp.flattenToString();
11350                for (int i=0; i<strings.size(); i++) {
11351                    if (flat.contains(strings.get(i))) {
11352                        return true;
11353                    }
11354                }
11355            }
11356            return false;
11357        }
11358    }
11359
11360    /**
11361     * There are three things that cmd can be:
11362     *  - a flattened component name that matches an existing activity
11363     *  - the cmd arg isn't the flattened component name of an existing activity:
11364     *    dump all activity whose component contains the cmd as a substring
11365     *  - A hex number of the ActivityRecord object instance.
11366     */
11367    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11368            int opti, boolean dumpAll) {
11369        ArrayList<ActivityRecord> activities;
11370
11371        synchronized (this) {
11372            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11373        }
11374
11375        if (activities.size() <= 0) {
11376            return false;
11377        }
11378
11379        String[] newArgs = new String[args.length - opti];
11380        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11381
11382        TaskRecord lastTask = null;
11383        boolean needSep = false;
11384        for (int i=activities.size()-1; i>=0; i--) {
11385            ActivityRecord r = activities.get(i);
11386            if (needSep) {
11387                pw.println();
11388            }
11389            needSep = true;
11390            synchronized (this) {
11391                if (lastTask != r.task) {
11392                    lastTask = r.task;
11393                    pw.print("TASK "); pw.print(lastTask.affinity);
11394                            pw.print(" id="); pw.println(lastTask.taskId);
11395                    if (dumpAll) {
11396                        lastTask.dump(pw, "  ");
11397                    }
11398                }
11399            }
11400            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11401        }
11402        return true;
11403    }
11404
11405    /**
11406     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11407     * there is a thread associated with the activity.
11408     */
11409    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11410            final ActivityRecord r, String[] args, boolean dumpAll) {
11411        String innerPrefix = prefix + "  ";
11412        synchronized (this) {
11413            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11414                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11415                    pw.print(" pid=");
11416                    if (r.app != null) pw.println(r.app.pid);
11417                    else pw.println("(not running)");
11418            if (dumpAll) {
11419                r.dump(pw, innerPrefix);
11420            }
11421        }
11422        if (r.app != null && r.app.thread != null) {
11423            // flush anything that is already in the PrintWriter since the thread is going
11424            // to write to the file descriptor directly
11425            pw.flush();
11426            try {
11427                TransferPipe tp = new TransferPipe();
11428                try {
11429                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11430                            r.appToken, innerPrefix, args);
11431                    tp.go(fd);
11432                } finally {
11433                    tp.kill();
11434                }
11435            } catch (IOException e) {
11436                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11437            } catch (RemoteException e) {
11438                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11439            }
11440        }
11441    }
11442
11443    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11444            int opti, boolean dumpAll, String dumpPackage) {
11445        boolean needSep = false;
11446        boolean onlyHistory = false;
11447        boolean printedAnything = false;
11448
11449        if ("history".equals(dumpPackage)) {
11450            if (opti < args.length && "-s".equals(args[opti])) {
11451                dumpAll = false;
11452            }
11453            onlyHistory = true;
11454            dumpPackage = null;
11455        }
11456
11457        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11458        if (!onlyHistory && dumpAll) {
11459            if (mRegisteredReceivers.size() > 0) {
11460                boolean printed = false;
11461                Iterator it = mRegisteredReceivers.values().iterator();
11462                while (it.hasNext()) {
11463                    ReceiverList r = (ReceiverList)it.next();
11464                    if (dumpPackage != null && (r.app == null ||
11465                            !dumpPackage.equals(r.app.info.packageName))) {
11466                        continue;
11467                    }
11468                    if (!printed) {
11469                        pw.println("  Registered Receivers:");
11470                        needSep = true;
11471                        printed = true;
11472                        printedAnything = true;
11473                    }
11474                    pw.print("  * "); pw.println(r);
11475                    r.dump(pw, "    ");
11476                }
11477            }
11478
11479            if (mReceiverResolver.dump(pw, needSep ?
11480                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11481                    "    ", dumpPackage, false)) {
11482                needSep = true;
11483                printedAnything = true;
11484            }
11485        }
11486
11487        for (BroadcastQueue q : mBroadcastQueues) {
11488            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11489            printedAnything |= needSep;
11490        }
11491
11492        needSep = true;
11493
11494        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11495            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11496                if (needSep) {
11497                    pw.println();
11498                }
11499                needSep = true;
11500                printedAnything = true;
11501                pw.print("  Sticky broadcasts for user ");
11502                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11503                StringBuilder sb = new StringBuilder(128);
11504                for (Map.Entry<String, ArrayList<Intent>> ent
11505                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11506                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11507                    if (dumpAll) {
11508                        pw.println(":");
11509                        ArrayList<Intent> intents = ent.getValue();
11510                        final int N = intents.size();
11511                        for (int i=0; i<N; i++) {
11512                            sb.setLength(0);
11513                            sb.append("    Intent: ");
11514                            intents.get(i).toShortString(sb, false, true, false, false);
11515                            pw.println(sb.toString());
11516                            Bundle bundle = intents.get(i).getExtras();
11517                            if (bundle != null) {
11518                                pw.print("      ");
11519                                pw.println(bundle.toString());
11520                            }
11521                        }
11522                    } else {
11523                        pw.println("");
11524                    }
11525                }
11526            }
11527        }
11528
11529        if (!onlyHistory && dumpAll) {
11530            pw.println();
11531            for (BroadcastQueue queue : mBroadcastQueues) {
11532                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11533                        + queue.mBroadcastsScheduled);
11534            }
11535            pw.println("  mHandler:");
11536            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11537            needSep = true;
11538            printedAnything = true;
11539        }
11540
11541        if (!printedAnything) {
11542            pw.println("  (nothing)");
11543        }
11544    }
11545
11546    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11547            int opti, boolean dumpAll, String dumpPackage) {
11548        boolean needSep;
11549        boolean printedAnything = false;
11550
11551        ItemMatcher matcher = new ItemMatcher();
11552        matcher.build(args, opti);
11553
11554        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11555
11556        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11557        printedAnything |= needSep;
11558
11559        if (mLaunchingProviders.size() > 0) {
11560            boolean printed = false;
11561            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11562                ContentProviderRecord r = mLaunchingProviders.get(i);
11563                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11564                    continue;
11565                }
11566                if (!printed) {
11567                    if (needSep) pw.println();
11568                    needSep = true;
11569                    pw.println("  Launching content providers:");
11570                    printed = true;
11571                    printedAnything = true;
11572                }
11573                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11574                        pw.println(r);
11575            }
11576        }
11577
11578        if (mGrantedUriPermissions.size() > 0) {
11579            boolean printed = false;
11580            int dumpUid = -2;
11581            if (dumpPackage != null) {
11582                try {
11583                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11584                } catch (NameNotFoundException e) {
11585                    dumpUid = -1;
11586                }
11587            }
11588            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11589                int uid = mGrantedUriPermissions.keyAt(i);
11590                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11591                    continue;
11592                }
11593                ArrayMap<Uri, UriPermission> perms
11594                        = mGrantedUriPermissions.valueAt(i);
11595                if (!printed) {
11596                    if (needSep) pw.println();
11597                    needSep = true;
11598                    pw.println("  Granted Uri Permissions:");
11599                    printed = true;
11600                    printedAnything = true;
11601                }
11602                pw.print("  * UID "); pw.print(uid);
11603                        pw.println(" holds:");
11604                for (UriPermission perm : perms.values()) {
11605                    pw.print("    "); pw.println(perm);
11606                    if (dumpAll) {
11607                        perm.dump(pw, "      ");
11608                    }
11609                }
11610            }
11611        }
11612
11613        if (!printedAnything) {
11614            pw.println("  (nothing)");
11615        }
11616    }
11617
11618    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11619            int opti, boolean dumpAll, String dumpPackage) {
11620        boolean printed = false;
11621
11622        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11623
11624        if (mIntentSenderRecords.size() > 0) {
11625            Iterator<WeakReference<PendingIntentRecord>> it
11626                    = mIntentSenderRecords.values().iterator();
11627            while (it.hasNext()) {
11628                WeakReference<PendingIntentRecord> ref = it.next();
11629                PendingIntentRecord rec = ref != null ? ref.get(): null;
11630                if (dumpPackage != null && (rec == null
11631                        || !dumpPackage.equals(rec.key.packageName))) {
11632                    continue;
11633                }
11634                printed = true;
11635                if (rec != null) {
11636                    pw.print("  * "); pw.println(rec);
11637                    if (dumpAll) {
11638                        rec.dump(pw, "    ");
11639                    }
11640                } else {
11641                    pw.print("  * "); pw.println(ref);
11642                }
11643            }
11644        }
11645
11646        if (!printed) {
11647            pw.println("  (nothing)");
11648        }
11649    }
11650
11651    private static final int dumpProcessList(PrintWriter pw,
11652            ActivityManagerService service, List list,
11653            String prefix, String normalLabel, String persistentLabel,
11654            String dumpPackage) {
11655        int numPers = 0;
11656        final int N = list.size()-1;
11657        for (int i=N; i>=0; i--) {
11658            ProcessRecord r = (ProcessRecord)list.get(i);
11659            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11660                continue;
11661            }
11662            pw.println(String.format("%s%s #%2d: %s",
11663                    prefix, (r.persistent ? persistentLabel : normalLabel),
11664                    i, r.toString()));
11665            if (r.persistent) {
11666                numPers++;
11667            }
11668        }
11669        return numPers;
11670    }
11671
11672    private static final boolean dumpProcessOomList(PrintWriter pw,
11673            ActivityManagerService service, List<ProcessRecord> origList,
11674            String prefix, String normalLabel, String persistentLabel,
11675            boolean inclDetails, String dumpPackage) {
11676
11677        ArrayList<Pair<ProcessRecord, Integer>> list
11678                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11679        for (int i=0; i<origList.size(); i++) {
11680            ProcessRecord r = origList.get(i);
11681            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11682                continue;
11683            }
11684            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11685        }
11686
11687        if (list.size() <= 0) {
11688            return false;
11689        }
11690
11691        Comparator<Pair<ProcessRecord, Integer>> comparator
11692                = new Comparator<Pair<ProcessRecord, Integer>>() {
11693            @Override
11694            public int compare(Pair<ProcessRecord, Integer> object1,
11695                    Pair<ProcessRecord, Integer> object2) {
11696                if (object1.first.setAdj != object2.first.setAdj) {
11697                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11698                }
11699                if (object1.second.intValue() != object2.second.intValue()) {
11700                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11701                }
11702                return 0;
11703            }
11704        };
11705
11706        Collections.sort(list, comparator);
11707
11708        final long curRealtime = SystemClock.elapsedRealtime();
11709        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11710        final long curUptime = SystemClock.uptimeMillis();
11711        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11712
11713        for (int i=list.size()-1; i>=0; i--) {
11714            ProcessRecord r = list.get(i).first;
11715            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11716            char schedGroup;
11717            switch (r.setSchedGroup) {
11718                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11719                    schedGroup = 'B';
11720                    break;
11721                case Process.THREAD_GROUP_DEFAULT:
11722                    schedGroup = 'F';
11723                    break;
11724                default:
11725                    schedGroup = '?';
11726                    break;
11727            }
11728            char foreground;
11729            if (r.foregroundActivities) {
11730                foreground = 'A';
11731            } else if (r.foregroundServices) {
11732                foreground = 'S';
11733            } else {
11734                foreground = ' ';
11735            }
11736            String procState = ProcessList.makeProcStateString(r.curProcState);
11737            pw.print(prefix);
11738            pw.print(r.persistent ? persistentLabel : normalLabel);
11739            pw.print(" #");
11740            int num = (origList.size()-1)-list.get(i).second;
11741            if (num < 10) pw.print(' ');
11742            pw.print(num);
11743            pw.print(": ");
11744            pw.print(oomAdj);
11745            pw.print(' ');
11746            pw.print(schedGroup);
11747            pw.print('/');
11748            pw.print(foreground);
11749            pw.print('/');
11750            pw.print(procState);
11751            pw.print(" trm:");
11752            if (r.trimMemoryLevel < 10) pw.print(' ');
11753            pw.print(r.trimMemoryLevel);
11754            pw.print(' ');
11755            pw.print(r.toShortString());
11756            pw.print(" (");
11757            pw.print(r.adjType);
11758            pw.println(')');
11759            if (r.adjSource != null || r.adjTarget != null) {
11760                pw.print(prefix);
11761                pw.print("    ");
11762                if (r.adjTarget instanceof ComponentName) {
11763                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11764                } else if (r.adjTarget != null) {
11765                    pw.print(r.adjTarget.toString());
11766                } else {
11767                    pw.print("{null}");
11768                }
11769                pw.print("<=");
11770                if (r.adjSource instanceof ProcessRecord) {
11771                    pw.print("Proc{");
11772                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11773                    pw.println("}");
11774                } else if (r.adjSource != null) {
11775                    pw.println(r.adjSource.toString());
11776                } else {
11777                    pw.println("{null}");
11778                }
11779            }
11780            if (inclDetails) {
11781                pw.print(prefix);
11782                pw.print("    ");
11783                pw.print("oom: max="); pw.print(r.maxAdj);
11784                pw.print(" curRaw="); pw.print(r.curRawAdj);
11785                pw.print(" setRaw="); pw.print(r.setRawAdj);
11786                pw.print(" cur="); pw.print(r.curAdj);
11787                pw.print(" set="); pw.println(r.setAdj);
11788                pw.print(prefix);
11789                pw.print("    ");
11790                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11791                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11792                pw.print(" lastPss="); pw.print(r.lastPss);
11793                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11794                pw.print(prefix);
11795                pw.print("    ");
11796                pw.print("keeping="); pw.print(r.keeping);
11797                pw.print(" cached="); pw.print(r.cached);
11798                pw.print(" empty="); pw.print(r.empty);
11799                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11800
11801                if (!r.keeping) {
11802                    if (r.lastWakeTime != 0) {
11803                        long wtime;
11804                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11805                        synchronized (stats) {
11806                            wtime = stats.getProcessWakeTime(r.info.uid,
11807                                    r.pid, curRealtime);
11808                        }
11809                        long timeUsed = wtime - r.lastWakeTime;
11810                        pw.print(prefix);
11811                        pw.print("    ");
11812                        pw.print("keep awake over ");
11813                        TimeUtils.formatDuration(realtimeSince, pw);
11814                        pw.print(" used ");
11815                        TimeUtils.formatDuration(timeUsed, pw);
11816                        pw.print(" (");
11817                        pw.print((timeUsed*100)/realtimeSince);
11818                        pw.println("%)");
11819                    }
11820                    if (r.lastCpuTime != 0) {
11821                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11822                        pw.print(prefix);
11823                        pw.print("    ");
11824                        pw.print("run cpu over ");
11825                        TimeUtils.formatDuration(uptimeSince, pw);
11826                        pw.print(" used ");
11827                        TimeUtils.formatDuration(timeUsed, pw);
11828                        pw.print(" (");
11829                        pw.print((timeUsed*100)/uptimeSince);
11830                        pw.println("%)");
11831                    }
11832                }
11833            }
11834        }
11835        return true;
11836    }
11837
11838    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11839        ArrayList<ProcessRecord> procs;
11840        synchronized (this) {
11841            if (args != null && args.length > start
11842                    && args[start].charAt(0) != '-') {
11843                procs = new ArrayList<ProcessRecord>();
11844                int pid = -1;
11845                try {
11846                    pid = Integer.parseInt(args[start]);
11847                } catch (NumberFormatException e) {
11848                }
11849                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11850                    ProcessRecord proc = mLruProcesses.get(i);
11851                    if (proc.pid == pid) {
11852                        procs.add(proc);
11853                    } else if (proc.processName.equals(args[start])) {
11854                        procs.add(proc);
11855                    }
11856                }
11857                if (procs.size() <= 0) {
11858                    return null;
11859                }
11860            } else {
11861                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11862            }
11863        }
11864        return procs;
11865    }
11866
11867    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11868            PrintWriter pw, String[] args) {
11869        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11870        if (procs == null) {
11871            pw.println("No process found for: " + args[0]);
11872            return;
11873        }
11874
11875        long uptime = SystemClock.uptimeMillis();
11876        long realtime = SystemClock.elapsedRealtime();
11877        pw.println("Applications Graphics Acceleration Info:");
11878        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11879
11880        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11881            ProcessRecord r = procs.get(i);
11882            if (r.thread != null) {
11883                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11884                pw.flush();
11885                try {
11886                    TransferPipe tp = new TransferPipe();
11887                    try {
11888                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11889                        tp.go(fd);
11890                    } finally {
11891                        tp.kill();
11892                    }
11893                } catch (IOException e) {
11894                    pw.println("Failure while dumping the app: " + r);
11895                    pw.flush();
11896                } catch (RemoteException e) {
11897                    pw.println("Got a RemoteException while dumping the app " + r);
11898                    pw.flush();
11899                }
11900            }
11901        }
11902    }
11903
11904    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11905        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11906        if (procs == null) {
11907            pw.println("No process found for: " + args[0]);
11908            return;
11909        }
11910
11911        pw.println("Applications Database Info:");
11912
11913        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11914            ProcessRecord r = procs.get(i);
11915            if (r.thread != null) {
11916                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11917                pw.flush();
11918                try {
11919                    TransferPipe tp = new TransferPipe();
11920                    try {
11921                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11922                        tp.go(fd);
11923                    } finally {
11924                        tp.kill();
11925                    }
11926                } catch (IOException e) {
11927                    pw.println("Failure while dumping the app: " + r);
11928                    pw.flush();
11929                } catch (RemoteException e) {
11930                    pw.println("Got a RemoteException while dumping the app " + r);
11931                    pw.flush();
11932                }
11933            }
11934        }
11935    }
11936
11937    final static class MemItem {
11938        final boolean isProc;
11939        final String label;
11940        final String shortLabel;
11941        final long pss;
11942        final int id;
11943        final boolean hasActivities;
11944        ArrayList<MemItem> subitems;
11945
11946        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11947                boolean _hasActivities) {
11948            isProc = true;
11949            label = _label;
11950            shortLabel = _shortLabel;
11951            pss = _pss;
11952            id = _id;
11953            hasActivities = _hasActivities;
11954        }
11955
11956        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11957            isProc = false;
11958            label = _label;
11959            shortLabel = _shortLabel;
11960            pss = _pss;
11961            id = _id;
11962            hasActivities = false;
11963        }
11964    }
11965
11966    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11967            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11968        if (sort && !isCompact) {
11969            Collections.sort(items, new Comparator<MemItem>() {
11970                @Override
11971                public int compare(MemItem lhs, MemItem rhs) {
11972                    if (lhs.pss < rhs.pss) {
11973                        return 1;
11974                    } else if (lhs.pss > rhs.pss) {
11975                        return -1;
11976                    }
11977                    return 0;
11978                }
11979            });
11980        }
11981
11982        for (int i=0; i<items.size(); i++) {
11983            MemItem mi = items.get(i);
11984            if (!isCompact) {
11985                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11986            } else if (mi.isProc) {
11987                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11988                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11989                pw.println(mi.hasActivities ? ",a" : ",e");
11990            } else {
11991                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11992                pw.println(mi.pss);
11993            }
11994            if (mi.subitems != null) {
11995                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11996                        true, isCompact);
11997            }
11998        }
11999    }
12000
12001    // These are in KB.
12002    static final long[] DUMP_MEM_BUCKETS = new long[] {
12003        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12004        120*1024, 160*1024, 200*1024,
12005        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12006        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12007    };
12008
12009    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12010            boolean stackLike) {
12011        int start = label.lastIndexOf('.');
12012        if (start >= 0) start++;
12013        else start = 0;
12014        int end = label.length();
12015        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12016            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12017                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12018                out.append(bucket);
12019                out.append(stackLike ? "MB." : "MB ");
12020                out.append(label, start, end);
12021                return;
12022            }
12023        }
12024        out.append(memKB/1024);
12025        out.append(stackLike ? "MB." : "MB ");
12026        out.append(label, start, end);
12027    }
12028
12029    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12030            ProcessList.NATIVE_ADJ,
12031            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12032            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12033            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12034            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12035            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12036    };
12037    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12038            "Native",
12039            "System", "Persistent", "Foreground",
12040            "Visible", "Perceptible",
12041            "Heavy Weight", "Backup",
12042            "A Services", "Home",
12043            "Previous", "B Services", "Cached"
12044    };
12045    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12046            "native",
12047            "sys", "pers", "fore",
12048            "vis", "percept",
12049            "heavy", "backup",
12050            "servicea", "home",
12051            "prev", "serviceb", "cached"
12052    };
12053
12054    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12055            long realtime, boolean isCheckinRequest, boolean isCompact) {
12056        if (isCheckinRequest || isCompact) {
12057            // short checkin version
12058            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12059        } else {
12060            pw.println("Applications Memory Usage (kB):");
12061            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12062        }
12063    }
12064
12065    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12066            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12067        boolean dumpDetails = false;
12068        boolean dumpFullDetails = false;
12069        boolean dumpDalvik = false;
12070        boolean oomOnly = false;
12071        boolean isCompact = false;
12072        boolean localOnly = false;
12073
12074        int opti = 0;
12075        while (opti < args.length) {
12076            String opt = args[opti];
12077            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12078                break;
12079            }
12080            opti++;
12081            if ("-a".equals(opt)) {
12082                dumpDetails = true;
12083                dumpFullDetails = true;
12084                dumpDalvik = true;
12085            } else if ("-d".equals(opt)) {
12086                dumpDalvik = true;
12087            } else if ("-c".equals(opt)) {
12088                isCompact = true;
12089            } else if ("--oom".equals(opt)) {
12090                oomOnly = true;
12091            } else if ("--local".equals(opt)) {
12092                localOnly = true;
12093            } else if ("-h".equals(opt)) {
12094                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12095                pw.println("  -a: include all available information for each process.");
12096                pw.println("  -d: include dalvik details when dumping process details.");
12097                pw.println("  -c: dump in a compact machine-parseable representation.");
12098                pw.println("  --oom: only show processes organized by oom adj.");
12099                pw.println("  --local: only collect details locally, don't call process.");
12100                pw.println("If [process] is specified it can be the name or ");
12101                pw.println("pid of a specific process to dump.");
12102                return;
12103            } else {
12104                pw.println("Unknown argument: " + opt + "; use -h for help");
12105            }
12106        }
12107
12108        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12109        long uptime = SystemClock.uptimeMillis();
12110        long realtime = SystemClock.elapsedRealtime();
12111        final long[] tmpLong = new long[1];
12112
12113        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12114        if (procs == null) {
12115            // No Java processes.  Maybe they want to print a native process.
12116            if (args != null && args.length > opti
12117                    && args[opti].charAt(0) != '-') {
12118                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12119                        = new ArrayList<ProcessCpuTracker.Stats>();
12120                updateCpuStatsNow();
12121                int findPid = -1;
12122                try {
12123                    findPid = Integer.parseInt(args[opti]);
12124                } catch (NumberFormatException e) {
12125                }
12126                synchronized (mProcessCpuThread) {
12127                    final int N = mProcessCpuTracker.countStats();
12128                    for (int i=0; i<N; i++) {
12129                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12130                        if (st.pid == findPid || (st.baseName != null
12131                                && st.baseName.equals(args[opti]))) {
12132                            nativeProcs.add(st);
12133                        }
12134                    }
12135                }
12136                if (nativeProcs.size() > 0) {
12137                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12138                            isCompact);
12139                    Debug.MemoryInfo mi = null;
12140                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12141                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12142                        final int pid = r.pid;
12143                        if (!isCheckinRequest && dumpDetails) {
12144                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12145                        }
12146                        if (mi == null) {
12147                            mi = new Debug.MemoryInfo();
12148                        }
12149                        if (dumpDetails || (!brief && !oomOnly)) {
12150                            Debug.getMemoryInfo(pid, mi);
12151                        } else {
12152                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12153                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12154                        }
12155                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12156                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12157                        if (isCheckinRequest) {
12158                            pw.println();
12159                        }
12160                    }
12161                    return;
12162                }
12163            }
12164            pw.println("No process found for: " + args[opti]);
12165            return;
12166        }
12167
12168        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12169            dumpDetails = true;
12170        }
12171
12172        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12173
12174        String[] innerArgs = new String[args.length-opti];
12175        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12176
12177        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12178        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12179        long nativePss=0, dalvikPss=0, otherPss=0;
12180        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12181
12182        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12183        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12184                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12185
12186        long totalPss = 0;
12187        long cachedPss = 0;
12188
12189        Debug.MemoryInfo mi = null;
12190        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12191            final ProcessRecord r = procs.get(i);
12192            final IApplicationThread thread;
12193            final int pid;
12194            final int oomAdj;
12195            final boolean hasActivities;
12196            synchronized (this) {
12197                thread = r.thread;
12198                pid = r.pid;
12199                oomAdj = r.getSetAdjWithServices();
12200                hasActivities = r.activities.size() > 0;
12201            }
12202            if (thread != null) {
12203                if (!isCheckinRequest && dumpDetails) {
12204                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12205                }
12206                if (mi == null) {
12207                    mi = new Debug.MemoryInfo();
12208                }
12209                if (dumpDetails || (!brief && !oomOnly)) {
12210                    Debug.getMemoryInfo(pid, mi);
12211                } else {
12212                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12213                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12214                }
12215                if (dumpDetails) {
12216                    if (localOnly) {
12217                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12218                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12219                        if (isCheckinRequest) {
12220                            pw.println();
12221                        }
12222                    } else {
12223                        try {
12224                            pw.flush();
12225                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12226                                    dumpDalvik, innerArgs);
12227                        } catch (RemoteException e) {
12228                            if (!isCheckinRequest) {
12229                                pw.println("Got RemoteException!");
12230                                pw.flush();
12231                            }
12232                        }
12233                    }
12234                }
12235
12236                final long myTotalPss = mi.getTotalPss();
12237                final long myTotalUss = mi.getTotalUss();
12238
12239                synchronized (this) {
12240                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12241                        // Record this for posterity if the process has been stable.
12242                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12243                    }
12244                }
12245
12246                if (!isCheckinRequest && mi != null) {
12247                    totalPss += myTotalPss;
12248                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12249                            (hasActivities ? " / activities)" : ")"),
12250                            r.processName, myTotalPss, pid, hasActivities);
12251                    procMems.add(pssItem);
12252                    procMemsMap.put(pid, pssItem);
12253
12254                    nativePss += mi.nativePss;
12255                    dalvikPss += mi.dalvikPss;
12256                    otherPss += mi.otherPss;
12257                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12258                        long mem = mi.getOtherPss(j);
12259                        miscPss[j] += mem;
12260                        otherPss -= mem;
12261                    }
12262
12263                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12264                        cachedPss += myTotalPss;
12265                    }
12266
12267                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12268                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12269                                || oomIndex == (oomPss.length-1)) {
12270                            oomPss[oomIndex] += myTotalPss;
12271                            if (oomProcs[oomIndex] == null) {
12272                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12273                            }
12274                            oomProcs[oomIndex].add(pssItem);
12275                            break;
12276                        }
12277                    }
12278                }
12279            }
12280        }
12281
12282        if (!isCheckinRequest && procs.size() > 1) {
12283            // If we are showing aggregations, also look for native processes to
12284            // include so that our aggregations are more accurate.
12285            updateCpuStatsNow();
12286            synchronized (mProcessCpuThread) {
12287                final int N = mProcessCpuTracker.countStats();
12288                for (int i=0; i<N; i++) {
12289                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12290                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12291                        if (mi == null) {
12292                            mi = new Debug.MemoryInfo();
12293                        }
12294                        if (!brief && !oomOnly) {
12295                            Debug.getMemoryInfo(st.pid, mi);
12296                        } else {
12297                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12298                            mi.nativePrivateDirty = (int)tmpLong[0];
12299                        }
12300
12301                        final long myTotalPss = mi.getTotalPss();
12302                        totalPss += myTotalPss;
12303
12304                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12305                                st.name, myTotalPss, st.pid, false);
12306                        procMems.add(pssItem);
12307
12308                        nativePss += mi.nativePss;
12309                        dalvikPss += mi.dalvikPss;
12310                        otherPss += mi.otherPss;
12311                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12312                            long mem = mi.getOtherPss(j);
12313                            miscPss[j] += mem;
12314                            otherPss -= mem;
12315                        }
12316                        oomPss[0] += myTotalPss;
12317                        if (oomProcs[0] == null) {
12318                            oomProcs[0] = new ArrayList<MemItem>();
12319                        }
12320                        oomProcs[0].add(pssItem);
12321                    }
12322                }
12323            }
12324
12325            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12326
12327            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12328            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12329            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12330            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12331                String label = Debug.MemoryInfo.getOtherLabel(j);
12332                catMems.add(new MemItem(label, label, miscPss[j], j));
12333            }
12334
12335            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12336            for (int j=0; j<oomPss.length; j++) {
12337                if (oomPss[j] != 0) {
12338                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12339                            : DUMP_MEM_OOM_LABEL[j];
12340                    MemItem item = new MemItem(label, label, oomPss[j],
12341                            DUMP_MEM_OOM_ADJ[j]);
12342                    item.subitems = oomProcs[j];
12343                    oomMems.add(item);
12344                }
12345            }
12346
12347            if (!brief && !oomOnly && !isCompact) {
12348                pw.println();
12349                pw.println("Total PSS by process:");
12350                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12351                pw.println();
12352            }
12353            if (!isCompact) {
12354                pw.println("Total PSS by OOM adjustment:");
12355            }
12356            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12357            if (!brief && !oomOnly) {
12358                PrintWriter out = categoryPw != null ? categoryPw : pw;
12359                if (!isCompact) {
12360                    out.println();
12361                    out.println("Total PSS by category:");
12362                }
12363                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12364            }
12365            if (!isCompact) {
12366                pw.println();
12367            }
12368            MemInfoReader memInfo = new MemInfoReader();
12369            memInfo.readMemInfo();
12370            if (!brief) {
12371                if (!isCompact) {
12372                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12373                    pw.print(" kB (status ");
12374                    switch (mLastMemoryLevel) {
12375                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12376                            pw.println("normal)");
12377                            break;
12378                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12379                            pw.println("moderate)");
12380                            break;
12381                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12382                            pw.println("low)");
12383                            break;
12384                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12385                            pw.println("critical)");
12386                            break;
12387                        default:
12388                            pw.print(mLastMemoryLevel);
12389                            pw.println(")");
12390                            break;
12391                    }
12392                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12393                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12394                            pw.print(cachedPss); pw.print(" cached pss + ");
12395                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12396                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12397                } else {
12398                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12399                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12400                            + memInfo.getFreeSizeKb()); pw.print(",");
12401                    pw.println(totalPss - cachedPss);
12402                }
12403            }
12404            if (!isCompact) {
12405                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12406                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12407                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12408                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12409                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12410                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12411                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12412                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12413                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12414                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12415                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12416            }
12417            if (!brief) {
12418                if (memInfo.getZramTotalSizeKb() != 0) {
12419                    if (!isCompact) {
12420                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12421                                pw.print(" kB physical used for ");
12422                                pw.print(memInfo.getSwapTotalSizeKb()
12423                                        - memInfo.getSwapFreeSizeKb());
12424                                pw.print(" kB in swap (");
12425                                pw.print(memInfo.getSwapTotalSizeKb());
12426                                pw.println(" kB total swap)");
12427                    } else {
12428                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12429                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12430                                pw.println(memInfo.getSwapFreeSizeKb());
12431                    }
12432                }
12433                final int[] SINGLE_LONG_FORMAT = new int[] {
12434                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12435                };
12436                long[] longOut = new long[1];
12437                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12438                        SINGLE_LONG_FORMAT, null, longOut, null);
12439                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12440                longOut[0] = 0;
12441                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12442                        SINGLE_LONG_FORMAT, null, longOut, null);
12443                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12444                longOut[0] = 0;
12445                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12446                        SINGLE_LONG_FORMAT, null, longOut, null);
12447                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12448                longOut[0] = 0;
12449                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12450                        SINGLE_LONG_FORMAT, null, longOut, null);
12451                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12452                if (!isCompact) {
12453                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12454                        pw.print("      KSM: "); pw.print(sharing);
12455                                pw.print(" kB saved from shared ");
12456                                pw.print(shared); pw.println(" kB");
12457                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12458                                pw.print(voltile); pw.println(" kB volatile");
12459                    }
12460                    pw.print("   Tuning: ");
12461                    pw.print(ActivityManager.staticGetMemoryClass());
12462                    pw.print(" (large ");
12463                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12464                    pw.print("), oom ");
12465                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12466                    pw.print(" kB");
12467                    pw.print(", restore limit ");
12468                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12469                    pw.print(" kB");
12470                    if (ActivityManager.isLowRamDeviceStatic()) {
12471                        pw.print(" (low-ram)");
12472                    }
12473                    if (ActivityManager.isHighEndGfx()) {
12474                        pw.print(" (high-end-gfx)");
12475                    }
12476                    pw.println();
12477                } else {
12478                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12479                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12480                    pw.println(voltile);
12481                    pw.print("tuning,");
12482                    pw.print(ActivityManager.staticGetMemoryClass());
12483                    pw.print(',');
12484                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12485                    pw.print(',');
12486                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12487                    if (ActivityManager.isLowRamDeviceStatic()) {
12488                        pw.print(",low-ram");
12489                    }
12490                    if (ActivityManager.isHighEndGfx()) {
12491                        pw.print(",high-end-gfx");
12492                    }
12493                    pw.println();
12494                }
12495            }
12496        }
12497    }
12498
12499    /**
12500     * Searches array of arguments for the specified string
12501     * @param args array of argument strings
12502     * @param value value to search for
12503     * @return true if the value is contained in the array
12504     */
12505    private static boolean scanArgs(String[] args, String value) {
12506        if (args != null) {
12507            for (String arg : args) {
12508                if (value.equals(arg)) {
12509                    return true;
12510                }
12511            }
12512        }
12513        return false;
12514    }
12515
12516    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12517            ContentProviderRecord cpr, boolean always) {
12518        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12519
12520        if (!inLaunching || always) {
12521            synchronized (cpr) {
12522                cpr.launchingApp = null;
12523                cpr.notifyAll();
12524            }
12525            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12526            String names[] = cpr.info.authority.split(";");
12527            for (int j = 0; j < names.length; j++) {
12528                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12529            }
12530        }
12531
12532        for (int i=0; i<cpr.connections.size(); i++) {
12533            ContentProviderConnection conn = cpr.connections.get(i);
12534            if (conn.waiting) {
12535                // If this connection is waiting for the provider, then we don't
12536                // need to mess with its process unless we are always removing
12537                // or for some reason the provider is not currently launching.
12538                if (inLaunching && !always) {
12539                    continue;
12540                }
12541            }
12542            ProcessRecord capp = conn.client;
12543            conn.dead = true;
12544            if (conn.stableCount > 0) {
12545                if (!capp.persistent && capp.thread != null
12546                        && capp.pid != 0
12547                        && capp.pid != MY_PID) {
12548                    killUnneededProcessLocked(capp, "depends on provider "
12549                            + cpr.name.flattenToShortString()
12550                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12551                }
12552            } else if (capp.thread != null && conn.provider.provider != null) {
12553                try {
12554                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12555                } catch (RemoteException e) {
12556                }
12557                // In the protocol here, we don't expect the client to correctly
12558                // clean up this connection, we'll just remove it.
12559                cpr.connections.remove(i);
12560                conn.client.conProviders.remove(conn);
12561            }
12562        }
12563
12564        if (inLaunching && always) {
12565            mLaunchingProviders.remove(cpr);
12566        }
12567        return inLaunching;
12568    }
12569
12570    /**
12571     * Main code for cleaning up a process when it has gone away.  This is
12572     * called both as a result of the process dying, or directly when stopping
12573     * a process when running in single process mode.
12574     */
12575    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12576            boolean restarting, boolean allowRestart, int index) {
12577        if (index >= 0) {
12578            removeLruProcessLocked(app);
12579            ProcessList.remove(app.pid);
12580        }
12581
12582        mProcessesToGc.remove(app);
12583        mPendingPssProcesses.remove(app);
12584
12585        // Dismiss any open dialogs.
12586        if (app.crashDialog != null && !app.forceCrashReport) {
12587            app.crashDialog.dismiss();
12588            app.crashDialog = null;
12589        }
12590        if (app.anrDialog != null) {
12591            app.anrDialog.dismiss();
12592            app.anrDialog = null;
12593        }
12594        if (app.waitDialog != null) {
12595            app.waitDialog.dismiss();
12596            app.waitDialog = null;
12597        }
12598
12599        app.crashing = false;
12600        app.notResponding = false;
12601
12602        app.resetPackageList(mProcessStats);
12603        app.unlinkDeathRecipient();
12604        app.makeInactive(mProcessStats);
12605        app.forcingToForeground = null;
12606        updateProcessForegroundLocked(app, false, false);
12607        app.foregroundActivities = false;
12608        app.hasShownUi = false;
12609        app.treatLikeActivity = false;
12610        app.hasAboveClient = false;
12611        app.hasClientActivities = false;
12612
12613        mServices.killServicesLocked(app, allowRestart);
12614
12615        boolean restart = false;
12616
12617        // Remove published content providers.
12618        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12619            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12620            final boolean always = app.bad || !allowRestart;
12621            if (removeDyingProviderLocked(app, cpr, always) || always) {
12622                // We left the provider in the launching list, need to
12623                // restart it.
12624                restart = true;
12625            }
12626
12627            cpr.provider = null;
12628            cpr.proc = null;
12629        }
12630        app.pubProviders.clear();
12631
12632        // Take care of any launching providers waiting for this process.
12633        if (checkAppInLaunchingProvidersLocked(app, false)) {
12634            restart = true;
12635        }
12636
12637        // Unregister from connected content providers.
12638        if (!app.conProviders.isEmpty()) {
12639            for (int i=0; i<app.conProviders.size(); i++) {
12640                ContentProviderConnection conn = app.conProviders.get(i);
12641                conn.provider.connections.remove(conn);
12642            }
12643            app.conProviders.clear();
12644        }
12645
12646        // At this point there may be remaining entries in mLaunchingProviders
12647        // where we were the only one waiting, so they are no longer of use.
12648        // Look for these and clean up if found.
12649        // XXX Commented out for now.  Trying to figure out a way to reproduce
12650        // the actual situation to identify what is actually going on.
12651        if (false) {
12652            for (int i=0; i<mLaunchingProviders.size(); i++) {
12653                ContentProviderRecord cpr = (ContentProviderRecord)
12654                        mLaunchingProviders.get(i);
12655                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12656                    synchronized (cpr) {
12657                        cpr.launchingApp = null;
12658                        cpr.notifyAll();
12659                    }
12660                }
12661            }
12662        }
12663
12664        skipCurrentReceiverLocked(app);
12665
12666        // Unregister any receivers.
12667        for (int i=app.receivers.size()-1; i>=0; i--) {
12668            removeReceiverLocked(app.receivers.valueAt(i));
12669        }
12670        app.receivers.clear();
12671
12672        // If the app is undergoing backup, tell the backup manager about it
12673        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12674            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12675                    + mBackupTarget.appInfo + " died during backup");
12676            try {
12677                IBackupManager bm = IBackupManager.Stub.asInterface(
12678                        ServiceManager.getService(Context.BACKUP_SERVICE));
12679                bm.agentDisconnected(app.info.packageName);
12680            } catch (RemoteException e) {
12681                // can't happen; backup manager is local
12682            }
12683        }
12684
12685        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12686            ProcessChangeItem item = mPendingProcessChanges.get(i);
12687            if (item.pid == app.pid) {
12688                mPendingProcessChanges.remove(i);
12689                mAvailProcessChanges.add(item);
12690            }
12691        }
12692        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12693
12694        // If the caller is restarting this app, then leave it in its
12695        // current lists and let the caller take care of it.
12696        if (restarting) {
12697            return;
12698        }
12699
12700        if (!app.persistent || app.isolated) {
12701            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12702                    "Removing non-persistent process during cleanup: " + app);
12703            mProcessNames.remove(app.processName, app.uid);
12704            mIsolatedProcesses.remove(app.uid);
12705            if (mHeavyWeightProcess == app) {
12706                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12707                        mHeavyWeightProcess.userId, 0));
12708                mHeavyWeightProcess = null;
12709            }
12710        } else if (!app.removed) {
12711            // This app is persistent, so we need to keep its record around.
12712            // If it is not already on the pending app list, add it there
12713            // and start a new process for it.
12714            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12715                mPersistentStartingProcesses.add(app);
12716                restart = true;
12717            }
12718        }
12719        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12720                "Clean-up removing on hold: " + app);
12721        mProcessesOnHold.remove(app);
12722
12723        if (app == mHomeProcess) {
12724            mHomeProcess = null;
12725        }
12726        if (app == mPreviousProcess) {
12727            mPreviousProcess = null;
12728        }
12729
12730        if (restart && !app.isolated) {
12731            // We have components that still need to be running in the
12732            // process, so re-launch it.
12733            mProcessNames.put(app.processName, app.uid, app);
12734            startProcessLocked(app, "restart", app.processName);
12735        } else if (app.pid > 0 && app.pid != MY_PID) {
12736            // Goodbye!
12737            boolean removed;
12738            synchronized (mPidsSelfLocked) {
12739                mPidsSelfLocked.remove(app.pid);
12740                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12741            }
12742            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12743                    app.processName, app.info.uid);
12744            if (app.isolated) {
12745                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12746            }
12747            app.setPid(0);
12748        }
12749    }
12750
12751    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12752        // Look through the content providers we are waiting to have launched,
12753        // and if any run in this process then either schedule a restart of
12754        // the process or kill the client waiting for it if this process has
12755        // gone bad.
12756        int NL = mLaunchingProviders.size();
12757        boolean restart = false;
12758        for (int i=0; i<NL; i++) {
12759            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12760            if (cpr.launchingApp == app) {
12761                if (!alwaysBad && !app.bad) {
12762                    restart = true;
12763                } else {
12764                    removeDyingProviderLocked(app, cpr, true);
12765                    // cpr should have been removed from mLaunchingProviders
12766                    NL = mLaunchingProviders.size();
12767                    i--;
12768                }
12769            }
12770        }
12771        return restart;
12772    }
12773
12774    // =========================================================
12775    // SERVICES
12776    // =========================================================
12777
12778    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12779            int flags) {
12780        enforceNotIsolatedCaller("getServices");
12781        synchronized (this) {
12782            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12783        }
12784    }
12785
12786    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12787        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12788        synchronized (this) {
12789            return mServices.getRunningServiceControlPanelLocked(name);
12790        }
12791    }
12792
12793    public ComponentName startService(IApplicationThread caller, Intent service,
12794            String resolvedType, int userId) {
12795        enforceNotIsolatedCaller("startService");
12796        // Refuse possible leaked file descriptors
12797        if (service != null && service.hasFileDescriptors() == true) {
12798            throw new IllegalArgumentException("File descriptors passed in Intent");
12799        }
12800
12801        if (DEBUG_SERVICE)
12802            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12803        synchronized(this) {
12804            final int callingPid = Binder.getCallingPid();
12805            final int callingUid = Binder.getCallingUid();
12806            final long origId = Binder.clearCallingIdentity();
12807            ComponentName res = mServices.startServiceLocked(caller, service,
12808                    resolvedType, callingPid, callingUid, userId);
12809            Binder.restoreCallingIdentity(origId);
12810            return res;
12811        }
12812    }
12813
12814    ComponentName startServiceInPackage(int uid,
12815            Intent service, String resolvedType, int userId) {
12816        synchronized(this) {
12817            if (DEBUG_SERVICE)
12818                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12819            final long origId = Binder.clearCallingIdentity();
12820            ComponentName res = mServices.startServiceLocked(null, service,
12821                    resolvedType, -1, uid, userId);
12822            Binder.restoreCallingIdentity(origId);
12823            return res;
12824        }
12825    }
12826
12827    public int stopService(IApplicationThread caller, Intent service,
12828            String resolvedType, int userId) {
12829        enforceNotIsolatedCaller("stopService");
12830        // Refuse possible leaked file descriptors
12831        if (service != null && service.hasFileDescriptors() == true) {
12832            throw new IllegalArgumentException("File descriptors passed in Intent");
12833        }
12834
12835        synchronized(this) {
12836            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12837        }
12838    }
12839
12840    public IBinder peekService(Intent service, String resolvedType) {
12841        enforceNotIsolatedCaller("peekService");
12842        // Refuse possible leaked file descriptors
12843        if (service != null && service.hasFileDescriptors() == true) {
12844            throw new IllegalArgumentException("File descriptors passed in Intent");
12845        }
12846        synchronized(this) {
12847            return mServices.peekServiceLocked(service, resolvedType);
12848        }
12849    }
12850
12851    public boolean stopServiceToken(ComponentName className, IBinder token,
12852            int startId) {
12853        synchronized(this) {
12854            return mServices.stopServiceTokenLocked(className, token, startId);
12855        }
12856    }
12857
12858    public void setServiceForeground(ComponentName className, IBinder token,
12859            int id, Notification notification, boolean removeNotification) {
12860        synchronized(this) {
12861            mServices.setServiceForegroundLocked(className, token, id, notification,
12862                    removeNotification);
12863        }
12864    }
12865
12866    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12867            boolean requireFull, String name, String callerPackage) {
12868        final int callingUserId = UserHandle.getUserId(callingUid);
12869        if (callingUserId != userId) {
12870            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12871                if ((requireFull || checkComponentPermission(
12872                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12873                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12874                        && checkComponentPermission(
12875                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12876                                callingPid, callingUid, -1, true)
12877                                != PackageManager.PERMISSION_GRANTED) {
12878                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12879                        // In this case, they would like to just execute as their
12880                        // owner user instead of failing.
12881                        userId = callingUserId;
12882                    } else {
12883                        StringBuilder builder = new StringBuilder(128);
12884                        builder.append("Permission Denial: ");
12885                        builder.append(name);
12886                        if (callerPackage != null) {
12887                            builder.append(" from ");
12888                            builder.append(callerPackage);
12889                        }
12890                        builder.append(" asks to run as user ");
12891                        builder.append(userId);
12892                        builder.append(" but is calling from user ");
12893                        builder.append(UserHandle.getUserId(callingUid));
12894                        builder.append("; this requires ");
12895                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12896                        if (!requireFull) {
12897                            builder.append(" or ");
12898                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12899                        }
12900                        String msg = builder.toString();
12901                        Slog.w(TAG, msg);
12902                        throw new SecurityException(msg);
12903                    }
12904                }
12905            }
12906            if (userId == UserHandle.USER_CURRENT
12907                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12908                // Note that we may be accessing this outside of a lock...
12909                // shouldn't be a big deal, if this is being called outside
12910                // of a locked context there is intrinsically a race with
12911                // the value the caller will receive and someone else changing it.
12912                userId = mCurrentUserId;
12913            }
12914            if (!allowAll && userId < 0) {
12915                throw new IllegalArgumentException(
12916                        "Call does not support special user #" + userId);
12917            }
12918        }
12919        return userId;
12920    }
12921
12922    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12923            String className, int flags) {
12924        boolean result = false;
12925        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12926            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12927                if (ActivityManager.checkUidPermission(
12928                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12929                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12930                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12931                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12932                            + " requests FLAG_SINGLE_USER, but app does not hold "
12933                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12934                    Slog.w(TAG, msg);
12935                    throw new SecurityException(msg);
12936                }
12937                result = true;
12938            }
12939        } else if (componentProcessName == aInfo.packageName) {
12940            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12941        } else if ("system".equals(componentProcessName)) {
12942            result = true;
12943        }
12944        if (DEBUG_MU) {
12945            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12946                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12947        }
12948        return result;
12949    }
12950
12951    public int bindService(IApplicationThread caller, IBinder token,
12952            Intent service, String resolvedType,
12953            IServiceConnection connection, int flags, int userId) {
12954        enforceNotIsolatedCaller("bindService");
12955        // Refuse possible leaked file descriptors
12956        if (service != null && service.hasFileDescriptors() == true) {
12957            throw new IllegalArgumentException("File descriptors passed in Intent");
12958        }
12959
12960        synchronized(this) {
12961            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12962                    connection, flags, userId);
12963        }
12964    }
12965
12966    public boolean unbindService(IServiceConnection connection) {
12967        synchronized (this) {
12968            return mServices.unbindServiceLocked(connection);
12969        }
12970    }
12971
12972    public void publishService(IBinder token, Intent intent, IBinder service) {
12973        // Refuse possible leaked file descriptors
12974        if (intent != null && intent.hasFileDescriptors() == true) {
12975            throw new IllegalArgumentException("File descriptors passed in Intent");
12976        }
12977
12978        synchronized(this) {
12979            if (!(token instanceof ServiceRecord)) {
12980                throw new IllegalArgumentException("Invalid service token");
12981            }
12982            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12983        }
12984    }
12985
12986    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12987        // Refuse possible leaked file descriptors
12988        if (intent != null && intent.hasFileDescriptors() == true) {
12989            throw new IllegalArgumentException("File descriptors passed in Intent");
12990        }
12991
12992        synchronized(this) {
12993            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12994        }
12995    }
12996
12997    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12998        synchronized(this) {
12999            if (!(token instanceof ServiceRecord)) {
13000                throw new IllegalArgumentException("Invalid service token");
13001            }
13002            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13003        }
13004    }
13005
13006    // =========================================================
13007    // BACKUP AND RESTORE
13008    // =========================================================
13009
13010    // Cause the target app to be launched if necessary and its backup agent
13011    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13012    // activity manager to announce its creation.
13013    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13014        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13015        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13016
13017        synchronized(this) {
13018            // !!! TODO: currently no check here that we're already bound
13019            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13020            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13021            synchronized (stats) {
13022                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13023            }
13024
13025            // Backup agent is now in use, its package can't be stopped.
13026            try {
13027                AppGlobals.getPackageManager().setPackageStoppedState(
13028                        app.packageName, false, UserHandle.getUserId(app.uid));
13029            } catch (RemoteException e) {
13030            } catch (IllegalArgumentException e) {
13031                Slog.w(TAG, "Failed trying to unstop package "
13032                        + app.packageName + ": " + e);
13033            }
13034
13035            BackupRecord r = new BackupRecord(ss, app, backupMode);
13036            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13037                    ? new ComponentName(app.packageName, app.backupAgentName)
13038                    : new ComponentName("android", "FullBackupAgent");
13039            // startProcessLocked() returns existing proc's record if it's already running
13040            ProcessRecord proc = startProcessLocked(app.processName, app,
13041                    false, 0, "backup", hostingName, false, false, false);
13042            if (proc == null) {
13043                Slog.e(TAG, "Unable to start backup agent process " + r);
13044                return false;
13045            }
13046
13047            r.app = proc;
13048            mBackupTarget = r;
13049            mBackupAppName = app.packageName;
13050
13051            // Try not to kill the process during backup
13052            updateOomAdjLocked(proc);
13053
13054            // If the process is already attached, schedule the creation of the backup agent now.
13055            // If it is not yet live, this will be done when it attaches to the framework.
13056            if (proc.thread != null) {
13057                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13058                try {
13059                    proc.thread.scheduleCreateBackupAgent(app,
13060                            compatibilityInfoForPackageLocked(app), backupMode);
13061                } catch (RemoteException e) {
13062                    // Will time out on the backup manager side
13063                }
13064            } else {
13065                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13066            }
13067            // Invariants: at this point, the target app process exists and the application
13068            // is either already running or in the process of coming up.  mBackupTarget and
13069            // mBackupAppName describe the app, so that when it binds back to the AM we
13070            // know that it's scheduled for a backup-agent operation.
13071        }
13072
13073        return true;
13074    }
13075
13076    @Override
13077    public void clearPendingBackup() {
13078        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13079        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13080
13081        synchronized (this) {
13082            mBackupTarget = null;
13083            mBackupAppName = null;
13084        }
13085    }
13086
13087    // A backup agent has just come up
13088    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13089        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13090                + " = " + agent);
13091
13092        synchronized(this) {
13093            if (!agentPackageName.equals(mBackupAppName)) {
13094                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13095                return;
13096            }
13097        }
13098
13099        long oldIdent = Binder.clearCallingIdentity();
13100        try {
13101            IBackupManager bm = IBackupManager.Stub.asInterface(
13102                    ServiceManager.getService(Context.BACKUP_SERVICE));
13103            bm.agentConnected(agentPackageName, agent);
13104        } catch (RemoteException e) {
13105            // can't happen; the backup manager service is local
13106        } catch (Exception e) {
13107            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13108            e.printStackTrace();
13109        } finally {
13110            Binder.restoreCallingIdentity(oldIdent);
13111        }
13112    }
13113
13114    // done with this agent
13115    public void unbindBackupAgent(ApplicationInfo appInfo) {
13116        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13117        if (appInfo == null) {
13118            Slog.w(TAG, "unbind backup agent for null app");
13119            return;
13120        }
13121
13122        synchronized(this) {
13123            try {
13124                if (mBackupAppName == null) {
13125                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13126                    return;
13127                }
13128
13129                if (!mBackupAppName.equals(appInfo.packageName)) {
13130                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13131                    return;
13132                }
13133
13134                // Not backing this app up any more; reset its OOM adjustment
13135                final ProcessRecord proc = mBackupTarget.app;
13136                updateOomAdjLocked(proc);
13137
13138                // If the app crashed during backup, 'thread' will be null here
13139                if (proc.thread != null) {
13140                    try {
13141                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13142                                compatibilityInfoForPackageLocked(appInfo));
13143                    } catch (Exception e) {
13144                        Slog.e(TAG, "Exception when unbinding backup agent:");
13145                        e.printStackTrace();
13146                    }
13147                }
13148            } finally {
13149                mBackupTarget = null;
13150                mBackupAppName = null;
13151            }
13152        }
13153    }
13154    // =========================================================
13155    // BROADCASTS
13156    // =========================================================
13157
13158    private final List getStickiesLocked(String action, IntentFilter filter,
13159            List cur, int userId) {
13160        final ContentResolver resolver = mContext.getContentResolver();
13161        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13162        if (stickies == null) {
13163            return cur;
13164        }
13165        final ArrayList<Intent> list = stickies.get(action);
13166        if (list == null) {
13167            return cur;
13168        }
13169        int N = list.size();
13170        for (int i=0; i<N; i++) {
13171            Intent intent = list.get(i);
13172            if (filter.match(resolver, intent, true, TAG) >= 0) {
13173                if (cur == null) {
13174                    cur = new ArrayList<Intent>();
13175                }
13176                cur.add(intent);
13177            }
13178        }
13179        return cur;
13180    }
13181
13182    boolean isPendingBroadcastProcessLocked(int pid) {
13183        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13184                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13185    }
13186
13187    void skipPendingBroadcastLocked(int pid) {
13188            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13189            for (BroadcastQueue queue : mBroadcastQueues) {
13190                queue.skipPendingBroadcastLocked(pid);
13191            }
13192    }
13193
13194    // The app just attached; send any pending broadcasts that it should receive
13195    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13196        boolean didSomething = false;
13197        for (BroadcastQueue queue : mBroadcastQueues) {
13198            didSomething |= queue.sendPendingBroadcastsLocked(app);
13199        }
13200        return didSomething;
13201    }
13202
13203    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13204            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13205        enforceNotIsolatedCaller("registerReceiver");
13206        int callingUid;
13207        int callingPid;
13208        synchronized(this) {
13209            ProcessRecord callerApp = null;
13210            if (caller != null) {
13211                callerApp = getRecordForAppLocked(caller);
13212                if (callerApp == null) {
13213                    throw new SecurityException(
13214                            "Unable to find app for caller " + caller
13215                            + " (pid=" + Binder.getCallingPid()
13216                            + ") when registering receiver " + receiver);
13217                }
13218                if (callerApp.info.uid != Process.SYSTEM_UID &&
13219                        !callerApp.pkgList.containsKey(callerPackage) &&
13220                        !"android".equals(callerPackage)) {
13221                    throw new SecurityException("Given caller package " + callerPackage
13222                            + " is not running in process " + callerApp);
13223                }
13224                callingUid = callerApp.info.uid;
13225                callingPid = callerApp.pid;
13226            } else {
13227                callerPackage = null;
13228                callingUid = Binder.getCallingUid();
13229                callingPid = Binder.getCallingPid();
13230            }
13231
13232            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13233                    true, true, "registerReceiver", callerPackage);
13234
13235            List allSticky = null;
13236
13237            // Look for any matching sticky broadcasts...
13238            Iterator actions = filter.actionsIterator();
13239            if (actions != null) {
13240                while (actions.hasNext()) {
13241                    String action = (String)actions.next();
13242                    allSticky = getStickiesLocked(action, filter, allSticky,
13243                            UserHandle.USER_ALL);
13244                    allSticky = getStickiesLocked(action, filter, allSticky,
13245                            UserHandle.getUserId(callingUid));
13246                }
13247            } else {
13248                allSticky = getStickiesLocked(null, filter, allSticky,
13249                        UserHandle.USER_ALL);
13250                allSticky = getStickiesLocked(null, filter, allSticky,
13251                        UserHandle.getUserId(callingUid));
13252            }
13253
13254            // The first sticky in the list is returned directly back to
13255            // the client.
13256            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13257
13258            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13259                    + ": " + sticky);
13260
13261            if (receiver == null) {
13262                return sticky;
13263            }
13264
13265            ReceiverList rl
13266                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13267            if (rl == null) {
13268                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13269                        userId, receiver);
13270                if (rl.app != null) {
13271                    rl.app.receivers.add(rl);
13272                } else {
13273                    try {
13274                        receiver.asBinder().linkToDeath(rl, 0);
13275                    } catch (RemoteException e) {
13276                        return sticky;
13277                    }
13278                    rl.linkedToDeath = true;
13279                }
13280                mRegisteredReceivers.put(receiver.asBinder(), rl);
13281            } else if (rl.uid != callingUid) {
13282                throw new IllegalArgumentException(
13283                        "Receiver requested to register for uid " + callingUid
13284                        + " was previously registered for uid " + rl.uid);
13285            } else if (rl.pid != callingPid) {
13286                throw new IllegalArgumentException(
13287                        "Receiver requested to register for pid " + callingPid
13288                        + " was previously registered for pid " + rl.pid);
13289            } else if (rl.userId != userId) {
13290                throw new IllegalArgumentException(
13291                        "Receiver requested to register for user " + userId
13292                        + " was previously registered for user " + rl.userId);
13293            }
13294            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13295                    permission, callingUid, userId);
13296            rl.add(bf);
13297            if (!bf.debugCheck()) {
13298                Slog.w(TAG, "==> For Dynamic broadast");
13299            }
13300            mReceiverResolver.addFilter(bf);
13301
13302            // Enqueue broadcasts for all existing stickies that match
13303            // this filter.
13304            if (allSticky != null) {
13305                ArrayList receivers = new ArrayList();
13306                receivers.add(bf);
13307
13308                int N = allSticky.size();
13309                for (int i=0; i<N; i++) {
13310                    Intent intent = (Intent)allSticky.get(i);
13311                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13312                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13313                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13314                            null, null, false, true, true, -1);
13315                    queue.enqueueParallelBroadcastLocked(r);
13316                    queue.scheduleBroadcastsLocked();
13317                }
13318            }
13319
13320            return sticky;
13321        }
13322    }
13323
13324    public void unregisterReceiver(IIntentReceiver receiver) {
13325        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13326
13327        final long origId = Binder.clearCallingIdentity();
13328        try {
13329            boolean doTrim = false;
13330
13331            synchronized(this) {
13332                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13333                if (rl != null) {
13334                    if (rl.curBroadcast != null) {
13335                        BroadcastRecord r = rl.curBroadcast;
13336                        final boolean doNext = finishReceiverLocked(
13337                                receiver.asBinder(), r.resultCode, r.resultData,
13338                                r.resultExtras, r.resultAbort);
13339                        if (doNext) {
13340                            doTrim = true;
13341                            r.queue.processNextBroadcast(false);
13342                        }
13343                    }
13344
13345                    if (rl.app != null) {
13346                        rl.app.receivers.remove(rl);
13347                    }
13348                    removeReceiverLocked(rl);
13349                    if (rl.linkedToDeath) {
13350                        rl.linkedToDeath = false;
13351                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13352                    }
13353                }
13354            }
13355
13356            // If we actually concluded any broadcasts, we might now be able
13357            // to trim the recipients' apps from our working set
13358            if (doTrim) {
13359                trimApplications();
13360                return;
13361            }
13362
13363        } finally {
13364            Binder.restoreCallingIdentity(origId);
13365        }
13366    }
13367
13368    void removeReceiverLocked(ReceiverList rl) {
13369        mRegisteredReceivers.remove(rl.receiver.asBinder());
13370        int N = rl.size();
13371        for (int i=0; i<N; i++) {
13372            mReceiverResolver.removeFilter(rl.get(i));
13373        }
13374    }
13375
13376    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13377        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13378            ProcessRecord r = mLruProcesses.get(i);
13379            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13380                try {
13381                    r.thread.dispatchPackageBroadcast(cmd, packages);
13382                } catch (RemoteException ex) {
13383                }
13384            }
13385        }
13386    }
13387
13388    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13389            int[] users) {
13390        List<ResolveInfo> receivers = null;
13391        try {
13392            HashSet<ComponentName> singleUserReceivers = null;
13393            boolean scannedFirstReceivers = false;
13394            for (int user : users) {
13395                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13396                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13397                if (user != 0 && newReceivers != null) {
13398                    // If this is not the primary user, we need to check for
13399                    // any receivers that should be filtered out.
13400                    for (int i=0; i<newReceivers.size(); i++) {
13401                        ResolveInfo ri = newReceivers.get(i);
13402                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13403                            newReceivers.remove(i);
13404                            i--;
13405                        }
13406                    }
13407                }
13408                if (newReceivers != null && newReceivers.size() == 0) {
13409                    newReceivers = null;
13410                }
13411                if (receivers == null) {
13412                    receivers = newReceivers;
13413                } else if (newReceivers != null) {
13414                    // We need to concatenate the additional receivers
13415                    // found with what we have do far.  This would be easy,
13416                    // but we also need to de-dup any receivers that are
13417                    // singleUser.
13418                    if (!scannedFirstReceivers) {
13419                        // Collect any single user receivers we had already retrieved.
13420                        scannedFirstReceivers = true;
13421                        for (int i=0; i<receivers.size(); i++) {
13422                            ResolveInfo ri = receivers.get(i);
13423                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13424                                ComponentName cn = new ComponentName(
13425                                        ri.activityInfo.packageName, ri.activityInfo.name);
13426                                if (singleUserReceivers == null) {
13427                                    singleUserReceivers = new HashSet<ComponentName>();
13428                                }
13429                                singleUserReceivers.add(cn);
13430                            }
13431                        }
13432                    }
13433                    // Add the new results to the existing results, tracking
13434                    // and de-dupping single user receivers.
13435                    for (int i=0; i<newReceivers.size(); i++) {
13436                        ResolveInfo ri = newReceivers.get(i);
13437                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13438                            ComponentName cn = new ComponentName(
13439                                    ri.activityInfo.packageName, ri.activityInfo.name);
13440                            if (singleUserReceivers == null) {
13441                                singleUserReceivers = new HashSet<ComponentName>();
13442                            }
13443                            if (!singleUserReceivers.contains(cn)) {
13444                                singleUserReceivers.add(cn);
13445                                receivers.add(ri);
13446                            }
13447                        } else {
13448                            receivers.add(ri);
13449                        }
13450                    }
13451                }
13452            }
13453        } catch (RemoteException ex) {
13454            // pm is in same process, this will never happen.
13455        }
13456        return receivers;
13457    }
13458
13459    private final int broadcastIntentLocked(ProcessRecord callerApp,
13460            String callerPackage, Intent intent, String resolvedType,
13461            IIntentReceiver resultTo, int resultCode, String resultData,
13462            Bundle map, String requiredPermission, int appOp,
13463            boolean ordered, boolean sticky, int callingPid, int callingUid,
13464            int userId) {
13465        intent = new Intent(intent);
13466
13467        // By default broadcasts do not go to stopped apps.
13468        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13469
13470        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13471            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13472            + " ordered=" + ordered + " userid=" + userId);
13473        if ((resultTo != null) && !ordered) {
13474            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13475        }
13476
13477        userId = handleIncomingUser(callingPid, callingUid, userId,
13478                true, false, "broadcast", callerPackage);
13479
13480        // Make sure that the user who is receiving this broadcast is started.
13481        // If not, we will just skip it.
13482        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13483            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13484                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13485                Slog.w(TAG, "Skipping broadcast of " + intent
13486                        + ": user " + userId + " is stopped");
13487                return ActivityManager.BROADCAST_SUCCESS;
13488            }
13489        }
13490
13491        /*
13492         * Prevent non-system code (defined here to be non-persistent
13493         * processes) from sending protected broadcasts.
13494         */
13495        int callingAppId = UserHandle.getAppId(callingUid);
13496        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13497            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13498            callingUid == 0) {
13499            // Always okay.
13500        } else if (callerApp == null || !callerApp.persistent) {
13501            try {
13502                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13503                        intent.getAction())) {
13504                    String msg = "Permission Denial: not allowed to send broadcast "
13505                            + intent.getAction() + " from pid="
13506                            + callingPid + ", uid=" + callingUid;
13507                    Slog.w(TAG, msg);
13508                    throw new SecurityException(msg);
13509                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13510                    // Special case for compatibility: we don't want apps to send this,
13511                    // but historically it has not been protected and apps may be using it
13512                    // to poke their own app widget.  So, instead of making it protected,
13513                    // just limit it to the caller.
13514                    if (callerApp == null) {
13515                        String msg = "Permission Denial: not allowed to send broadcast "
13516                                + intent.getAction() + " from unknown caller.";
13517                        Slog.w(TAG, msg);
13518                        throw new SecurityException(msg);
13519                    } else if (intent.getComponent() != null) {
13520                        // They are good enough to send to an explicit component...  verify
13521                        // it is being sent to the calling app.
13522                        if (!intent.getComponent().getPackageName().equals(
13523                                callerApp.info.packageName)) {
13524                            String msg = "Permission Denial: not allowed to send broadcast "
13525                                    + intent.getAction() + " to "
13526                                    + intent.getComponent().getPackageName() + " from "
13527                                    + callerApp.info.packageName;
13528                            Slog.w(TAG, msg);
13529                            throw new SecurityException(msg);
13530                        }
13531                    } else {
13532                        // Limit broadcast to their own package.
13533                        intent.setPackage(callerApp.info.packageName);
13534                    }
13535                }
13536            } catch (RemoteException e) {
13537                Slog.w(TAG, "Remote exception", e);
13538                return ActivityManager.BROADCAST_SUCCESS;
13539            }
13540        }
13541
13542        // Handle special intents: if this broadcast is from the package
13543        // manager about a package being removed, we need to remove all of
13544        // its activities from the history stack.
13545        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13546                intent.getAction());
13547        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13548                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13549                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13550                || uidRemoved) {
13551            if (checkComponentPermission(
13552                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13553                    callingPid, callingUid, -1, true)
13554                    == PackageManager.PERMISSION_GRANTED) {
13555                if (uidRemoved) {
13556                    final Bundle intentExtras = intent.getExtras();
13557                    final int uid = intentExtras != null
13558                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13559                    if (uid >= 0) {
13560                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13561                        synchronized (bs) {
13562                            bs.removeUidStatsLocked(uid);
13563                        }
13564                        mAppOpsService.uidRemoved(uid);
13565                    }
13566                } else {
13567                    // If resources are unavailable just force stop all
13568                    // those packages and flush the attribute cache as well.
13569                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13570                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13571                        if (list != null && (list.length > 0)) {
13572                            for (String pkg : list) {
13573                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13574                                        "storage unmount");
13575                            }
13576                            sendPackageBroadcastLocked(
13577                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13578                        }
13579                    } else {
13580                        Uri data = intent.getData();
13581                        String ssp;
13582                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13583                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13584                                    intent.getAction());
13585                            boolean fullUninstall = removed &&
13586                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13587                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13588                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13589                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13590                                        false, fullUninstall, userId,
13591                                        removed ? "pkg removed" : "pkg changed");
13592                            }
13593                            if (removed) {
13594                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13595                                        new String[] {ssp}, userId);
13596                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13597                                    mAppOpsService.packageRemoved(
13598                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13599
13600                                    // Remove all permissions granted from/to this package
13601                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13602                                }
13603                            }
13604                        }
13605                    }
13606                }
13607            } else {
13608                String msg = "Permission Denial: " + intent.getAction()
13609                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13610                        + ", uid=" + callingUid + ")"
13611                        + " requires "
13612                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13613                Slog.w(TAG, msg);
13614                throw new SecurityException(msg);
13615            }
13616
13617        // Special case for adding a package: by default turn on compatibility
13618        // mode.
13619        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13620            Uri data = intent.getData();
13621            String ssp;
13622            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13623                mCompatModePackages.handlePackageAddedLocked(ssp,
13624                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13625            }
13626        }
13627
13628        /*
13629         * If this is the time zone changed action, queue up a message that will reset the timezone
13630         * of all currently running processes. This message will get queued up before the broadcast
13631         * happens.
13632         */
13633        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13634            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13635        }
13636
13637        /*
13638         * If the user set the time, let all running processes know.
13639         */
13640        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13641            final int is24Hour = intent.getBooleanExtra(
13642                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13643            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13644        }
13645
13646        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13647            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13648        }
13649
13650        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13651            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13652            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13653        }
13654
13655        // Add to the sticky list if requested.
13656        if (sticky) {
13657            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13658                    callingPid, callingUid)
13659                    != PackageManager.PERMISSION_GRANTED) {
13660                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13661                        + callingPid + ", uid=" + callingUid
13662                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13663                Slog.w(TAG, msg);
13664                throw new SecurityException(msg);
13665            }
13666            if (requiredPermission != null) {
13667                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13668                        + " and enforce permission " + requiredPermission);
13669                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13670            }
13671            if (intent.getComponent() != null) {
13672                throw new SecurityException(
13673                        "Sticky broadcasts can't target a specific component");
13674            }
13675            // We use userId directly here, since the "all" target is maintained
13676            // as a separate set of sticky broadcasts.
13677            if (userId != UserHandle.USER_ALL) {
13678                // But first, if this is not a broadcast to all users, then
13679                // make sure it doesn't conflict with an existing broadcast to
13680                // all users.
13681                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13682                        UserHandle.USER_ALL);
13683                if (stickies != null) {
13684                    ArrayList<Intent> list = stickies.get(intent.getAction());
13685                    if (list != null) {
13686                        int N = list.size();
13687                        int i;
13688                        for (i=0; i<N; i++) {
13689                            if (intent.filterEquals(list.get(i))) {
13690                                throw new IllegalArgumentException(
13691                                        "Sticky broadcast " + intent + " for user "
13692                                        + userId + " conflicts with existing global broadcast");
13693                            }
13694                        }
13695                    }
13696                }
13697            }
13698            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13699            if (stickies == null) {
13700                stickies = new ArrayMap<String, ArrayList<Intent>>();
13701                mStickyBroadcasts.put(userId, stickies);
13702            }
13703            ArrayList<Intent> list = stickies.get(intent.getAction());
13704            if (list == null) {
13705                list = new ArrayList<Intent>();
13706                stickies.put(intent.getAction(), list);
13707            }
13708            int N = list.size();
13709            int i;
13710            for (i=0; i<N; i++) {
13711                if (intent.filterEquals(list.get(i))) {
13712                    // This sticky already exists, replace it.
13713                    list.set(i, new Intent(intent));
13714                    break;
13715                }
13716            }
13717            if (i >= N) {
13718                list.add(new Intent(intent));
13719            }
13720        }
13721
13722        int[] users;
13723        if (userId == UserHandle.USER_ALL) {
13724            // Caller wants broadcast to go to all started users.
13725            users = mStartedUserArray;
13726        } else {
13727            // Caller wants broadcast to go to one specific user.
13728            users = new int[] {userId};
13729        }
13730
13731        // Figure out who all will receive this broadcast.
13732        List receivers = null;
13733        List<BroadcastFilter> registeredReceivers = null;
13734        // Need to resolve the intent to interested receivers...
13735        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13736                 == 0) {
13737            receivers = collectReceiverComponents(intent, resolvedType, users);
13738        }
13739        if (intent.getComponent() == null) {
13740            registeredReceivers = mReceiverResolver.queryIntent(intent,
13741                    resolvedType, false, userId);
13742        }
13743
13744        final boolean replacePending =
13745                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13746
13747        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13748                + " replacePending=" + replacePending);
13749
13750        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13751        if (!ordered && NR > 0) {
13752            // If we are not serializing this broadcast, then send the
13753            // registered receivers separately so they don't wait for the
13754            // components to be launched.
13755            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13756            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13757                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13758                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13759                    ordered, sticky, false, userId);
13760            if (DEBUG_BROADCAST) Slog.v(
13761                    TAG, "Enqueueing parallel broadcast " + r);
13762            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13763            if (!replaced) {
13764                queue.enqueueParallelBroadcastLocked(r);
13765                queue.scheduleBroadcastsLocked();
13766            }
13767            registeredReceivers = null;
13768            NR = 0;
13769        }
13770
13771        // Merge into one list.
13772        int ir = 0;
13773        if (receivers != null) {
13774            // A special case for PACKAGE_ADDED: do not allow the package
13775            // being added to see this broadcast.  This prevents them from
13776            // using this as a back door to get run as soon as they are
13777            // installed.  Maybe in the future we want to have a special install
13778            // broadcast or such for apps, but we'd like to deliberately make
13779            // this decision.
13780            String skipPackages[] = null;
13781            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13782                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13783                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13784                Uri data = intent.getData();
13785                if (data != null) {
13786                    String pkgName = data.getSchemeSpecificPart();
13787                    if (pkgName != null) {
13788                        skipPackages = new String[] { pkgName };
13789                    }
13790                }
13791            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13792                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13793            }
13794            if (skipPackages != null && (skipPackages.length > 0)) {
13795                for (String skipPackage : skipPackages) {
13796                    if (skipPackage != null) {
13797                        int NT = receivers.size();
13798                        for (int it=0; it<NT; it++) {
13799                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13800                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13801                                receivers.remove(it);
13802                                it--;
13803                                NT--;
13804                            }
13805                        }
13806                    }
13807                }
13808            }
13809
13810            int NT = receivers != null ? receivers.size() : 0;
13811            int it = 0;
13812            ResolveInfo curt = null;
13813            BroadcastFilter curr = null;
13814            while (it < NT && ir < NR) {
13815                if (curt == null) {
13816                    curt = (ResolveInfo)receivers.get(it);
13817                }
13818                if (curr == null) {
13819                    curr = registeredReceivers.get(ir);
13820                }
13821                if (curr.getPriority() >= curt.priority) {
13822                    // Insert this broadcast record into the final list.
13823                    receivers.add(it, curr);
13824                    ir++;
13825                    curr = null;
13826                    it++;
13827                    NT++;
13828                } else {
13829                    // Skip to the next ResolveInfo in the final list.
13830                    it++;
13831                    curt = null;
13832                }
13833            }
13834        }
13835        while (ir < NR) {
13836            if (receivers == null) {
13837                receivers = new ArrayList();
13838            }
13839            receivers.add(registeredReceivers.get(ir));
13840            ir++;
13841        }
13842
13843        if ((receivers != null && receivers.size() > 0)
13844                || resultTo != null) {
13845            BroadcastQueue queue = broadcastQueueForIntent(intent);
13846            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13847                    callerPackage, callingPid, callingUid, resolvedType,
13848                    requiredPermission, appOp, receivers, resultTo, resultCode,
13849                    resultData, map, ordered, sticky, false, userId);
13850            if (DEBUG_BROADCAST) Slog.v(
13851                    TAG, "Enqueueing ordered broadcast " + r
13852                    + ": prev had " + queue.mOrderedBroadcasts.size());
13853            if (DEBUG_BROADCAST) {
13854                int seq = r.intent.getIntExtra("seq", -1);
13855                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13856            }
13857            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13858            if (!replaced) {
13859                queue.enqueueOrderedBroadcastLocked(r);
13860                queue.scheduleBroadcastsLocked();
13861            }
13862        }
13863
13864        return ActivityManager.BROADCAST_SUCCESS;
13865    }
13866
13867    final Intent verifyBroadcastLocked(Intent intent) {
13868        // Refuse possible leaked file descriptors
13869        if (intent != null && intent.hasFileDescriptors() == true) {
13870            throw new IllegalArgumentException("File descriptors passed in Intent");
13871        }
13872
13873        int flags = intent.getFlags();
13874
13875        if (!mProcessesReady) {
13876            // if the caller really truly claims to know what they're doing, go
13877            // ahead and allow the broadcast without launching any receivers
13878            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13879                intent = new Intent(intent);
13880                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13881            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13882                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13883                        + " before boot completion");
13884                throw new IllegalStateException("Cannot broadcast before boot completed");
13885            }
13886        }
13887
13888        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13889            throw new IllegalArgumentException(
13890                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13891        }
13892
13893        return intent;
13894    }
13895
13896    public final int broadcastIntent(IApplicationThread caller,
13897            Intent intent, String resolvedType, IIntentReceiver resultTo,
13898            int resultCode, String resultData, Bundle map,
13899            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13900        enforceNotIsolatedCaller("broadcastIntent");
13901        synchronized(this) {
13902            intent = verifyBroadcastLocked(intent);
13903
13904            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13905            final int callingPid = Binder.getCallingPid();
13906            final int callingUid = Binder.getCallingUid();
13907            final long origId = Binder.clearCallingIdentity();
13908            int res = broadcastIntentLocked(callerApp,
13909                    callerApp != null ? callerApp.info.packageName : null,
13910                    intent, resolvedType, resultTo,
13911                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13912                    callingPid, callingUid, userId);
13913            Binder.restoreCallingIdentity(origId);
13914            return res;
13915        }
13916    }
13917
13918    int broadcastIntentInPackage(String packageName, int uid,
13919            Intent intent, String resolvedType, IIntentReceiver resultTo,
13920            int resultCode, String resultData, Bundle map,
13921            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13922        synchronized(this) {
13923            intent = verifyBroadcastLocked(intent);
13924
13925            final long origId = Binder.clearCallingIdentity();
13926            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13927                    resultTo, resultCode, resultData, map, requiredPermission,
13928                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13929            Binder.restoreCallingIdentity(origId);
13930            return res;
13931        }
13932    }
13933
13934    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13935        // Refuse possible leaked file descriptors
13936        if (intent != null && intent.hasFileDescriptors() == true) {
13937            throw new IllegalArgumentException("File descriptors passed in Intent");
13938        }
13939
13940        userId = handleIncomingUser(Binder.getCallingPid(),
13941                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13942
13943        synchronized(this) {
13944            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13945                    != PackageManager.PERMISSION_GRANTED) {
13946                String msg = "Permission Denial: unbroadcastIntent() from pid="
13947                        + Binder.getCallingPid()
13948                        + ", uid=" + Binder.getCallingUid()
13949                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13950                Slog.w(TAG, msg);
13951                throw new SecurityException(msg);
13952            }
13953            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13954            if (stickies != null) {
13955                ArrayList<Intent> list = stickies.get(intent.getAction());
13956                if (list != null) {
13957                    int N = list.size();
13958                    int i;
13959                    for (i=0; i<N; i++) {
13960                        if (intent.filterEquals(list.get(i))) {
13961                            list.remove(i);
13962                            break;
13963                        }
13964                    }
13965                    if (list.size() <= 0) {
13966                        stickies.remove(intent.getAction());
13967                    }
13968                }
13969                if (stickies.size() <= 0) {
13970                    mStickyBroadcasts.remove(userId);
13971                }
13972            }
13973        }
13974    }
13975
13976    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13977            String resultData, Bundle resultExtras, boolean resultAbort) {
13978        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13979        if (r == null) {
13980            Slog.w(TAG, "finishReceiver called but not found on queue");
13981            return false;
13982        }
13983
13984        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13985    }
13986
13987    void backgroundServicesFinishedLocked(int userId) {
13988        for (BroadcastQueue queue : mBroadcastQueues) {
13989            queue.backgroundServicesFinishedLocked(userId);
13990        }
13991    }
13992
13993    public void finishReceiver(IBinder who, int resultCode, String resultData,
13994            Bundle resultExtras, boolean resultAbort) {
13995        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13996
13997        // Refuse possible leaked file descriptors
13998        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13999            throw new IllegalArgumentException("File descriptors passed in Bundle");
14000        }
14001
14002        final long origId = Binder.clearCallingIdentity();
14003        try {
14004            boolean doNext = false;
14005            BroadcastRecord r;
14006
14007            synchronized(this) {
14008                r = broadcastRecordForReceiverLocked(who);
14009                if (r != null) {
14010                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14011                        resultData, resultExtras, resultAbort, true);
14012                }
14013            }
14014
14015            if (doNext) {
14016                r.queue.processNextBroadcast(false);
14017            }
14018            trimApplications();
14019        } finally {
14020            Binder.restoreCallingIdentity(origId);
14021        }
14022    }
14023
14024    // =========================================================
14025    // INSTRUMENTATION
14026    // =========================================================
14027
14028    public boolean startInstrumentation(ComponentName className,
14029            String profileFile, int flags, Bundle arguments,
14030            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14031            int userId) {
14032        enforceNotIsolatedCaller("startInstrumentation");
14033        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14034                userId, false, true, "startInstrumentation", null);
14035        // Refuse possible leaked file descriptors
14036        if (arguments != null && arguments.hasFileDescriptors()) {
14037            throw new IllegalArgumentException("File descriptors passed in Bundle");
14038        }
14039
14040        synchronized(this) {
14041            InstrumentationInfo ii = null;
14042            ApplicationInfo ai = null;
14043            try {
14044                ii = mContext.getPackageManager().getInstrumentationInfo(
14045                    className, STOCK_PM_FLAGS);
14046                ai = AppGlobals.getPackageManager().getApplicationInfo(
14047                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14048            } catch (PackageManager.NameNotFoundException e) {
14049            } catch (RemoteException e) {
14050            }
14051            if (ii == null) {
14052                reportStartInstrumentationFailure(watcher, className,
14053                        "Unable to find instrumentation info for: " + className);
14054                return false;
14055            }
14056            if (ai == null) {
14057                reportStartInstrumentationFailure(watcher, className,
14058                        "Unable to find instrumentation target package: " + ii.targetPackage);
14059                return false;
14060            }
14061
14062            int match = mContext.getPackageManager().checkSignatures(
14063                    ii.targetPackage, ii.packageName);
14064            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14065                String msg = "Permission Denial: starting instrumentation "
14066                        + className + " from pid="
14067                        + Binder.getCallingPid()
14068                        + ", uid=" + Binder.getCallingPid()
14069                        + " not allowed because package " + ii.packageName
14070                        + " does not have a signature matching the target "
14071                        + ii.targetPackage;
14072                reportStartInstrumentationFailure(watcher, className, msg);
14073                throw new SecurityException(msg);
14074            }
14075
14076            final long origId = Binder.clearCallingIdentity();
14077            // Instrumentation can kill and relaunch even persistent processes
14078            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14079                    "start instr");
14080            ProcessRecord app = addAppLocked(ai, false);
14081            app.instrumentationClass = className;
14082            app.instrumentationInfo = ai;
14083            app.instrumentationProfileFile = profileFile;
14084            app.instrumentationArguments = arguments;
14085            app.instrumentationWatcher = watcher;
14086            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14087            app.instrumentationResultClass = className;
14088            Binder.restoreCallingIdentity(origId);
14089        }
14090
14091        return true;
14092    }
14093
14094    /**
14095     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14096     * error to the logs, but if somebody is watching, send the report there too.  This enables
14097     * the "am" command to report errors with more information.
14098     *
14099     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14100     * @param cn The component name of the instrumentation.
14101     * @param report The error report.
14102     */
14103    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14104            ComponentName cn, String report) {
14105        Slog.w(TAG, report);
14106        try {
14107            if (watcher != null) {
14108                Bundle results = new Bundle();
14109                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14110                results.putString("Error", report);
14111                watcher.instrumentationStatus(cn, -1, results);
14112            }
14113        } catch (RemoteException e) {
14114            Slog.w(TAG, e);
14115        }
14116    }
14117
14118    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14119        if (app.instrumentationWatcher != null) {
14120            try {
14121                // NOTE:  IInstrumentationWatcher *must* be oneway here
14122                app.instrumentationWatcher.instrumentationFinished(
14123                    app.instrumentationClass,
14124                    resultCode,
14125                    results);
14126            } catch (RemoteException e) {
14127            }
14128        }
14129        if (app.instrumentationUiAutomationConnection != null) {
14130            try {
14131                app.instrumentationUiAutomationConnection.shutdown();
14132            } catch (RemoteException re) {
14133                /* ignore */
14134            }
14135            // Only a UiAutomation can set this flag and now that
14136            // it is finished we make sure it is reset to its default.
14137            mUserIsMonkey = false;
14138        }
14139        app.instrumentationWatcher = null;
14140        app.instrumentationUiAutomationConnection = null;
14141        app.instrumentationClass = null;
14142        app.instrumentationInfo = null;
14143        app.instrumentationProfileFile = null;
14144        app.instrumentationArguments = null;
14145
14146        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14147                "finished inst");
14148    }
14149
14150    public void finishInstrumentation(IApplicationThread target,
14151            int resultCode, Bundle results) {
14152        int userId = UserHandle.getCallingUserId();
14153        // Refuse possible leaked file descriptors
14154        if (results != null && results.hasFileDescriptors()) {
14155            throw new IllegalArgumentException("File descriptors passed in Intent");
14156        }
14157
14158        synchronized(this) {
14159            ProcessRecord app = getRecordForAppLocked(target);
14160            if (app == null) {
14161                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14162                return;
14163            }
14164            final long origId = Binder.clearCallingIdentity();
14165            finishInstrumentationLocked(app, resultCode, results);
14166            Binder.restoreCallingIdentity(origId);
14167        }
14168    }
14169
14170    // =========================================================
14171    // CONFIGURATION
14172    // =========================================================
14173
14174    public ConfigurationInfo getDeviceConfigurationInfo() {
14175        ConfigurationInfo config = new ConfigurationInfo();
14176        synchronized (this) {
14177            config.reqTouchScreen = mConfiguration.touchscreen;
14178            config.reqKeyboardType = mConfiguration.keyboard;
14179            config.reqNavigation = mConfiguration.navigation;
14180            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14181                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14182                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14183            }
14184            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14185                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14186                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14187            }
14188            config.reqGlEsVersion = GL_ES_VERSION;
14189        }
14190        return config;
14191    }
14192
14193    ActivityStack getFocusedStack() {
14194        return mStackSupervisor.getFocusedStack();
14195    }
14196
14197    public Configuration getConfiguration() {
14198        Configuration ci;
14199        synchronized(this) {
14200            ci = new Configuration(mConfiguration);
14201        }
14202        return ci;
14203    }
14204
14205    public void updatePersistentConfiguration(Configuration values) {
14206        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14207                "updateConfiguration()");
14208        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14209                "updateConfiguration()");
14210        if (values == null) {
14211            throw new NullPointerException("Configuration must not be null");
14212        }
14213
14214        synchronized(this) {
14215            final long origId = Binder.clearCallingIdentity();
14216            updateConfigurationLocked(values, null, true, false);
14217            Binder.restoreCallingIdentity(origId);
14218        }
14219    }
14220
14221    public void updateConfiguration(Configuration values) {
14222        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14223                "updateConfiguration()");
14224
14225        synchronized(this) {
14226            if (values == null && mWindowManager != null) {
14227                // sentinel: fetch the current configuration from the window manager
14228                values = mWindowManager.computeNewConfiguration();
14229            }
14230
14231            if (mWindowManager != null) {
14232                mProcessList.applyDisplaySize(mWindowManager);
14233            }
14234
14235            final long origId = Binder.clearCallingIdentity();
14236            if (values != null) {
14237                Settings.System.clearConfiguration(values);
14238            }
14239            updateConfigurationLocked(values, null, false, false);
14240            Binder.restoreCallingIdentity(origId);
14241        }
14242    }
14243
14244    /**
14245     * Do either or both things: (1) change the current configuration, and (2)
14246     * make sure the given activity is running with the (now) current
14247     * configuration.  Returns true if the activity has been left running, or
14248     * false if <var>starting</var> is being destroyed to match the new
14249     * configuration.
14250     * @param persistent TODO
14251     */
14252    boolean updateConfigurationLocked(Configuration values,
14253            ActivityRecord starting, boolean persistent, boolean initLocale) {
14254        int changes = 0;
14255
14256        if (values != null) {
14257            Configuration newConfig = new Configuration(mConfiguration);
14258            changes = newConfig.updateFrom(values);
14259            if (changes != 0) {
14260                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14261                    Slog.i(TAG, "Updating configuration to: " + values);
14262                }
14263
14264                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14265
14266                if (values.locale != null && !initLocale) {
14267                    saveLocaleLocked(values.locale,
14268                                     !values.locale.equals(mConfiguration.locale),
14269                                     values.userSetLocale);
14270                }
14271
14272                mConfigurationSeq++;
14273                if (mConfigurationSeq <= 0) {
14274                    mConfigurationSeq = 1;
14275                }
14276                newConfig.seq = mConfigurationSeq;
14277                mConfiguration = newConfig;
14278                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14279
14280                final Configuration configCopy = new Configuration(mConfiguration);
14281
14282                // TODO: If our config changes, should we auto dismiss any currently
14283                // showing dialogs?
14284                mShowDialogs = shouldShowDialogs(newConfig);
14285
14286                AttributeCache ac = AttributeCache.instance();
14287                if (ac != null) {
14288                    ac.updateConfiguration(configCopy);
14289                }
14290
14291                // Make sure all resources in our process are updated
14292                // right now, so that anyone who is going to retrieve
14293                // resource values after we return will be sure to get
14294                // the new ones.  This is especially important during
14295                // boot, where the first config change needs to guarantee
14296                // all resources have that config before following boot
14297                // code is executed.
14298                mSystemThread.applyConfigurationToResources(configCopy);
14299
14300                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14301                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14302                    msg.obj = new Configuration(configCopy);
14303                    mHandler.sendMessage(msg);
14304                }
14305
14306                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14307                    ProcessRecord app = mLruProcesses.get(i);
14308                    try {
14309                        if (app.thread != null) {
14310                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14311                                    + app.processName + " new config " + mConfiguration);
14312                            app.thread.scheduleConfigurationChanged(configCopy);
14313                        }
14314                    } catch (Exception e) {
14315                    }
14316                }
14317                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14318                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14319                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14320                        | Intent.FLAG_RECEIVER_FOREGROUND);
14321                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14322                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14323                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14324                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14325                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14326                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14327                    broadcastIntentLocked(null, null, intent,
14328                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14329                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14330                }
14331            }
14332        }
14333
14334        boolean kept = true;
14335        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14336        // mainStack is null during startup.
14337        if (mainStack != null) {
14338            if (changes != 0 && starting == null) {
14339                // If the configuration changed, and the caller is not already
14340                // in the process of starting an activity, then find the top
14341                // activity to check if its configuration needs to change.
14342                starting = mainStack.topRunningActivityLocked(null);
14343            }
14344
14345            if (starting != null) {
14346                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14347                // And we need to make sure at this point that all other activities
14348                // are made visible with the correct configuration.
14349                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14350            }
14351        }
14352
14353        if (values != null && mWindowManager != null) {
14354            mWindowManager.setNewConfiguration(mConfiguration);
14355        }
14356
14357        return kept;
14358    }
14359
14360    /**
14361     * Decide based on the configuration whether we should shouw the ANR,
14362     * crash, etc dialogs.  The idea is that if there is no affordnace to
14363     * press the on-screen buttons, we shouldn't show the dialog.
14364     *
14365     * A thought: SystemUI might also want to get told about this, the Power
14366     * dialog / global actions also might want different behaviors.
14367     */
14368    private static final boolean shouldShowDialogs(Configuration config) {
14369        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14370                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14371    }
14372
14373    /**
14374     * Save the locale.  You must be inside a synchronized (this) block.
14375     */
14376    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14377        if(isDiff) {
14378            SystemProperties.set("user.language", l.getLanguage());
14379            SystemProperties.set("user.region", l.getCountry());
14380        }
14381
14382        if(isPersist) {
14383            SystemProperties.set("persist.sys.language", l.getLanguage());
14384            SystemProperties.set("persist.sys.country", l.getCountry());
14385            SystemProperties.set("persist.sys.localevar", l.getVariant());
14386        }
14387    }
14388
14389    @Override
14390    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14391        ActivityRecord srec = ActivityRecord.forToken(token);
14392        return srec != null && srec.task.affinity != null &&
14393                srec.task.affinity.equals(destAffinity);
14394    }
14395
14396    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14397            Intent resultData) {
14398
14399        synchronized (this) {
14400            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14401            if (stack != null) {
14402                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14403            }
14404            return false;
14405        }
14406    }
14407
14408    public int getLaunchedFromUid(IBinder activityToken) {
14409        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14410        if (srec == null) {
14411            return -1;
14412        }
14413        return srec.launchedFromUid;
14414    }
14415
14416    public String getLaunchedFromPackage(IBinder activityToken) {
14417        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14418        if (srec == null) {
14419            return null;
14420        }
14421        return srec.launchedFromPackage;
14422    }
14423
14424    // =========================================================
14425    // LIFETIME MANAGEMENT
14426    // =========================================================
14427
14428    // Returns which broadcast queue the app is the current [or imminent] receiver
14429    // on, or 'null' if the app is not an active broadcast recipient.
14430    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14431        BroadcastRecord r = app.curReceiver;
14432        if (r != null) {
14433            return r.queue;
14434        }
14435
14436        // It's not the current receiver, but it might be starting up to become one
14437        synchronized (this) {
14438            for (BroadcastQueue queue : mBroadcastQueues) {
14439                r = queue.mPendingBroadcast;
14440                if (r != null && r.curApp == app) {
14441                    // found it; report which queue it's in
14442                    return queue;
14443                }
14444            }
14445        }
14446
14447        return null;
14448    }
14449
14450    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14451            boolean doingAll, long now) {
14452        if (mAdjSeq == app.adjSeq) {
14453            // This adjustment has already been computed.
14454            return app.curRawAdj;
14455        }
14456
14457        if (app.thread == null) {
14458            app.adjSeq = mAdjSeq;
14459            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14460            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14461            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14462        }
14463
14464        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14465        app.adjSource = null;
14466        app.adjTarget = null;
14467        app.empty = false;
14468        app.cached = false;
14469
14470        final int activitiesSize = app.activities.size();
14471
14472        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14473            // The max adjustment doesn't allow this app to be anything
14474            // below foreground, so it is not worth doing work for it.
14475            app.adjType = "fixed";
14476            app.adjSeq = mAdjSeq;
14477            app.curRawAdj = app.maxAdj;
14478            app.foregroundActivities = false;
14479            app.keeping = true;
14480            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14481            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14482            // System process can do UI, and when they do we want to have
14483            // them trim their memory after the user leaves the UI.  To
14484            // facilitate this, here we need to determine whether or not it
14485            // is currently showing UI.
14486            app.systemNoUi = true;
14487            if (app == TOP_APP) {
14488                app.systemNoUi = false;
14489            } else if (activitiesSize > 0) {
14490                for (int j = 0; j < activitiesSize; j++) {
14491                    final ActivityRecord r = app.activities.get(j);
14492                    if (r.visible) {
14493                        app.systemNoUi = false;
14494                    }
14495                }
14496            }
14497            if (!app.systemNoUi) {
14498                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14499            }
14500            return (app.curAdj=app.maxAdj);
14501        }
14502
14503        app.keeping = false;
14504        app.systemNoUi = false;
14505
14506        // Determine the importance of the process, starting with most
14507        // important to least, and assign an appropriate OOM adjustment.
14508        int adj;
14509        int schedGroup;
14510        int procState;
14511        boolean foregroundActivities = false;
14512        boolean interesting = false;
14513        BroadcastQueue queue;
14514        if (app == TOP_APP) {
14515            // The last app on the list is the foreground app.
14516            adj = ProcessList.FOREGROUND_APP_ADJ;
14517            schedGroup = Process.THREAD_GROUP_DEFAULT;
14518            app.adjType = "top-activity";
14519            foregroundActivities = true;
14520            interesting = true;
14521            procState = ActivityManager.PROCESS_STATE_TOP;
14522        } else if (app.instrumentationClass != null) {
14523            // Don't want to kill running instrumentation.
14524            adj = ProcessList.FOREGROUND_APP_ADJ;
14525            schedGroup = Process.THREAD_GROUP_DEFAULT;
14526            app.adjType = "instrumentation";
14527            interesting = true;
14528            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14529        } else if ((queue = isReceivingBroadcast(app)) != null) {
14530            // An app that is currently receiving a broadcast also
14531            // counts as being in the foreground for OOM killer purposes.
14532            // It's placed in a sched group based on the nature of the
14533            // broadcast as reflected by which queue it's active in.
14534            adj = ProcessList.FOREGROUND_APP_ADJ;
14535            schedGroup = (queue == mFgBroadcastQueue)
14536                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14537            app.adjType = "broadcast";
14538            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14539        } else if (app.executingServices.size() > 0) {
14540            // An app that is currently executing a service callback also
14541            // counts as being in the foreground.
14542            adj = ProcessList.FOREGROUND_APP_ADJ;
14543            schedGroup = app.execServicesFg ?
14544                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14545            app.adjType = "exec-service";
14546            procState = ActivityManager.PROCESS_STATE_SERVICE;
14547            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14548        } else {
14549            // As far as we know the process is empty.  We may change our mind later.
14550            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14551            // At this point we don't actually know the adjustment.  Use the cached adj
14552            // value that the caller wants us to.
14553            adj = cachedAdj;
14554            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14555            app.cached = true;
14556            app.empty = true;
14557            app.adjType = "cch-empty";
14558        }
14559
14560        // Examine all activities if not already foreground.
14561        if (!foregroundActivities && activitiesSize > 0) {
14562            for (int j = 0; j < activitiesSize; j++) {
14563                final ActivityRecord r = app.activities.get(j);
14564                if (r.app != app) {
14565                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14566                            + app + "?!?");
14567                    continue;
14568                }
14569                if (r.visible) {
14570                    // App has a visible activity; only upgrade adjustment.
14571                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14572                        adj = ProcessList.VISIBLE_APP_ADJ;
14573                        app.adjType = "visible";
14574                    }
14575                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14576                        procState = ActivityManager.PROCESS_STATE_TOP;
14577                    }
14578                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14579                    app.cached = false;
14580                    app.empty = false;
14581                    foregroundActivities = true;
14582                    break;
14583                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14584                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14585                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14586                        app.adjType = "pausing";
14587                    }
14588                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14589                        procState = ActivityManager.PROCESS_STATE_TOP;
14590                    }
14591                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14592                    app.cached = false;
14593                    app.empty = false;
14594                    foregroundActivities = true;
14595                } else if (r.state == ActivityState.STOPPING) {
14596                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14597                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14598                        app.adjType = "stopping";
14599                    }
14600                    // For the process state, we will at this point consider the
14601                    // process to be cached.  It will be cached either as an activity
14602                    // or empty depending on whether the activity is finishing.  We do
14603                    // this so that we can treat the process as cached for purposes of
14604                    // memory trimming (determing current memory level, trim command to
14605                    // send to process) since there can be an arbitrary number of stopping
14606                    // processes and they should soon all go into the cached state.
14607                    if (!r.finishing) {
14608                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14609                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14610                        }
14611                    }
14612                    app.cached = false;
14613                    app.empty = false;
14614                    foregroundActivities = true;
14615                } else {
14616                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14617                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14618                        app.adjType = "cch-act";
14619                    }
14620                }
14621            }
14622        }
14623
14624        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14625            if (app.foregroundServices) {
14626                // The user is aware of this app, so make it visible.
14627                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14628                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14629                app.cached = false;
14630                app.adjType = "fg-service";
14631                schedGroup = Process.THREAD_GROUP_DEFAULT;
14632            } else if (app.forcingToForeground != null) {
14633                // The user is aware of this app, so make it visible.
14634                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14635                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14636                app.cached = false;
14637                app.adjType = "force-fg";
14638                app.adjSource = app.forcingToForeground;
14639                schedGroup = Process.THREAD_GROUP_DEFAULT;
14640            }
14641        }
14642
14643        if (app.foregroundServices) {
14644            interesting = true;
14645        }
14646
14647        if (app == mHeavyWeightProcess) {
14648            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14649                // We don't want to kill the current heavy-weight process.
14650                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14651                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14652                app.cached = false;
14653                app.adjType = "heavy";
14654            }
14655            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14656                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14657            }
14658        }
14659
14660        if (app == mHomeProcess) {
14661            if (adj > ProcessList.HOME_APP_ADJ) {
14662                // This process is hosting what we currently consider to be the
14663                // home app, so we don't want to let it go into the background.
14664                adj = ProcessList.HOME_APP_ADJ;
14665                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14666                app.cached = false;
14667                app.adjType = "home";
14668            }
14669            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14670                procState = ActivityManager.PROCESS_STATE_HOME;
14671            }
14672        }
14673
14674        if (app == mPreviousProcess && app.activities.size() > 0) {
14675            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14676                // This was the previous process that showed UI to the user.
14677                // We want to try to keep it around more aggressively, to give
14678                // a good experience around switching between two apps.
14679                adj = ProcessList.PREVIOUS_APP_ADJ;
14680                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14681                app.cached = false;
14682                app.adjType = "previous";
14683            }
14684            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14685                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14686            }
14687        }
14688
14689        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14690                + " reason=" + app.adjType);
14691
14692        // By default, we use the computed adjustment.  It may be changed if
14693        // there are applications dependent on our services or providers, but
14694        // this gives us a baseline and makes sure we don't get into an
14695        // infinite recursion.
14696        app.adjSeq = mAdjSeq;
14697        app.curRawAdj = adj;
14698        app.hasStartedServices = false;
14699
14700        if (mBackupTarget != null && app == mBackupTarget.app) {
14701            // If possible we want to avoid killing apps while they're being backed up
14702            if (adj > ProcessList.BACKUP_APP_ADJ) {
14703                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14704                adj = ProcessList.BACKUP_APP_ADJ;
14705                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14706                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14707                }
14708                app.adjType = "backup";
14709                app.cached = false;
14710            }
14711            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14712                procState = ActivityManager.PROCESS_STATE_BACKUP;
14713            }
14714        }
14715
14716        boolean mayBeTop = false;
14717
14718        for (int is = app.services.size()-1;
14719                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14720                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14721                        || procState > ActivityManager.PROCESS_STATE_TOP);
14722                is--) {
14723            ServiceRecord s = app.services.valueAt(is);
14724            if (s.startRequested) {
14725                app.hasStartedServices = true;
14726                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14727                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14728                }
14729                if (app.hasShownUi && app != mHomeProcess) {
14730                    // If this process has shown some UI, let it immediately
14731                    // go to the LRU list because it may be pretty heavy with
14732                    // UI stuff.  We'll tag it with a label just to help
14733                    // debug and understand what is going on.
14734                    if (adj > ProcessList.SERVICE_ADJ) {
14735                        app.adjType = "cch-started-ui-services";
14736                    }
14737                } else {
14738                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14739                        // This service has seen some activity within
14740                        // recent memory, so we will keep its process ahead
14741                        // of the background processes.
14742                        if (adj > ProcessList.SERVICE_ADJ) {
14743                            adj = ProcessList.SERVICE_ADJ;
14744                            app.adjType = "started-services";
14745                            app.cached = false;
14746                        }
14747                    }
14748                    // If we have let the service slide into the background
14749                    // state, still have some text describing what it is doing
14750                    // even though the service no longer has an impact.
14751                    if (adj > ProcessList.SERVICE_ADJ) {
14752                        app.adjType = "cch-started-services";
14753                    }
14754                }
14755                // Don't kill this process because it is doing work; it
14756                // has said it is doing work.
14757                app.keeping = true;
14758            }
14759            for (int conni = s.connections.size()-1;
14760                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14761                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14762                            || procState > ActivityManager.PROCESS_STATE_TOP);
14763                    conni--) {
14764                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14765                for (int i = 0;
14766                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14767                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14768                                || procState > ActivityManager.PROCESS_STATE_TOP);
14769                        i++) {
14770                    // XXX should compute this based on the max of
14771                    // all connected clients.
14772                    ConnectionRecord cr = clist.get(i);
14773                    if (cr.binding.client == app) {
14774                        // Binding to ourself is not interesting.
14775                        continue;
14776                    }
14777                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14778                        ProcessRecord client = cr.binding.client;
14779                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14780                                TOP_APP, doingAll, now);
14781                        int clientProcState = client.curProcState;
14782                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14783                            // If the other app is cached for any reason, for purposes here
14784                            // we are going to consider it empty.  The specific cached state
14785                            // doesn't propagate except under certain conditions.
14786                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14787                        }
14788                        String adjType = null;
14789                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14790                            // Not doing bind OOM management, so treat
14791                            // this guy more like a started service.
14792                            if (app.hasShownUi && app != mHomeProcess) {
14793                                // If this process has shown some UI, let it immediately
14794                                // go to the LRU list because it may be pretty heavy with
14795                                // UI stuff.  We'll tag it with a label just to help
14796                                // debug and understand what is going on.
14797                                if (adj > clientAdj) {
14798                                    adjType = "cch-bound-ui-services";
14799                                }
14800                                app.cached = false;
14801                                clientAdj = adj;
14802                                clientProcState = procState;
14803                            } else {
14804                                if (now >= (s.lastActivity
14805                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14806                                    // This service has not seen activity within
14807                                    // recent memory, so allow it to drop to the
14808                                    // LRU list if there is no other reason to keep
14809                                    // it around.  We'll also tag it with a label just
14810                                    // to help debug and undertand what is going on.
14811                                    if (adj > clientAdj) {
14812                                        adjType = "cch-bound-services";
14813                                    }
14814                                    clientAdj = adj;
14815                                }
14816                            }
14817                        }
14818                        if (adj > clientAdj) {
14819                            // If this process has recently shown UI, and
14820                            // the process that is binding to it is less
14821                            // important than being visible, then we don't
14822                            // care about the binding as much as we care
14823                            // about letting this process get into the LRU
14824                            // list to be killed and restarted if needed for
14825                            // memory.
14826                            if (app.hasShownUi && app != mHomeProcess
14827                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14828                                adjType = "cch-bound-ui-services";
14829                            } else {
14830                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14831                                        |Context.BIND_IMPORTANT)) != 0) {
14832                                    adj = clientAdj;
14833                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14834                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14835                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14836                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14837                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14838                                    adj = clientAdj;
14839                                } else {
14840                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14841                                        adj = ProcessList.VISIBLE_APP_ADJ;
14842                                    }
14843                                }
14844                                if (!client.cached) {
14845                                    app.cached = false;
14846                                }
14847                                if (client.keeping) {
14848                                    app.keeping = true;
14849                                }
14850                                adjType = "service";
14851                            }
14852                        }
14853                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14854                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14855                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14856                            }
14857                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14858                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14859                                    // Special handling of clients who are in the top state.
14860                                    // We *may* want to consider this process to be in the
14861                                    // top state as well, but only if there is not another
14862                                    // reason for it to be running.  Being on the top is a
14863                                    // special state, meaning you are specifically running
14864                                    // for the current top app.  If the process is already
14865                                    // running in the background for some other reason, it
14866                                    // is more important to continue considering it to be
14867                                    // in the background state.
14868                                    mayBeTop = true;
14869                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14870                                } else {
14871                                    // Special handling for above-top states (persistent
14872                                    // processes).  These should not bring the current process
14873                                    // into the top state, since they are not on top.  Instead
14874                                    // give them the best state after that.
14875                                    clientProcState =
14876                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14877                                }
14878                            }
14879                        } else {
14880                            if (clientProcState <
14881                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14882                                clientProcState =
14883                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14884                            }
14885                        }
14886                        if (procState > clientProcState) {
14887                            procState = clientProcState;
14888                        }
14889                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14890                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14891                            app.pendingUiClean = true;
14892                        }
14893                        if (adjType != null) {
14894                            app.adjType = adjType;
14895                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14896                                    .REASON_SERVICE_IN_USE;
14897                            app.adjSource = cr.binding.client;
14898                            app.adjSourceOom = clientAdj;
14899                            app.adjTarget = s.name;
14900                        }
14901                    }
14902                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14903                        app.treatLikeActivity = true;
14904                    }
14905                    final ActivityRecord a = cr.activity;
14906                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14907                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14908                                (a.visible || a.state == ActivityState.RESUMED
14909                                 || a.state == ActivityState.PAUSING)) {
14910                            adj = ProcessList.FOREGROUND_APP_ADJ;
14911                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14912                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14913                            }
14914                            app.cached = false;
14915                            app.adjType = "service";
14916                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14917                                    .REASON_SERVICE_IN_USE;
14918                            app.adjSource = a;
14919                            app.adjSourceOom = adj;
14920                            app.adjTarget = s.name;
14921                        }
14922                    }
14923                }
14924            }
14925        }
14926
14927        for (int provi = app.pubProviders.size()-1;
14928                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14929                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14930                        || procState > ActivityManager.PROCESS_STATE_TOP);
14931                provi--) {
14932            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14933            for (int i = cpr.connections.size()-1;
14934                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14935                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14936                            || procState > ActivityManager.PROCESS_STATE_TOP);
14937                    i--) {
14938                ContentProviderConnection conn = cpr.connections.get(i);
14939                ProcessRecord client = conn.client;
14940                if (client == app) {
14941                    // Being our own client is not interesting.
14942                    continue;
14943                }
14944                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14945                int clientProcState = client.curProcState;
14946                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14947                    // If the other app is cached for any reason, for purposes here
14948                    // we are going to consider it empty.
14949                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14950                }
14951                if (adj > clientAdj) {
14952                    if (app.hasShownUi && app != mHomeProcess
14953                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14954                        app.adjType = "cch-ui-provider";
14955                    } else {
14956                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14957                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14958                        app.adjType = "provider";
14959                    }
14960                    app.cached &= client.cached;
14961                    app.keeping |= client.keeping;
14962                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14963                            .REASON_PROVIDER_IN_USE;
14964                    app.adjSource = client;
14965                    app.adjSourceOom = clientAdj;
14966                    app.adjTarget = cpr.name;
14967                }
14968                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14969                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14970                        // Special handling of clients who are in the top state.
14971                        // We *may* want to consider this process to be in the
14972                        // top state as well, but only if there is not another
14973                        // reason for it to be running.  Being on the top is a
14974                        // special state, meaning you are specifically running
14975                        // for the current top app.  If the process is already
14976                        // running in the background for some other reason, it
14977                        // is more important to continue considering it to be
14978                        // in the background state.
14979                        mayBeTop = true;
14980                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14981                    } else {
14982                        // Special handling for above-top states (persistent
14983                        // processes).  These should not bring the current process
14984                        // into the top state, since they are not on top.  Instead
14985                        // give them the best state after that.
14986                        clientProcState =
14987                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14988                    }
14989                }
14990                if (procState > clientProcState) {
14991                    procState = clientProcState;
14992                }
14993                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14994                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14995                }
14996            }
14997            // If the provider has external (non-framework) process
14998            // dependencies, ensure that its adjustment is at least
14999            // FOREGROUND_APP_ADJ.
15000            if (cpr.hasExternalProcessHandles()) {
15001                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15002                    adj = ProcessList.FOREGROUND_APP_ADJ;
15003                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15004                    app.cached = false;
15005                    app.keeping = true;
15006                    app.adjType = "provider";
15007                    app.adjTarget = cpr.name;
15008                }
15009                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15010                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15011                }
15012            }
15013        }
15014
15015        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15016            // A client of one of our services or providers is in the top state.  We
15017            // *may* want to be in the top state, but not if we are already running in
15018            // the background for some other reason.  For the decision here, we are going
15019            // to pick out a few specific states that we want to remain in when a client
15020            // is top (states that tend to be longer-term) and otherwise allow it to go
15021            // to the top state.
15022            switch (procState) {
15023                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15024                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15025                case ActivityManager.PROCESS_STATE_SERVICE:
15026                    // These all are longer-term states, so pull them up to the top
15027                    // of the background states, but not all the way to the top state.
15028                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15029                    break;
15030                default:
15031                    // Otherwise, top is a better choice, so take it.
15032                    procState = ActivityManager.PROCESS_STATE_TOP;
15033                    break;
15034            }
15035        }
15036
15037        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15038            if (app.hasClientActivities) {
15039                // This is a cached process, but with client activities.  Mark it so.
15040                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15041                app.adjType = "cch-client-act";
15042            } else if (app.treatLikeActivity) {
15043                // This is a cached process, but somebody wants us to treat it like it has
15044                // an activity, okay!
15045                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15046                app.adjType = "cch-as-act";
15047            }
15048        }
15049
15050        if (adj == ProcessList.SERVICE_ADJ) {
15051            if (doingAll) {
15052                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15053                mNewNumServiceProcs++;
15054                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15055                if (!app.serviceb) {
15056                    // This service isn't far enough down on the LRU list to
15057                    // normally be a B service, but if we are low on RAM and it
15058                    // is large we want to force it down since we would prefer to
15059                    // keep launcher over it.
15060                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15061                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15062                        app.serviceHighRam = true;
15063                        app.serviceb = true;
15064                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15065                    } else {
15066                        mNewNumAServiceProcs++;
15067                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15068                    }
15069                } else {
15070                    app.serviceHighRam = false;
15071                }
15072            }
15073            if (app.serviceb) {
15074                adj = ProcessList.SERVICE_B_ADJ;
15075            }
15076        }
15077
15078        app.curRawAdj = adj;
15079
15080        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15081        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15082        if (adj > app.maxAdj) {
15083            adj = app.maxAdj;
15084            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15085                schedGroup = Process.THREAD_GROUP_DEFAULT;
15086            }
15087        }
15088        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15089            app.keeping = true;
15090        }
15091
15092        // Do final modification to adj.  Everything we do between here and applying
15093        // the final setAdj must be done in this function, because we will also use
15094        // it when computing the final cached adj later.  Note that we don't need to
15095        // worry about this for max adj above, since max adj will always be used to
15096        // keep it out of the cached vaues.
15097        adj = app.modifyRawOomAdj(adj);
15098
15099        app.curProcState = procState;
15100
15101        int importance = app.memImportance;
15102        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15103            app.curAdj = adj;
15104            app.curSchedGroup = schedGroup;
15105            if (!interesting) {
15106                // For this reporting, if there is not something explicitly
15107                // interesting in this process then we will push it to the
15108                // background importance.
15109                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15110            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15111                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15112            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15113                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15114            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15115                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15116            } else if (adj >= ProcessList.SERVICE_ADJ) {
15117                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15118            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15119                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15120            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15121                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15122            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15123                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15124            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15125                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15126            } else {
15127                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15128            }
15129        }
15130
15131        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15132        if (foregroundActivities != app.foregroundActivities) {
15133            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15134        }
15135        if (changes != 0) {
15136            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15137            app.memImportance = importance;
15138            app.foregroundActivities = foregroundActivities;
15139            int i = mPendingProcessChanges.size()-1;
15140            ProcessChangeItem item = null;
15141            while (i >= 0) {
15142                item = mPendingProcessChanges.get(i);
15143                if (item.pid == app.pid) {
15144                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15145                    break;
15146                }
15147                i--;
15148            }
15149            if (i < 0) {
15150                // No existing item in pending changes; need a new one.
15151                final int NA = mAvailProcessChanges.size();
15152                if (NA > 0) {
15153                    item = mAvailProcessChanges.remove(NA-1);
15154                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15155                } else {
15156                    item = new ProcessChangeItem();
15157                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15158                }
15159                item.changes = 0;
15160                item.pid = app.pid;
15161                item.uid = app.info.uid;
15162                if (mPendingProcessChanges.size() == 0) {
15163                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15164                            "*** Enqueueing dispatch processes changed!");
15165                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15166                }
15167                mPendingProcessChanges.add(item);
15168            }
15169            item.changes |= changes;
15170            item.importance = importance;
15171            item.foregroundActivities = foregroundActivities;
15172            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15173                    + Integer.toHexString(System.identityHashCode(item))
15174                    + " " + app.toShortString() + ": changes=" + item.changes
15175                    + " importance=" + item.importance
15176                    + " foreground=" + item.foregroundActivities
15177                    + " type=" + app.adjType + " source=" + app.adjSource
15178                    + " target=" + app.adjTarget);
15179        }
15180
15181        return app.curRawAdj;
15182    }
15183
15184    /**
15185     * Schedule PSS collection of a process.
15186     */
15187    void requestPssLocked(ProcessRecord proc, int procState) {
15188        if (mPendingPssProcesses.contains(proc)) {
15189            return;
15190        }
15191        if (mPendingPssProcesses.size() == 0) {
15192            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15193        }
15194        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15195        proc.pssProcState = procState;
15196        mPendingPssProcesses.add(proc);
15197    }
15198
15199    /**
15200     * Schedule PSS collection of all processes.
15201     */
15202    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15203        if (!always) {
15204            if (now < (mLastFullPssTime +
15205                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15206                return;
15207            }
15208        }
15209        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15210        mLastFullPssTime = now;
15211        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15212        mPendingPssProcesses.clear();
15213        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15214            ProcessRecord app = mLruProcesses.get(i);
15215            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15216                app.pssProcState = app.setProcState;
15217                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15218                        mSleeping, now);
15219                mPendingPssProcesses.add(app);
15220            }
15221        }
15222        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15223    }
15224
15225    /**
15226     * Ask a given process to GC right now.
15227     */
15228    final void performAppGcLocked(ProcessRecord app) {
15229        try {
15230            app.lastRequestedGc = SystemClock.uptimeMillis();
15231            if (app.thread != null) {
15232                if (app.reportLowMemory) {
15233                    app.reportLowMemory = false;
15234                    app.thread.scheduleLowMemory();
15235                } else {
15236                    app.thread.processInBackground();
15237                }
15238            }
15239        } catch (Exception e) {
15240            // whatever.
15241        }
15242    }
15243
15244    /**
15245     * Returns true if things are idle enough to perform GCs.
15246     */
15247    private final boolean canGcNowLocked() {
15248        boolean processingBroadcasts = false;
15249        for (BroadcastQueue q : mBroadcastQueues) {
15250            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15251                processingBroadcasts = true;
15252            }
15253        }
15254        return !processingBroadcasts
15255                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15256    }
15257
15258    /**
15259     * Perform GCs on all processes that are waiting for it, but only
15260     * if things are idle.
15261     */
15262    final void performAppGcsLocked() {
15263        final int N = mProcessesToGc.size();
15264        if (N <= 0) {
15265            return;
15266        }
15267        if (canGcNowLocked()) {
15268            while (mProcessesToGc.size() > 0) {
15269                ProcessRecord proc = mProcessesToGc.remove(0);
15270                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15271                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15272                            <= SystemClock.uptimeMillis()) {
15273                        // To avoid spamming the system, we will GC processes one
15274                        // at a time, waiting a few seconds between each.
15275                        performAppGcLocked(proc);
15276                        scheduleAppGcsLocked();
15277                        return;
15278                    } else {
15279                        // It hasn't been long enough since we last GCed this
15280                        // process...  put it in the list to wait for its time.
15281                        addProcessToGcListLocked(proc);
15282                        break;
15283                    }
15284                }
15285            }
15286
15287            scheduleAppGcsLocked();
15288        }
15289    }
15290
15291    /**
15292     * If all looks good, perform GCs on all processes waiting for them.
15293     */
15294    final void performAppGcsIfAppropriateLocked() {
15295        if (canGcNowLocked()) {
15296            performAppGcsLocked();
15297            return;
15298        }
15299        // Still not idle, wait some more.
15300        scheduleAppGcsLocked();
15301    }
15302
15303    /**
15304     * Schedule the execution of all pending app GCs.
15305     */
15306    final void scheduleAppGcsLocked() {
15307        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15308
15309        if (mProcessesToGc.size() > 0) {
15310            // Schedule a GC for the time to the next process.
15311            ProcessRecord proc = mProcessesToGc.get(0);
15312            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15313
15314            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15315            long now = SystemClock.uptimeMillis();
15316            if (when < (now+GC_TIMEOUT)) {
15317                when = now + GC_TIMEOUT;
15318            }
15319            mHandler.sendMessageAtTime(msg, when);
15320        }
15321    }
15322
15323    /**
15324     * Add a process to the array of processes waiting to be GCed.  Keeps the
15325     * list in sorted order by the last GC time.  The process can't already be
15326     * on the list.
15327     */
15328    final void addProcessToGcListLocked(ProcessRecord proc) {
15329        boolean added = false;
15330        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15331            if (mProcessesToGc.get(i).lastRequestedGc <
15332                    proc.lastRequestedGc) {
15333                added = true;
15334                mProcessesToGc.add(i+1, proc);
15335                break;
15336            }
15337        }
15338        if (!added) {
15339            mProcessesToGc.add(0, proc);
15340        }
15341    }
15342
15343    /**
15344     * Set up to ask a process to GC itself.  This will either do it
15345     * immediately, or put it on the list of processes to gc the next
15346     * time things are idle.
15347     */
15348    final void scheduleAppGcLocked(ProcessRecord app) {
15349        long now = SystemClock.uptimeMillis();
15350        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15351            return;
15352        }
15353        if (!mProcessesToGc.contains(app)) {
15354            addProcessToGcListLocked(app);
15355            scheduleAppGcsLocked();
15356        }
15357    }
15358
15359    final void checkExcessivePowerUsageLocked(boolean doKills) {
15360        updateCpuStatsNow();
15361
15362        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15363        boolean doWakeKills = doKills;
15364        boolean doCpuKills = doKills;
15365        if (mLastPowerCheckRealtime == 0) {
15366            doWakeKills = false;
15367        }
15368        if (mLastPowerCheckUptime == 0) {
15369            doCpuKills = false;
15370        }
15371        if (stats.isScreenOn()) {
15372            doWakeKills = false;
15373        }
15374        final long curRealtime = SystemClock.elapsedRealtime();
15375        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15376        final long curUptime = SystemClock.uptimeMillis();
15377        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15378        mLastPowerCheckRealtime = curRealtime;
15379        mLastPowerCheckUptime = curUptime;
15380        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15381            doWakeKills = false;
15382        }
15383        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15384            doCpuKills = false;
15385        }
15386        int i = mLruProcesses.size();
15387        while (i > 0) {
15388            i--;
15389            ProcessRecord app = mLruProcesses.get(i);
15390            if (!app.keeping) {
15391                long wtime;
15392                synchronized (stats) {
15393                    wtime = stats.getProcessWakeTime(app.info.uid,
15394                            app.pid, curRealtime);
15395                }
15396                long wtimeUsed = wtime - app.lastWakeTime;
15397                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15398                if (DEBUG_POWER) {
15399                    StringBuilder sb = new StringBuilder(128);
15400                    sb.append("Wake for ");
15401                    app.toShortString(sb);
15402                    sb.append(": over ");
15403                    TimeUtils.formatDuration(realtimeSince, sb);
15404                    sb.append(" used ");
15405                    TimeUtils.formatDuration(wtimeUsed, sb);
15406                    sb.append(" (");
15407                    sb.append((wtimeUsed*100)/realtimeSince);
15408                    sb.append("%)");
15409                    Slog.i(TAG, sb.toString());
15410                    sb.setLength(0);
15411                    sb.append("CPU for ");
15412                    app.toShortString(sb);
15413                    sb.append(": over ");
15414                    TimeUtils.formatDuration(uptimeSince, sb);
15415                    sb.append(" used ");
15416                    TimeUtils.formatDuration(cputimeUsed, sb);
15417                    sb.append(" (");
15418                    sb.append((cputimeUsed*100)/uptimeSince);
15419                    sb.append("%)");
15420                    Slog.i(TAG, sb.toString());
15421                }
15422                // If a process has held a wake lock for more
15423                // than 50% of the time during this period,
15424                // that sounds bad.  Kill!
15425                if (doWakeKills && realtimeSince > 0
15426                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15427                    synchronized (stats) {
15428                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15429                                realtimeSince, wtimeUsed);
15430                    }
15431                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15432                            + " during " + realtimeSince);
15433                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15434                } else if (doCpuKills && uptimeSince > 0
15435                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15436                    synchronized (stats) {
15437                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15438                                uptimeSince, cputimeUsed);
15439                    }
15440                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15441                            + " during " + uptimeSince);
15442                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15443                } else {
15444                    app.lastWakeTime = wtime;
15445                    app.lastCpuTime = app.curCpuTime;
15446                }
15447            }
15448        }
15449    }
15450
15451    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15452            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15453        boolean success = true;
15454
15455        if (app.curRawAdj != app.setRawAdj) {
15456            if (wasKeeping && !app.keeping) {
15457                // This app is no longer something we want to keep.  Note
15458                // its current wake lock time to later know to kill it if
15459                // it is not behaving well.
15460                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15461                synchronized (stats) {
15462                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15463                            app.pid, SystemClock.elapsedRealtime());
15464                }
15465                app.lastCpuTime = app.curCpuTime;
15466            }
15467
15468            app.setRawAdj = app.curRawAdj;
15469        }
15470
15471        if (app.curAdj != app.setAdj) {
15472            ProcessList.setOomAdj(app.pid, app.curAdj);
15473            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15474                TAG, "Set " + app.pid + " " + app.processName +
15475                " adj " + app.curAdj + ": " + app.adjType);
15476            app.setAdj = app.curAdj;
15477        }
15478
15479        if (app.setSchedGroup != app.curSchedGroup) {
15480            app.setSchedGroup = app.curSchedGroup;
15481            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15482                    "Setting process group of " + app.processName
15483                    + " to " + app.curSchedGroup);
15484            if (app.waitingToKill != null &&
15485                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15486                killUnneededProcessLocked(app, app.waitingToKill);
15487                success = false;
15488            } else {
15489                if (true) {
15490                    long oldId = Binder.clearCallingIdentity();
15491                    try {
15492                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15493                    } catch (Exception e) {
15494                        Slog.w(TAG, "Failed setting process group of " + app.pid
15495                                + " to " + app.curSchedGroup);
15496                        e.printStackTrace();
15497                    } finally {
15498                        Binder.restoreCallingIdentity(oldId);
15499                    }
15500                } else {
15501                    if (app.thread != null) {
15502                        try {
15503                            app.thread.setSchedulingGroup(app.curSchedGroup);
15504                        } catch (RemoteException e) {
15505                        }
15506                    }
15507                }
15508                Process.setSwappiness(app.pid,
15509                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15510            }
15511        }
15512        if (app.repProcState != app.curProcState) {
15513            app.repProcState = app.curProcState;
15514            if (!reportingProcessState && app.thread != null) {
15515                try {
15516                    if (false) {
15517                        //RuntimeException h = new RuntimeException("here");
15518                        Slog.i(TAG, "Sending new process state " + app.repProcState
15519                                + " to " + app /*, h*/);
15520                    }
15521                    app.thread.setProcessState(app.repProcState);
15522                } catch (RemoteException e) {
15523                }
15524            }
15525        }
15526        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15527                app.setProcState)) {
15528            app.lastStateTime = now;
15529            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15530                    mSleeping, now);
15531            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15532                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15533                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15534                    + (app.nextPssTime-now) + ": " + app);
15535        } else {
15536            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15537                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15538                requestPssLocked(app, app.setProcState);
15539                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15540                        mSleeping, now);
15541            } else if (false && DEBUG_PSS) {
15542                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15543            }
15544        }
15545        if (app.setProcState != app.curProcState) {
15546            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15547                    "Proc state change of " + app.processName
15548                    + " to " + app.curProcState);
15549            app.setProcState = app.curProcState;
15550            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15551                app.notCachedSinceIdle = false;
15552            }
15553            if (!doingAll) {
15554                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15555            } else {
15556                app.procStateChanged = true;
15557            }
15558        }
15559        return success;
15560    }
15561
15562    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15563        if (proc.thread != null && proc.baseProcessTracker != null) {
15564            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15565        }
15566    }
15567
15568    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15569            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15570        if (app.thread == null) {
15571            return false;
15572        }
15573
15574        final boolean wasKeeping = app.keeping;
15575
15576        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15577
15578        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15579                reportingProcessState, now);
15580    }
15581
15582    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15583            boolean oomAdj) {
15584        if (isForeground != proc.foregroundServices) {
15585            proc.foregroundServices = isForeground;
15586            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15587                    proc.info.uid);
15588            if (isForeground) {
15589                if (curProcs == null) {
15590                    curProcs = new ArrayList<ProcessRecord>();
15591                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15592                }
15593                if (!curProcs.contains(proc)) {
15594                    curProcs.add(proc);
15595                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15596                            proc.info.packageName, proc.info.uid);
15597                }
15598            } else {
15599                if (curProcs != null) {
15600                    if (curProcs.remove(proc)) {
15601                        mBatteryStatsService.noteEvent(
15602                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15603                                proc.info.packageName, proc.info.uid);
15604                        if (curProcs.size() <= 0) {
15605                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15606                        }
15607                    }
15608                }
15609            }
15610            if (oomAdj) {
15611                updateOomAdjLocked();
15612            }
15613        }
15614    }
15615
15616    private final ActivityRecord resumedAppLocked() {
15617        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15618        String pkg;
15619        int uid;
15620        if (act != null && !act.sleeping) {
15621            pkg = act.packageName;
15622            uid = act.info.applicationInfo.uid;
15623        } else {
15624            pkg = null;
15625            uid = -1;
15626        }
15627        // Has the UID or resumed package name changed?
15628        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15629                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15630            if (mCurResumedPackage != null) {
15631                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15632                        mCurResumedPackage, mCurResumedUid);
15633            }
15634            mCurResumedPackage = pkg;
15635            mCurResumedUid = uid;
15636            if (mCurResumedPackage != null) {
15637                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15638                        mCurResumedPackage, mCurResumedUid);
15639            }
15640        }
15641        return act;
15642    }
15643
15644    final boolean updateOomAdjLocked(ProcessRecord app) {
15645        return updateOomAdjLocked(app, false);
15646    }
15647
15648    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15649        final ActivityRecord TOP_ACT = resumedAppLocked();
15650        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15651        final boolean wasCached = app.cached;
15652
15653        mAdjSeq++;
15654
15655        // This is the desired cached adjusment we want to tell it to use.
15656        // If our app is currently cached, we know it, and that is it.  Otherwise,
15657        // we don't know it yet, and it needs to now be cached we will then
15658        // need to do a complete oom adj.
15659        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15660                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15661        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15662                SystemClock.uptimeMillis());
15663        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15664            // Changed to/from cached state, so apps after it in the LRU
15665            // list may also be changed.
15666            updateOomAdjLocked();
15667        }
15668        return success;
15669    }
15670
15671    final void updateOomAdjLocked() {
15672        final ActivityRecord TOP_ACT = resumedAppLocked();
15673        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15674        final long now = SystemClock.uptimeMillis();
15675        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15676        final int N = mLruProcesses.size();
15677
15678        if (false) {
15679            RuntimeException e = new RuntimeException();
15680            e.fillInStackTrace();
15681            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15682        }
15683
15684        mAdjSeq++;
15685        mNewNumServiceProcs = 0;
15686        mNewNumAServiceProcs = 0;
15687
15688        final int emptyProcessLimit;
15689        final int cachedProcessLimit;
15690        if (mProcessLimit <= 0) {
15691            emptyProcessLimit = cachedProcessLimit = 0;
15692        } else if (mProcessLimit == 1) {
15693            emptyProcessLimit = 1;
15694            cachedProcessLimit = 0;
15695        } else {
15696            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15697            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15698        }
15699
15700        // Let's determine how many processes we have running vs.
15701        // how many slots we have for background processes; we may want
15702        // to put multiple processes in a slot of there are enough of
15703        // them.
15704        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15705                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15706        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15707        if (numEmptyProcs > cachedProcessLimit) {
15708            // If there are more empty processes than our limit on cached
15709            // processes, then use the cached process limit for the factor.
15710            // This ensures that the really old empty processes get pushed
15711            // down to the bottom, so if we are running low on memory we will
15712            // have a better chance at keeping around more cached processes
15713            // instead of a gazillion empty processes.
15714            numEmptyProcs = cachedProcessLimit;
15715        }
15716        int emptyFactor = numEmptyProcs/numSlots;
15717        if (emptyFactor < 1) emptyFactor = 1;
15718        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15719        if (cachedFactor < 1) cachedFactor = 1;
15720        int stepCached = 0;
15721        int stepEmpty = 0;
15722        int numCached = 0;
15723        int numEmpty = 0;
15724        int numTrimming = 0;
15725
15726        mNumNonCachedProcs = 0;
15727        mNumCachedHiddenProcs = 0;
15728
15729        // First update the OOM adjustment for each of the
15730        // application processes based on their current state.
15731        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15732        int nextCachedAdj = curCachedAdj+1;
15733        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15734        int nextEmptyAdj = curEmptyAdj+2;
15735        for (int i=N-1; i>=0; i--) {
15736            ProcessRecord app = mLruProcesses.get(i);
15737            if (!app.killedByAm && app.thread != null) {
15738                app.procStateChanged = false;
15739                final boolean wasKeeping = app.keeping;
15740                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15741
15742                // If we haven't yet assigned the final cached adj
15743                // to the process, do that now.
15744                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15745                    switch (app.curProcState) {
15746                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15747                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15748                            // This process is a cached process holding activities...
15749                            // assign it the next cached value for that type, and then
15750                            // step that cached level.
15751                            app.curRawAdj = curCachedAdj;
15752                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15753                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15754                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15755                                    + ")");
15756                            if (curCachedAdj != nextCachedAdj) {
15757                                stepCached++;
15758                                if (stepCached >= cachedFactor) {
15759                                    stepCached = 0;
15760                                    curCachedAdj = nextCachedAdj;
15761                                    nextCachedAdj += 2;
15762                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15763                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15764                                    }
15765                                }
15766                            }
15767                            break;
15768                        default:
15769                            // For everything else, assign next empty cached process
15770                            // level and bump that up.  Note that this means that
15771                            // long-running services that have dropped down to the
15772                            // cached level will be treated as empty (since their process
15773                            // state is still as a service), which is what we want.
15774                            app.curRawAdj = curEmptyAdj;
15775                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15776                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15777                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15778                                    + ")");
15779                            if (curEmptyAdj != nextEmptyAdj) {
15780                                stepEmpty++;
15781                                if (stepEmpty >= emptyFactor) {
15782                                    stepEmpty = 0;
15783                                    curEmptyAdj = nextEmptyAdj;
15784                                    nextEmptyAdj += 2;
15785                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15786                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15787                                    }
15788                                }
15789                            }
15790                            break;
15791                    }
15792                }
15793
15794                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15795
15796                // Count the number of process types.
15797                switch (app.curProcState) {
15798                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15799                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15800                        mNumCachedHiddenProcs++;
15801                        numCached++;
15802                        if (numCached > cachedProcessLimit) {
15803                            killUnneededProcessLocked(app, "cached #" + numCached);
15804                        }
15805                        break;
15806                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15807                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15808                                && app.lastActivityTime < oldTime) {
15809                            killUnneededProcessLocked(app, "empty for "
15810                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15811                                    / 1000) + "s");
15812                        } else {
15813                            numEmpty++;
15814                            if (numEmpty > emptyProcessLimit) {
15815                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15816                            }
15817                        }
15818                        break;
15819                    default:
15820                        mNumNonCachedProcs++;
15821                        break;
15822                }
15823
15824                if (app.isolated && app.services.size() <= 0) {
15825                    // If this is an isolated process, and there are no
15826                    // services running in it, then the process is no longer
15827                    // needed.  We agressively kill these because we can by
15828                    // definition not re-use the same process again, and it is
15829                    // good to avoid having whatever code was running in them
15830                    // left sitting around after no longer needed.
15831                    killUnneededProcessLocked(app, "isolated not needed");
15832                }
15833
15834                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15835                        && !app.killedByAm) {
15836                    numTrimming++;
15837                }
15838            }
15839        }
15840
15841        mNumServiceProcs = mNewNumServiceProcs;
15842
15843        // Now determine the memory trimming level of background processes.
15844        // Unfortunately we need to start at the back of the list to do this
15845        // properly.  We only do this if the number of background apps we
15846        // are managing to keep around is less than half the maximum we desire;
15847        // if we are keeping a good number around, we'll let them use whatever
15848        // memory they want.
15849        final int numCachedAndEmpty = numCached + numEmpty;
15850        int memFactor;
15851        if (numCached <= ProcessList.TRIM_CACHED_APPS
15852                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15853            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15854                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15855            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15856                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15857            } else {
15858                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15859            }
15860        } else {
15861            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15862        }
15863        // We always allow the memory level to go up (better).  We only allow it to go
15864        // down if we are in a state where that is allowed, *and* the total number of processes
15865        // has gone down since last time.
15866        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15867                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15868                + " last=" + mLastNumProcesses);
15869        if (memFactor > mLastMemoryLevel) {
15870            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15871                memFactor = mLastMemoryLevel;
15872                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15873            }
15874        }
15875        mLastMemoryLevel = memFactor;
15876        mLastNumProcesses = mLruProcesses.size();
15877        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15878        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15879        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15880            if (mLowRamStartTime == 0) {
15881                mLowRamStartTime = now;
15882            }
15883            int step = 0;
15884            int fgTrimLevel;
15885            switch (memFactor) {
15886                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15887                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15888                    break;
15889                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15890                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15891                    break;
15892                default:
15893                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15894                    break;
15895            }
15896            int factor = numTrimming/3;
15897            int minFactor = 2;
15898            if (mHomeProcess != null) minFactor++;
15899            if (mPreviousProcess != null) minFactor++;
15900            if (factor < minFactor) factor = minFactor;
15901            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15902            for (int i=N-1; i>=0; i--) {
15903                ProcessRecord app = mLruProcesses.get(i);
15904                if (allChanged || app.procStateChanged) {
15905                    setProcessTrackerState(app, trackerMemFactor, now);
15906                    app.procStateChanged = false;
15907                }
15908                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15909                        && !app.killedByAm) {
15910                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15911                        try {
15912                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15913                                    "Trimming memory of " + app.processName
15914                                    + " to " + curLevel);
15915                            app.thread.scheduleTrimMemory(curLevel);
15916                        } catch (RemoteException e) {
15917                        }
15918                        if (false) {
15919                            // For now we won't do this; our memory trimming seems
15920                            // to be good enough at this point that destroying
15921                            // activities causes more harm than good.
15922                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15923                                    && app != mHomeProcess && app != mPreviousProcess) {
15924                                // Need to do this on its own message because the stack may not
15925                                // be in a consistent state at this point.
15926                                // For these apps we will also finish their activities
15927                                // to help them free memory.
15928                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15929                            }
15930                        }
15931                    }
15932                    app.trimMemoryLevel = curLevel;
15933                    step++;
15934                    if (step >= factor) {
15935                        step = 0;
15936                        switch (curLevel) {
15937                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15938                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15939                                break;
15940                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15941                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15942                                break;
15943                        }
15944                    }
15945                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15946                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15947                            && app.thread != null) {
15948                        try {
15949                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15950                                    "Trimming memory of heavy-weight " + app.processName
15951                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15952                            app.thread.scheduleTrimMemory(
15953                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15954                        } catch (RemoteException e) {
15955                        }
15956                    }
15957                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15958                } else {
15959                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15960                            || app.systemNoUi) && app.pendingUiClean) {
15961                        // If this application is now in the background and it
15962                        // had done UI, then give it the special trim level to
15963                        // have it free UI resources.
15964                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15965                        if (app.trimMemoryLevel < level && app.thread != null) {
15966                            try {
15967                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15968                                        "Trimming memory of bg-ui " + app.processName
15969                                        + " to " + level);
15970                                app.thread.scheduleTrimMemory(level);
15971                            } catch (RemoteException e) {
15972                            }
15973                        }
15974                        app.pendingUiClean = false;
15975                    }
15976                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15977                        try {
15978                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15979                                    "Trimming memory of fg " + app.processName
15980                                    + " to " + fgTrimLevel);
15981                            app.thread.scheduleTrimMemory(fgTrimLevel);
15982                        } catch (RemoteException e) {
15983                        }
15984                    }
15985                    app.trimMemoryLevel = fgTrimLevel;
15986                }
15987            }
15988        } else {
15989            if (mLowRamStartTime != 0) {
15990                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15991                mLowRamStartTime = 0;
15992            }
15993            for (int i=N-1; i>=0; i--) {
15994                ProcessRecord app = mLruProcesses.get(i);
15995                if (allChanged || app.procStateChanged) {
15996                    setProcessTrackerState(app, trackerMemFactor, now);
15997                    app.procStateChanged = false;
15998                }
15999                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16000                        || app.systemNoUi) && app.pendingUiClean) {
16001                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16002                            && app.thread != null) {
16003                        try {
16004                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16005                                    "Trimming memory of ui hidden " + app.processName
16006                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16007                            app.thread.scheduleTrimMemory(
16008                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16009                        } catch (RemoteException e) {
16010                        }
16011                    }
16012                    app.pendingUiClean = false;
16013                }
16014                app.trimMemoryLevel = 0;
16015            }
16016        }
16017
16018        if (mAlwaysFinishActivities) {
16019            // Need to do this on its own message because the stack may not
16020            // be in a consistent state at this point.
16021            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16022        }
16023
16024        if (allChanged) {
16025            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16026        }
16027
16028        if (mProcessStats.shouldWriteNowLocked(now)) {
16029            mHandler.post(new Runnable() {
16030                @Override public void run() {
16031                    synchronized (ActivityManagerService.this) {
16032                        mProcessStats.writeStateAsyncLocked();
16033                    }
16034                }
16035            });
16036        }
16037
16038        if (DEBUG_OOM_ADJ) {
16039            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16040        }
16041    }
16042
16043    final void trimApplications() {
16044        synchronized (this) {
16045            int i;
16046
16047            // First remove any unused application processes whose package
16048            // has been removed.
16049            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16050                final ProcessRecord app = mRemovedProcesses.get(i);
16051                if (app.activities.size() == 0
16052                        && app.curReceiver == null && app.services.size() == 0) {
16053                    Slog.i(
16054                        TAG, "Exiting empty application process "
16055                        + app.processName + " ("
16056                        + (app.thread != null ? app.thread.asBinder() : null)
16057                        + ")\n");
16058                    if (app.pid > 0 && app.pid != MY_PID) {
16059                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16060                                app.processName, app.setAdj, "empty");
16061                        app.killedByAm = true;
16062                        Process.killProcessQuiet(app.pid);
16063                    } else {
16064                        try {
16065                            app.thread.scheduleExit();
16066                        } catch (Exception e) {
16067                            // Ignore exceptions.
16068                        }
16069                    }
16070                    cleanUpApplicationRecordLocked(app, false, true, -1);
16071                    mRemovedProcesses.remove(i);
16072
16073                    if (app.persistent) {
16074                        if (app.persistent) {
16075                            addAppLocked(app.info, false);
16076                        }
16077                    }
16078                }
16079            }
16080
16081            // Now update the oom adj for all processes.
16082            updateOomAdjLocked();
16083        }
16084    }
16085
16086    /** This method sends the specified signal to each of the persistent apps */
16087    public void signalPersistentProcesses(int sig) throws RemoteException {
16088        if (sig != Process.SIGNAL_USR1) {
16089            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16090        }
16091
16092        synchronized (this) {
16093            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16094                    != PackageManager.PERMISSION_GRANTED) {
16095                throw new SecurityException("Requires permission "
16096                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16097            }
16098
16099            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16100                ProcessRecord r = mLruProcesses.get(i);
16101                if (r.thread != null && r.persistent) {
16102                    Process.sendSignal(r.pid, sig);
16103                }
16104            }
16105        }
16106    }
16107
16108    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16109        if (proc == null || proc == mProfileProc) {
16110            proc = mProfileProc;
16111            path = mProfileFile;
16112            profileType = mProfileType;
16113            clearProfilerLocked();
16114        }
16115        if (proc == null) {
16116            return;
16117        }
16118        try {
16119            proc.thread.profilerControl(false, path, null, profileType);
16120        } catch (RemoteException e) {
16121            throw new IllegalStateException("Process disappeared");
16122        }
16123    }
16124
16125    private void clearProfilerLocked() {
16126        if (mProfileFd != null) {
16127            try {
16128                mProfileFd.close();
16129            } catch (IOException e) {
16130            }
16131        }
16132        mProfileApp = null;
16133        mProfileProc = null;
16134        mProfileFile = null;
16135        mProfileType = 0;
16136        mAutoStopProfiler = false;
16137    }
16138
16139    public boolean profileControl(String process, int userId, boolean start,
16140            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16141
16142        try {
16143            synchronized (this) {
16144                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16145                // its own permission.
16146                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16147                        != PackageManager.PERMISSION_GRANTED) {
16148                    throw new SecurityException("Requires permission "
16149                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16150                }
16151
16152                if (start && fd == null) {
16153                    throw new IllegalArgumentException("null fd");
16154                }
16155
16156                ProcessRecord proc = null;
16157                if (process != null) {
16158                    proc = findProcessLocked(process, userId, "profileControl");
16159                }
16160
16161                if (start && (proc == null || proc.thread == null)) {
16162                    throw new IllegalArgumentException("Unknown process: " + process);
16163                }
16164
16165                if (start) {
16166                    stopProfilerLocked(null, null, 0);
16167                    setProfileApp(proc.info, proc.processName, path, fd, false);
16168                    mProfileProc = proc;
16169                    mProfileType = profileType;
16170                    try {
16171                        fd = fd.dup();
16172                    } catch (IOException e) {
16173                        fd = null;
16174                    }
16175                    proc.thread.profilerControl(start, path, fd, profileType);
16176                    fd = null;
16177                    mProfileFd = null;
16178                } else {
16179                    stopProfilerLocked(proc, path, profileType);
16180                    if (fd != null) {
16181                        try {
16182                            fd.close();
16183                        } catch (IOException e) {
16184                        }
16185                    }
16186                }
16187
16188                return true;
16189            }
16190        } catch (RemoteException e) {
16191            throw new IllegalStateException("Process disappeared");
16192        } finally {
16193            if (fd != null) {
16194                try {
16195                    fd.close();
16196                } catch (IOException e) {
16197                }
16198            }
16199        }
16200    }
16201
16202    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16203        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16204                userId, true, true, callName, null);
16205        ProcessRecord proc = null;
16206        try {
16207            int pid = Integer.parseInt(process);
16208            synchronized (mPidsSelfLocked) {
16209                proc = mPidsSelfLocked.get(pid);
16210            }
16211        } catch (NumberFormatException e) {
16212        }
16213
16214        if (proc == null) {
16215            ArrayMap<String, SparseArray<ProcessRecord>> all
16216                    = mProcessNames.getMap();
16217            SparseArray<ProcessRecord> procs = all.get(process);
16218            if (procs != null && procs.size() > 0) {
16219                proc = procs.valueAt(0);
16220                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16221                    for (int i=1; i<procs.size(); i++) {
16222                        ProcessRecord thisProc = procs.valueAt(i);
16223                        if (thisProc.userId == userId) {
16224                            proc = thisProc;
16225                            break;
16226                        }
16227                    }
16228                }
16229            }
16230        }
16231
16232        return proc;
16233    }
16234
16235    public boolean dumpHeap(String process, int userId, boolean managed,
16236            String path, ParcelFileDescriptor fd) throws RemoteException {
16237
16238        try {
16239            synchronized (this) {
16240                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16241                // its own permission (same as profileControl).
16242                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16243                        != PackageManager.PERMISSION_GRANTED) {
16244                    throw new SecurityException("Requires permission "
16245                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16246                }
16247
16248                if (fd == null) {
16249                    throw new IllegalArgumentException("null fd");
16250                }
16251
16252                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16253                if (proc == null || proc.thread == null) {
16254                    throw new IllegalArgumentException("Unknown process: " + process);
16255                }
16256
16257                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16258                if (!isDebuggable) {
16259                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16260                        throw new SecurityException("Process not debuggable: " + proc);
16261                    }
16262                }
16263
16264                proc.thread.dumpHeap(managed, path, fd);
16265                fd = null;
16266                return true;
16267            }
16268        } catch (RemoteException e) {
16269            throw new IllegalStateException("Process disappeared");
16270        } finally {
16271            if (fd != null) {
16272                try {
16273                    fd.close();
16274                } catch (IOException e) {
16275                }
16276            }
16277        }
16278    }
16279
16280    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16281    public void monitor() {
16282        synchronized (this) { }
16283    }
16284
16285    void onCoreSettingsChange(Bundle settings) {
16286        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16287            ProcessRecord processRecord = mLruProcesses.get(i);
16288            try {
16289                if (processRecord.thread != null) {
16290                    processRecord.thread.setCoreSettings(settings);
16291                }
16292            } catch (RemoteException re) {
16293                /* ignore */
16294            }
16295        }
16296    }
16297
16298    // Multi-user methods
16299
16300    /**
16301     * Start user, if its not already running, but don't bring it to foreground.
16302     */
16303    @Override
16304    public boolean startUserInBackground(final int userId) {
16305        return startUser(userId, /* foreground */ false);
16306    }
16307
16308    /**
16309     * Refreshes the list of users related to the current user when either a
16310     * user switch happens or when a new related user is started in the
16311     * background.
16312     */
16313    private void updateCurrentProfileIdsLocked() {
16314        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16315        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16316        for (int i = 0; i < currentProfileIds.length; i++) {
16317            currentProfileIds[i] = profiles.get(i).id;
16318        }
16319        mCurrentProfileIds = currentProfileIds;
16320    }
16321
16322    private Set getProfileIdsLocked(int userId) {
16323        Set userIds = new HashSet<Integer>();
16324        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId);
16325        for (UserInfo user : profiles) {
16326            userIds.add(Integer.valueOf(user.id));
16327        }
16328        return userIds;
16329    }
16330
16331    @Override
16332    public boolean switchUser(final int userId) {
16333        return startUser(userId, /* foregound */ true);
16334    }
16335
16336    private boolean startUser(final int userId, boolean foreground) {
16337        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16338                != PackageManager.PERMISSION_GRANTED) {
16339            String msg = "Permission Denial: switchUser() from pid="
16340                    + Binder.getCallingPid()
16341                    + ", uid=" + Binder.getCallingUid()
16342                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16343            Slog.w(TAG, msg);
16344            throw new SecurityException(msg);
16345        }
16346
16347        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16348
16349        final long ident = Binder.clearCallingIdentity();
16350        try {
16351            synchronized (this) {
16352                final int oldUserId = mCurrentUserId;
16353                if (oldUserId == userId) {
16354                    return true;
16355                }
16356
16357                mStackSupervisor.setLockTaskModeLocked(null);
16358
16359                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16360                if (userInfo == null) {
16361                    Slog.w(TAG, "No user info for user #" + userId);
16362                    return false;
16363                }
16364
16365                if (foreground) {
16366                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16367                            R.anim.screen_user_enter);
16368                }
16369
16370                boolean needStart = false;
16371
16372                // If the user we are switching to is not currently started, then
16373                // we need to start it now.
16374                if (mStartedUsers.get(userId) == null) {
16375                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16376                    updateStartedUserArrayLocked();
16377                    needStart = true;
16378                }
16379
16380                final Integer userIdInt = Integer.valueOf(userId);
16381                mUserLru.remove(userIdInt);
16382                mUserLru.add(userIdInt);
16383
16384                if (foreground) {
16385                    mCurrentUserId = userId;
16386                    updateCurrentProfileIdsLocked();
16387                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16388                    // Once the internal notion of the active user has switched, we lock the device
16389                    // with the option to show the user switcher on the keyguard.
16390                    mWindowManager.lockNow(null);
16391                } else {
16392                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16393                    updateCurrentProfileIdsLocked();
16394                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16395                    mUserLru.remove(currentUserIdInt);
16396                    mUserLru.add(currentUserIdInt);
16397                }
16398
16399                final UserStartedState uss = mStartedUsers.get(userId);
16400
16401                // Make sure user is in the started state.  If it is currently
16402                // stopping, we need to knock that off.
16403                if (uss.mState == UserStartedState.STATE_STOPPING) {
16404                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16405                    // so we can just fairly silently bring the user back from
16406                    // the almost-dead.
16407                    uss.mState = UserStartedState.STATE_RUNNING;
16408                    updateStartedUserArrayLocked();
16409                    needStart = true;
16410                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16411                    // This means ACTION_SHUTDOWN has been sent, so we will
16412                    // need to treat this as a new boot of the user.
16413                    uss.mState = UserStartedState.STATE_BOOTING;
16414                    updateStartedUserArrayLocked();
16415                    needStart = true;
16416                }
16417
16418                if (foreground) {
16419                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16420                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16421                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16422                            oldUserId, userId, uss));
16423                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16424                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16425                }
16426
16427                if (needStart) {
16428                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16429                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16430                            | Intent.FLAG_RECEIVER_FOREGROUND);
16431                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16432                    broadcastIntentLocked(null, null, intent,
16433                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16434                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16435                }
16436
16437                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16438                    if (userId != 0) {
16439                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16440                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16441                        broadcastIntentLocked(null, null, intent, null,
16442                                new IIntentReceiver.Stub() {
16443                                    public void performReceive(Intent intent, int resultCode,
16444                                            String data, Bundle extras, boolean ordered,
16445                                            boolean sticky, int sendingUser) {
16446                                        userInitialized(uss, userId);
16447                                    }
16448                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16449                                true, false, MY_PID, Process.SYSTEM_UID,
16450                                userId);
16451                        uss.initializing = true;
16452                    } else {
16453                        getUserManagerLocked().makeInitialized(userInfo.id);
16454                    }
16455                }
16456
16457                if (foreground) {
16458                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16459                    if (homeInFront) {
16460                        startHomeActivityLocked(userId);
16461                    } else {
16462                        mStackSupervisor.resumeTopActivitiesLocked();
16463                    }
16464                    EventLogTags.writeAmSwitchUser(userId);
16465                    getUserManagerLocked().userForeground(userId);
16466                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16467                }
16468
16469                if (needStart) {
16470                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16471                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16472                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16473                    broadcastIntentLocked(null, null, intent,
16474                            null, new IIntentReceiver.Stub() {
16475                                @Override
16476                                public void performReceive(Intent intent, int resultCode, String data,
16477                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16478                                        throws RemoteException {
16479                                }
16480                            }, 0, null, null,
16481                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16482                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16483                }
16484            }
16485        } finally {
16486            Binder.restoreCallingIdentity(ident);
16487        }
16488
16489        return true;
16490    }
16491
16492    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16493        long ident = Binder.clearCallingIdentity();
16494        try {
16495            Intent intent;
16496            if (oldUserId >= 0) {
16497                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16498                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16499                        | Intent.FLAG_RECEIVER_FOREGROUND);
16500                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16501                broadcastIntentLocked(null, null, intent,
16502                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16503                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16504            }
16505            if (newUserId >= 0) {
16506                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16507                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16508                        | Intent.FLAG_RECEIVER_FOREGROUND);
16509                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16510                broadcastIntentLocked(null, null, intent,
16511                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16512                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16513                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16514                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16515                        | Intent.FLAG_RECEIVER_FOREGROUND);
16516                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16517                broadcastIntentLocked(null, null, intent,
16518                        null, null, 0, null, null,
16519                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16520                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16521            }
16522        } finally {
16523            Binder.restoreCallingIdentity(ident);
16524        }
16525    }
16526
16527    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16528            final int newUserId) {
16529        final int N = mUserSwitchObservers.beginBroadcast();
16530        if (N > 0) {
16531            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16532                int mCount = 0;
16533                @Override
16534                public void sendResult(Bundle data) throws RemoteException {
16535                    synchronized (ActivityManagerService.this) {
16536                        if (mCurUserSwitchCallback == this) {
16537                            mCount++;
16538                            if (mCount == N) {
16539                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16540                            }
16541                        }
16542                    }
16543                }
16544            };
16545            synchronized (this) {
16546                uss.switching = true;
16547                mCurUserSwitchCallback = callback;
16548            }
16549            for (int i=0; i<N; i++) {
16550                try {
16551                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16552                            newUserId, callback);
16553                } catch (RemoteException e) {
16554                }
16555            }
16556        } else {
16557            synchronized (this) {
16558                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16559            }
16560        }
16561        mUserSwitchObservers.finishBroadcast();
16562    }
16563
16564    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16565        synchronized (this) {
16566            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16567            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16568        }
16569    }
16570
16571    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16572        mCurUserSwitchCallback = null;
16573        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16574        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16575                oldUserId, newUserId, uss));
16576    }
16577
16578    void userInitialized(UserStartedState uss, int newUserId) {
16579        completeSwitchAndInitalize(uss, newUserId, true, false);
16580    }
16581
16582    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16583        completeSwitchAndInitalize(uss, newUserId, false, true);
16584    }
16585
16586    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16587            boolean clearInitializing, boolean clearSwitching) {
16588        boolean unfrozen = false;
16589        synchronized (this) {
16590            if (clearInitializing) {
16591                uss.initializing = false;
16592                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16593            }
16594            if (clearSwitching) {
16595                uss.switching = false;
16596            }
16597            if (!uss.switching && !uss.initializing) {
16598                mWindowManager.stopFreezingScreen();
16599                unfrozen = true;
16600            }
16601        }
16602        if (unfrozen) {
16603            final int N = mUserSwitchObservers.beginBroadcast();
16604            for (int i=0; i<N; i++) {
16605                try {
16606                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16607                } catch (RemoteException e) {
16608                }
16609            }
16610            mUserSwitchObservers.finishBroadcast();
16611        }
16612    }
16613
16614    void scheduleStartProfilesLocked() {
16615        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16616            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16617                    DateUtils.SECOND_IN_MILLIS);
16618        }
16619    }
16620
16621    void startProfilesLocked() {
16622        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16623        List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16624        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16625        for (UserInfo user : profiles) {
16626            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16627                    && user.id != mCurrentUserId) {
16628                toStart.add(user);
16629            }
16630        }
16631        final int n = toStart.size();
16632        int i = 0;
16633        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16634            startUserInBackground(toStart.get(i).id);
16635        }
16636        if (i < n) {
16637            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16638        }
16639    }
16640
16641    void finishUserSwitch(UserStartedState uss) {
16642        synchronized (this) {
16643            if (uss.mState == UserStartedState.STATE_BOOTING
16644                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16645                uss.mState = UserStartedState.STATE_RUNNING;
16646                final int userId = uss.mHandle.getIdentifier();
16647                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16648                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16649                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16650                broadcastIntentLocked(null, null, intent,
16651                        null, null, 0, null, null,
16652                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16653                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16654            }
16655
16656            startProfilesLocked();
16657
16658            int num = mUserLru.size();
16659            int i = 0;
16660            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16661                Integer oldUserId = mUserLru.get(i);
16662                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16663                if (oldUss == null) {
16664                    // Shouldn't happen, but be sane if it does.
16665                    mUserLru.remove(i);
16666                    num--;
16667                    continue;
16668                }
16669                if (oldUss.mState == UserStartedState.STATE_STOPPING
16670                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16671                    // This user is already stopping, doesn't count.
16672                    num--;
16673                    i++;
16674                    continue;
16675                }
16676                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16677                    // Owner and current can't be stopped, but count as running.
16678                    i++;
16679                    continue;
16680                }
16681                // This is a user to be stopped.
16682                stopUserLocked(oldUserId, null);
16683                num--;
16684                i++;
16685            }
16686        }
16687    }
16688
16689    @Override
16690    public int stopUser(final int userId, final IStopUserCallback callback) {
16691        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16692                != PackageManager.PERMISSION_GRANTED) {
16693            String msg = "Permission Denial: switchUser() from pid="
16694                    + Binder.getCallingPid()
16695                    + ", uid=" + Binder.getCallingUid()
16696                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16697            Slog.w(TAG, msg);
16698            throw new SecurityException(msg);
16699        }
16700        if (userId <= 0) {
16701            throw new IllegalArgumentException("Can't stop primary user " + userId);
16702        }
16703        synchronized (this) {
16704            return stopUserLocked(userId, callback);
16705        }
16706    }
16707
16708    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16709        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16710        if (mCurrentUserId == userId) {
16711            return ActivityManager.USER_OP_IS_CURRENT;
16712        }
16713
16714        final UserStartedState uss = mStartedUsers.get(userId);
16715        if (uss == null) {
16716            // User is not started, nothing to do...  but we do need to
16717            // callback if requested.
16718            if (callback != null) {
16719                mHandler.post(new Runnable() {
16720                    @Override
16721                    public void run() {
16722                        try {
16723                            callback.userStopped(userId);
16724                        } catch (RemoteException e) {
16725                        }
16726                    }
16727                });
16728            }
16729            return ActivityManager.USER_OP_SUCCESS;
16730        }
16731
16732        if (callback != null) {
16733            uss.mStopCallbacks.add(callback);
16734        }
16735
16736        if (uss.mState != UserStartedState.STATE_STOPPING
16737                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16738            uss.mState = UserStartedState.STATE_STOPPING;
16739            updateStartedUserArrayLocked();
16740
16741            long ident = Binder.clearCallingIdentity();
16742            try {
16743                // We are going to broadcast ACTION_USER_STOPPING and then
16744                // once that is done send a final ACTION_SHUTDOWN and then
16745                // stop the user.
16746                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16747                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16748                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16749                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16750                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16751                // This is the result receiver for the final shutdown broadcast.
16752                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16753                    @Override
16754                    public void performReceive(Intent intent, int resultCode, String data,
16755                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16756                        finishUserStop(uss);
16757                    }
16758                };
16759                // This is the result receiver for the initial stopping broadcast.
16760                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16761                    @Override
16762                    public void performReceive(Intent intent, int resultCode, String data,
16763                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16764                        // On to the next.
16765                        synchronized (ActivityManagerService.this) {
16766                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16767                                // Whoops, we are being started back up.  Abort, abort!
16768                                return;
16769                            }
16770                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16771                        }
16772                        broadcastIntentLocked(null, null, shutdownIntent,
16773                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16774                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16775                    }
16776                };
16777                // Kick things off.
16778                broadcastIntentLocked(null, null, stoppingIntent,
16779                        null, stoppingReceiver, 0, null, null,
16780                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16781                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16782            } finally {
16783                Binder.restoreCallingIdentity(ident);
16784            }
16785        }
16786
16787        return ActivityManager.USER_OP_SUCCESS;
16788    }
16789
16790    void finishUserStop(UserStartedState uss) {
16791        final int userId = uss.mHandle.getIdentifier();
16792        boolean stopped;
16793        ArrayList<IStopUserCallback> callbacks;
16794        synchronized (this) {
16795            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16796            if (mStartedUsers.get(userId) != uss) {
16797                stopped = false;
16798            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16799                stopped = false;
16800            } else {
16801                stopped = true;
16802                // User can no longer run.
16803                mStartedUsers.remove(userId);
16804                mUserLru.remove(Integer.valueOf(userId));
16805                updateStartedUserArrayLocked();
16806
16807                // Clean up all state and processes associated with the user.
16808                // Kill all the processes for the user.
16809                forceStopUserLocked(userId, "finish user");
16810            }
16811        }
16812
16813        for (int i=0; i<callbacks.size(); i++) {
16814            try {
16815                if (stopped) callbacks.get(i).userStopped(userId);
16816                else callbacks.get(i).userStopAborted(userId);
16817            } catch (RemoteException e) {
16818            }
16819        }
16820
16821        mStackSupervisor.removeUserLocked(userId);
16822    }
16823
16824    @Override
16825    public UserInfo getCurrentUser() {
16826        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16827                != PackageManager.PERMISSION_GRANTED) && (
16828                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16829                != PackageManager.PERMISSION_GRANTED)) {
16830            String msg = "Permission Denial: getCurrentUser() from pid="
16831                    + Binder.getCallingPid()
16832                    + ", uid=" + Binder.getCallingUid()
16833                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16834            Slog.w(TAG, msg);
16835            throw new SecurityException(msg);
16836        }
16837        synchronized (this) {
16838            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16839        }
16840    }
16841
16842    int getCurrentUserIdLocked() {
16843        return mCurrentUserId;
16844    }
16845
16846    @Override
16847    public boolean isUserRunning(int userId, boolean orStopped) {
16848        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16849                != PackageManager.PERMISSION_GRANTED) {
16850            String msg = "Permission Denial: isUserRunning() from pid="
16851                    + Binder.getCallingPid()
16852                    + ", uid=" + Binder.getCallingUid()
16853                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16854            Slog.w(TAG, msg);
16855            throw new SecurityException(msg);
16856        }
16857        synchronized (this) {
16858            return isUserRunningLocked(userId, orStopped);
16859        }
16860    }
16861
16862    boolean isUserRunningLocked(int userId, boolean orStopped) {
16863        UserStartedState state = mStartedUsers.get(userId);
16864        if (state == null) {
16865            return false;
16866        }
16867        if (orStopped) {
16868            return true;
16869        }
16870        return state.mState != UserStartedState.STATE_STOPPING
16871                && state.mState != UserStartedState.STATE_SHUTDOWN;
16872    }
16873
16874    @Override
16875    public int[] getRunningUserIds() {
16876        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16877                != PackageManager.PERMISSION_GRANTED) {
16878            String msg = "Permission Denial: isUserRunning() from pid="
16879                    + Binder.getCallingPid()
16880                    + ", uid=" + Binder.getCallingUid()
16881                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16882            Slog.w(TAG, msg);
16883            throw new SecurityException(msg);
16884        }
16885        synchronized (this) {
16886            return mStartedUserArray;
16887        }
16888    }
16889
16890    private void updateStartedUserArrayLocked() {
16891        int num = 0;
16892        for (int i=0; i<mStartedUsers.size();  i++) {
16893            UserStartedState uss = mStartedUsers.valueAt(i);
16894            // This list does not include stopping users.
16895            if (uss.mState != UserStartedState.STATE_STOPPING
16896                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16897                num++;
16898            }
16899        }
16900        mStartedUserArray = new int[num];
16901        num = 0;
16902        for (int i=0; i<mStartedUsers.size();  i++) {
16903            UserStartedState uss = mStartedUsers.valueAt(i);
16904            if (uss.mState != UserStartedState.STATE_STOPPING
16905                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16906                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16907                num++;
16908            }
16909        }
16910    }
16911
16912    @Override
16913    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16914        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16915                != PackageManager.PERMISSION_GRANTED) {
16916            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16917                    + Binder.getCallingPid()
16918                    + ", uid=" + Binder.getCallingUid()
16919                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16920            Slog.w(TAG, msg);
16921            throw new SecurityException(msg);
16922        }
16923
16924        mUserSwitchObservers.register(observer);
16925    }
16926
16927    @Override
16928    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16929        mUserSwitchObservers.unregister(observer);
16930    }
16931
16932    private boolean userExists(int userId) {
16933        if (userId == 0) {
16934            return true;
16935        }
16936        UserManagerService ums = getUserManagerLocked();
16937        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16938    }
16939
16940    int[] getUsersLocked() {
16941        UserManagerService ums = getUserManagerLocked();
16942        return ums != null ? ums.getUserIds() : new int[] { 0 };
16943    }
16944
16945    UserManagerService getUserManagerLocked() {
16946        if (mUserManager == null) {
16947            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16948            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16949        }
16950        return mUserManager;
16951    }
16952
16953    private int applyUserId(int uid, int userId) {
16954        return UserHandle.getUid(userId, uid);
16955    }
16956
16957    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16958        if (info == null) return null;
16959        ApplicationInfo newInfo = new ApplicationInfo(info);
16960        newInfo.uid = applyUserId(info.uid, userId);
16961        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16962                + info.packageName;
16963        return newInfo;
16964    }
16965
16966    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16967        if (aInfo == null
16968                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16969            return aInfo;
16970        }
16971
16972        ActivityInfo info = new ActivityInfo(aInfo);
16973        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16974        return info;
16975    }
16976
16977    private final class LocalService extends ActivityManagerInternal {
16978        @Override
16979        public void goingToSleep() {
16980            ActivityManagerService.this.goingToSleep();
16981        }
16982
16983        @Override
16984        public void wakingUp() {
16985            ActivityManagerService.this.wakingUp();
16986        }
16987    }
16988}
16989